mirror of
git://sourceware.org/git/lvm2.git
synced 2025-11-04 12:23:49 +03:00
Compare commits
3003 Commits
dev-mcsont
...
v2_02_42
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a5dce4c92 | ||
|
|
22d7e60d0e | ||
|
|
5752156c9e | ||
|
|
a30215a530 | ||
|
|
f9c8c1b964 | ||
|
|
5650f67ef5 | ||
|
|
5ec25dfb94 | ||
|
|
ef16682725 | ||
|
|
883486cc67 | ||
|
|
f367f9b747 | ||
|
|
a3d987fa73 | ||
|
|
2d48685673 | ||
|
|
9b21ace1e9 | ||
|
|
be2c03fa96 | ||
|
|
f5585e9252 | ||
|
|
4d534dd7e4 | ||
|
|
c8584e1cce | ||
|
|
84a1de464c | ||
|
|
3966f3d319 | ||
|
|
e6166cf711 | ||
|
|
2285712834 | ||
|
|
53cb6128e8 | ||
|
|
8c317baf19 | ||
|
|
8cac933c71 | ||
|
|
03e61a4bf8 | ||
|
|
71446a76b2 | ||
|
|
28db8d6c7c | ||
|
|
786e33d7d5 | ||
|
|
b140d6c50e | ||
|
|
64a95abdee | ||
|
|
57f926be17 | ||
|
|
4933b67959 | ||
|
|
370b4f1b9e | ||
|
|
f3b7baa84e | ||
|
|
eafdb2c807 | ||
|
|
a91fa821ab | ||
|
|
37ef162cda | ||
|
|
770928acfc | ||
|
|
d0f3570219 | ||
|
|
3d07c2605f | ||
|
|
c350798528 | ||
|
|
6bc3cc0bec | ||
|
|
2e3e5fcc81 | ||
|
|
dfdb10f6de | ||
|
|
5cbe5909eb | ||
|
|
04d52b450b | ||
|
|
a586a89547 | ||
|
|
1905eacf15 | ||
|
|
858ec0d740 | ||
|
|
76cfd406ca | ||
|
|
9dbaad859d | ||
|
|
95d43e17b3 | ||
|
|
09a2dff8de | ||
|
|
57208f879a | ||
|
|
149638431d | ||
|
|
30d2940c67 | ||
|
|
5ee86fc5d0 | ||
|
|
a03d0e2c3f | ||
|
|
8bd367d58d | ||
|
|
bc633e03aa | ||
|
|
797d0f1ef1 | ||
|
|
1be3e86aa0 | ||
|
|
e56dd38021 | ||
|
|
410904bef1 | ||
|
|
026cc120e7 | ||
|
|
ef2fda05cf | ||
|
|
92277e3ae2 | ||
|
|
fbc34d70b0 | ||
|
|
91dcddbdf7 | ||
|
|
874f42ad6c | ||
|
|
1989ef4ebc | ||
|
|
4f4c72c065 | ||
|
|
666cc72661 | ||
|
|
4524e8f5c9 | ||
|
|
bd07a29886 | ||
|
|
a0d865492e | ||
|
|
de27790de8 | ||
|
|
9c910b7be2 | ||
|
|
7f23ab94e2 | ||
|
|
77dc036c8f | ||
|
|
aa6e8d82ce | ||
|
|
3010285bb3 | ||
|
|
aaad3252f8 | ||
|
|
9065f534d8 | ||
|
|
52361c94e5 | ||
|
|
798be60fef | ||
|
|
6294154b15 | ||
|
|
6594fe077d | ||
|
|
582706cde6 | ||
|
|
6537cbdc17 | ||
|
|
53959459bb | ||
|
|
22d6121099 | ||
|
|
48d7f6f2f4 | ||
|
|
9fd4ddc490 | ||
|
|
a4d2fddbb2 | ||
|
|
c54a3f2721 | ||
|
|
04c0dba697 | ||
|
|
5406e3b7c5 | ||
|
|
6b624b7d00 | ||
|
|
2d364d4d80 | ||
|
|
1f27bf3774 | ||
|
|
d30a2653b5 | ||
|
|
3086822cd2 | ||
|
|
2c08336490 | ||
|
|
5936ac58c2 | ||
|
|
ded77e3f5c | ||
|
|
8a29df0a6c | ||
|
|
9db22babaf | ||
|
|
c318c5ed61 | ||
|
|
61243c65cd | ||
|
|
4a5d5cb462 | ||
|
|
cbf1447ebd | ||
|
|
30104441bf | ||
|
|
b4a70804f0 | ||
|
|
74f6707bde | ||
|
|
223eb8c84d | ||
|
|
107d000606 | ||
|
|
43e05607af | ||
|
|
55793452d5 | ||
|
|
686ba37255 | ||
|
|
03ed19dad5 | ||
|
|
ad2b6e5de1 | ||
|
|
767676d6ff | ||
|
|
bc7a54c615 | ||
|
|
1bda393678 | ||
|
|
bb5495c6bd | ||
|
|
484f905749 | ||
|
|
e0d61a4336 | ||
|
|
e643a16ba5 | ||
|
|
98fadec2b6 | ||
|
|
14f464ecb0 | ||
|
|
2ecdaf9bd4 | ||
|
|
707c898f66 | ||
|
|
69e4400774 | ||
|
|
695efde68d | ||
|
|
0c4b769011 | ||
|
|
e53eff0634 | ||
|
|
6c75243a06 | ||
|
|
efde37880b | ||
|
|
7d8f6381be | ||
|
|
3c361e3393 | ||
|
|
8440ecef5e | ||
|
|
6401f1b1c9 | ||
|
|
7487a7c988 | ||
|
|
f44584fa10 | ||
|
|
7b32165614 | ||
|
|
b0dc94d187 | ||
|
|
0383c4e1d8 | ||
|
|
a8c5758222 | ||
|
|
a7fabfd8cb | ||
|
|
5d5b575d16 | ||
|
|
ac1373653c | ||
|
|
b097aa787b | ||
|
|
723be0fe69 | ||
|
|
f0597a03de | ||
|
|
65f0656f54 | ||
|
|
507ece15a5 | ||
|
|
30be4d1613 | ||
|
|
366e89bda0 | ||
|
|
f159c3f768 | ||
|
|
8506d1d567 | ||
|
|
111829da46 | ||
|
|
605798073e | ||
|
|
8320f2b094 | ||
|
|
df0d8d809b | ||
|
|
062886df64 | ||
|
|
148ea3aaa8 | ||
|
|
ab5f66c13a | ||
|
|
e65ffb8e68 | ||
|
|
949c1ab517 | ||
|
|
946d8ee046 | ||
|
|
c54a8a2e10 | ||
|
|
31177e4f85 | ||
|
|
750f81b4b5 | ||
|
|
987ff02a45 | ||
|
|
f5adaf813c | ||
|
|
78ff7dc7f0 | ||
|
|
d1fced3324 | ||
|
|
e7df9c289b | ||
|
|
a78d7231a9 | ||
|
|
ba7ae0002e | ||
|
|
a090f7b839 | ||
|
|
34ed15a987 | ||
|
|
cacec4c910 | ||
|
|
3e47d4e65b | ||
|
|
8b42fa150b | ||
|
|
60e660b9c7 | ||
|
|
fe74f013e3 | ||
|
|
24c0c70f90 | ||
|
|
757f91ca89 | ||
|
|
5c34f7847e | ||
|
|
de456f014e | ||
|
|
d29565066d | ||
|
|
4d52c9233b | ||
|
|
6da1ca0cb9 | ||
|
|
2f02f1518a | ||
|
|
e8863707de | ||
|
|
6a336dfc69 | ||
|
|
35dec1b9e4 | ||
|
|
f148280c99 | ||
|
|
599fe39749 | ||
|
|
44f3fcb238 | ||
|
|
af40fdb285 | ||
|
|
9daf8b825c | ||
|
|
ef5d8ce367 | ||
|
|
4a199ab23b | ||
|
|
6f0f5a569d | ||
|
|
3172fbfde6 | ||
|
|
e97a07a505 | ||
|
|
6579ad92da | ||
|
|
ec2fad0cfa | ||
|
|
6196ac7995 | ||
|
|
095a861018 | ||
|
|
2449ed7765 | ||
|
|
117a0408d6 | ||
|
|
a54b0223a3 | ||
|
|
44ee708ba5 | ||
|
|
58a20d0fb6 | ||
|
|
063078a02d | ||
|
|
01402fea50 | ||
|
|
b7fc2d1147 | ||
|
|
43eeb7011c | ||
|
|
d7901a4220 | ||
|
|
0c6271dabc | ||
|
|
2d4cf0c9f5 | ||
|
|
0646d0dd91 | ||
|
|
83e54b45a5 | ||
|
|
5cd87d3d27 | ||
|
|
689d8a80b5 | ||
|
|
b1d82a92e7 | ||
|
|
4d65627a50 | ||
|
|
ce3a68d817 | ||
|
|
409725be24 | ||
|
|
b74f74a0d7 | ||
|
|
719d554430 | ||
|
|
13f54f4521 | ||
|
|
57dfc9cf42 | ||
|
|
57244a6823 | ||
|
|
8bdde01bef | ||
|
|
09bbd5a472 | ||
|
|
9154a74400 | ||
|
|
1399b84b32 | ||
|
|
2ddbb3a8fa | ||
|
|
e46a6d1cc1 | ||
|
|
b698ab9011 | ||
|
|
0a2572a5eb | ||
|
|
77d049cc3d | ||
|
|
7b8f053be2 | ||
|
|
2c850d5293 | ||
|
|
4056bbf10b | ||
|
|
896b04a846 | ||
|
|
93cda8b6ec | ||
|
|
bb5e930684 | ||
|
|
43761fed2a | ||
|
|
a636299680 | ||
|
|
08e5bd5b72 | ||
|
|
2f057bef5e | ||
|
|
5ab4f21444 | ||
|
|
9ec26ed481 | ||
|
|
29c9df1389 | ||
|
|
867e9c51d4 | ||
|
|
0170f7b42a | ||
|
|
74bb6ead95 | ||
|
|
303388e5cb | ||
|
|
8388779937 | ||
|
|
fc7dfca452 | ||
|
|
e5a1db2392 | ||
|
|
6790656af6 | ||
|
|
b7477bdc15 | ||
|
|
ffc61f31de | ||
|
|
e612871ea7 | ||
|
|
7f40f09f10 | ||
|
|
456e42257c | ||
|
|
8618c271cf | ||
|
|
72ca1ccc23 | ||
|
|
075b4bef3f | ||
|
|
b59fce4393 | ||
|
|
8674a25eb8 | ||
|
|
10bf8fd2cd | ||
|
|
57cb22ff3c | ||
|
|
0162abdcae | ||
|
|
5801171518 | ||
|
|
bf1edbd1e2 | ||
|
|
a8484d987d | ||
|
|
9b2147f608 | ||
|
|
32530b378e | ||
|
|
a42905efa6 | ||
|
|
c59745f9dd | ||
|
|
b4ad9a5d08 | ||
|
|
3ead7a38b1 | ||
|
|
bf90435200 | ||
|
|
9c181fa3d3 | ||
|
|
3af0b1eb90 | ||
|
|
7110c318ee | ||
|
|
49a552ccdc | ||
|
|
57685f17a9 | ||
|
|
a1c09a463f | ||
|
|
194121760a | ||
|
|
6a987d46bf | ||
|
|
e3db0b39b9 | ||
|
|
4d4f0ee188 | ||
|
|
ac7334c167 | ||
|
|
e7bdd69af0 | ||
|
|
fefc655969 | ||
|
|
4dceaef60e | ||
|
|
6fc10dd3ae | ||
|
|
1ecd05a584 | ||
|
|
976acaca31 | ||
|
|
b4e5131d59 | ||
|
|
49f7cfefd7 | ||
|
|
fc365092f6 | ||
|
|
7f26240442 | ||
|
|
db559bb20a | ||
|
|
52850faa15 | ||
|
|
57d9a6c836 | ||
|
|
752c880bfc | ||
|
|
d83a354781 | ||
|
|
17dd81336d | ||
|
|
eaa46a2575 | ||
|
|
fc0ec1e71e | ||
|
|
fb2f92df1d | ||
|
|
74adbb77b7 | ||
|
|
788e544e1d | ||
|
|
368a0d4d2d | ||
|
|
962b7222d0 | ||
|
|
17c1f54369 | ||
|
|
33ae38e71b | ||
|
|
ef58af4bf1 | ||
|
|
3fad2db2f8 | ||
|
|
9feaeb28ca | ||
|
|
0075364715 | ||
|
|
99c5da5da5 | ||
|
|
22c957bc20 | ||
|
|
3316d59910 | ||
|
|
a109ce1eca | ||
|
|
e581a78d65 | ||
|
|
3c78f9900c | ||
|
|
bd606943e6 | ||
|
|
6381666df4 | ||
|
|
736f1aa301 | ||
|
|
b1a4eac7a8 | ||
|
|
8226a5276b | ||
|
|
77ad0bb12e | ||
|
|
9412b42206 | ||
|
|
2a91d87074 | ||
|
|
4a23617d79 | ||
|
|
0e2ceed74d | ||
|
|
ed56aed8eb | ||
|
|
8d909cbdc0 | ||
|
|
bf98943cbb | ||
|
|
6ff4552be2 | ||
|
|
1c7eb79370 | ||
|
|
f095a75f1e | ||
|
|
f70af6018c | ||
|
|
71b3b1ff4c | ||
|
|
d9fefa0c6c | ||
|
|
3bfe922381 | ||
|
|
a85cf17bf1 | ||
|
|
dbb5a09918 | ||
|
|
93e5097f20 | ||
|
|
dd53f2dc83 | ||
|
|
2b83c80593 | ||
|
|
6930f60c06 | ||
|
|
376b76e75c | ||
|
|
1ddd4509dc | ||
|
|
6af3f4f4cf | ||
|
|
6726c5f958 | ||
|
|
d5a9c43cb2 | ||
|
|
19a5a6a4eb | ||
|
|
617a599ee9 | ||
|
|
25e2d4da44 | ||
|
|
ad2e7218cb | ||
|
|
917637fa9b | ||
|
|
b595ee1c0b | ||
|
|
c8260a4a56 | ||
|
|
d2eaff3204 | ||
|
|
b65f5a844f | ||
|
|
95a69f99ba | ||
|
|
71d609895a | ||
|
|
9229630447 | ||
|
|
eb18a0b7dc | ||
|
|
05ed5c0d74 | ||
|
|
41330ecc5e | ||
|
|
16fbcc6e36 | ||
|
|
d87da9c7de | ||
|
|
94563b6017 | ||
|
|
34d22f7047 | ||
|
|
e24d996fbe | ||
|
|
9b52617919 | ||
|
|
efc1d46c89 | ||
|
|
9397833ceb | ||
|
|
e9433e83cd | ||
|
|
f3c58100a0 | ||
|
|
8900231d99 | ||
|
|
c7a63b8a2b | ||
|
|
90e90672a4 | ||
|
|
fa51e5c762 | ||
|
|
911f55d005 | ||
|
|
d30eb4e570 | ||
|
|
67bcfb6947 | ||
|
|
3915a61b1e | ||
|
|
c170d321e8 | ||
|
|
2802c476ee | ||
|
|
1050cebf7f | ||
|
|
dad73465fc | ||
|
|
8e2ac98fe2 | ||
|
|
9aaf0c36d5 | ||
|
|
1cb07e9cfd | ||
|
|
f1ccdf25b1 | ||
|
|
6dca497b27 | ||
|
|
42a83262a1 | ||
|
|
63ee9cbee6 | ||
|
|
3862f8ca7c | ||
|
|
4ada7cffd0 | ||
|
|
a664ce4298 | ||
|
|
8d7b6c6905 | ||
|
|
16d22d404a | ||
|
|
ccb24d5779 | ||
|
|
8795b45cb4 | ||
|
|
628d3bff45 | ||
|
|
0336bc9de9 | ||
|
|
033cb21797 | ||
|
|
09b98a45df | ||
|
|
38857ba29e | ||
|
|
1c7520ec8f | ||
|
|
362b9769b2 | ||
|
|
b2d68bd3d2 | ||
|
|
0dc7e635d4 | ||
|
|
80e070a857 | ||
|
|
cc203245e4 | ||
|
|
2f9a65fc93 | ||
|
|
62738e8001 | ||
|
|
5ecacf0c7f | ||
|
|
06b103c8d4 | ||
|
|
d473b7bca8 | ||
|
|
50a1e81ba7 | ||
|
|
d9885b1b64 | ||
|
|
0a9c8cada2 | ||
|
|
60f55f8461 | ||
|
|
7bedaea38f | ||
|
|
9e4b87e798 | ||
|
|
95bf59095c | ||
|
|
e0f34a9720 | ||
|
|
f3797c2a8e | ||
|
|
30cbcccc80 | ||
|
|
f49c0d696f | ||
|
|
71f564ee5b | ||
|
|
4b0950aba5 | ||
|
|
8c3af822ec | ||
|
|
878a207d19 | ||
|
|
0537ad860a | ||
|
|
2cdbbb1aea | ||
|
|
7af977d36b | ||
|
|
9afff4cf30 | ||
|
|
48ba9734aa | ||
|
|
897fc59f72 | ||
|
|
947e44ae67 | ||
|
|
e44843beba | ||
|
|
147482ea69 | ||
|
|
09091c5cf8 | ||
|
|
50827a5f69 | ||
|
|
2d6444c924 | ||
|
|
1d2675d9aa | ||
|
|
ad98990a8e | ||
|
|
8e58c143f2 | ||
|
|
556a4a2395 | ||
|
|
5be987b40f | ||
|
|
066bc35e69 | ||
|
|
403779437c | ||
|
|
fb806f61d4 | ||
|
|
6ce306661c | ||
|
|
3c08ff94d4 | ||
|
|
a6afae2356 | ||
|
|
0eea7070a7 | ||
|
|
105c2b1eea | ||
|
|
82bb0e8dda | ||
|
|
8c01179075 | ||
|
|
c9d9a96630 | ||
|
|
8f21c9a920 | ||
|
|
0ba7d05ea7 | ||
|
|
5a4c5b4155 | ||
|
|
55323fb497 | ||
|
|
7c082d2471 | ||
|
|
f3cafcf983 | ||
|
|
75073e4aa6 | ||
|
|
a3c23f650c | ||
|
|
0545cd5879 | ||
|
|
c96506f22c | ||
|
|
49b2006824 | ||
|
|
8c6f96faab | ||
|
|
a0e648abfd | ||
|
|
6350cd12fc | ||
|
|
f2fab0677b | ||
|
|
edffc52927 | ||
|
|
d6e5e3d103 | ||
|
|
5be7a0ebf7 | ||
|
|
7f722fe7d3 | ||
|
|
a01732ee9b | ||
|
|
85ac11b69b | ||
|
|
590cfb77a5 | ||
|
|
f01dd16a27 | ||
|
|
df49287e5f | ||
|
|
c8ec8391ee | ||
|
|
3499e48064 | ||
|
|
2e379cb8a5 | ||
|
|
f8ee3c2369 | ||
|
|
c74fa11518 | ||
|
|
ceec4455df | ||
|
|
17c9975c0b | ||
|
|
6c1cdff912 | ||
|
|
79f53f569d | ||
|
|
ccb85cc719 | ||
|
|
c0eff8a07f | ||
|
|
954626f157 | ||
|
|
17e7dfa4bd | ||
|
|
971f233fb7 | ||
|
|
b12bc692af | ||
|
|
730301b34d | ||
|
|
c443bcf43c | ||
|
|
b77e7eeddc | ||
|
|
031b7b57a1 | ||
|
|
5123fab525 | ||
|
|
705b96c6f9 | ||
|
|
9ec582002b | ||
|
|
ee79277774 | ||
|
|
db02dc218e | ||
|
|
b66ce1089e | ||
|
|
ec0e70b599 | ||
|
|
a273482f9d | ||
|
|
76cf8c4cf7 | ||
|
|
9691ecc839 | ||
|
|
59b2a86359 | ||
|
|
fe7cd72cff | ||
|
|
f0761fc570 | ||
|
|
90990aa19d | ||
|
|
a3d3ce82e4 | ||
|
|
b8e48113a3 | ||
|
|
d4b1003a97 | ||
|
|
efd83567c9 | ||
|
|
5563f373f7 | ||
|
|
15a36619fe | ||
|
|
38e54b626e | ||
|
|
8aa30fb56a | ||
|
|
b764becd1b | ||
|
|
219370932e | ||
|
|
90afae186c | ||
|
|
84e49a809d | ||
|
|
1cfb9ff46a | ||
|
|
f35026c74f | ||
|
|
5f2d3da8c5 | ||
|
|
4e61f32a28 | ||
|
|
d7814c7011 | ||
|
|
aa40668e84 | ||
|
|
3767e6e96f | ||
|
|
44976cef6c | ||
|
|
eba4417947 | ||
|
|
c99204d370 | ||
|
|
1bfc4335bb | ||
|
|
6b9c7485f1 | ||
|
|
737f3d78f2 | ||
|
|
b1d5e1b5e3 | ||
|
|
8d92a5cc14 | ||
|
|
fc455df92c | ||
|
|
c0076ebfa1 | ||
|
|
5d607aa3cd | ||
|
|
fa1b9a4098 | ||
|
|
c8c4dbb409 | ||
|
|
16628e6cea | ||
|
|
7067c12991 | ||
|
|
7b47e241e0 | ||
|
|
d1e46207a5 | ||
|
|
2a04b97cbd | ||
|
|
e6c8ef59e0 | ||
|
|
d3380f41de | ||
|
|
4ef1633969 | ||
|
|
57e593aab2 | ||
|
|
6461caacbb | ||
|
|
e5531e2a93 | ||
|
|
329402a614 | ||
|
|
4656ed462e | ||
|
|
96ddad91a9 | ||
|
|
5eb40588d2 | ||
|
|
58def149aa | ||
|
|
0ee5743d75 | ||
|
|
7c266f3e81 | ||
|
|
d7ce981cd1 | ||
|
|
eadadf6299 | ||
|
|
8ac9fabd07 | ||
|
|
44c2b4b281 | ||
|
|
4cd97611e5 | ||
|
|
da27380ab5 | ||
|
|
756e539661 | ||
|
|
cde44e3172 | ||
|
|
e79a4b34b0 | ||
|
|
e9f0bdd72c | ||
|
|
d080291150 | ||
|
|
06c69c56ba | ||
|
|
d79710ba9d | ||
|
|
c9bc7dd0b6 | ||
|
|
ebc26c7421 | ||
|
|
3769425f6b | ||
|
|
a50957443e | ||
|
|
63fa007af0 | ||
|
|
a6a52a128b | ||
|
|
1ad58e1121 | ||
|
|
3f507a26fb | ||
|
|
bfc368764a | ||
|
|
53fbce932b | ||
|
|
a94195c6cd | ||
|
|
626c6d1124 | ||
|
|
471ab92bbb | ||
|
|
fbccd12924 | ||
|
|
e5928bbaea | ||
|
|
3c1597bc67 | ||
|
|
295019815e | ||
|
|
654a391250 | ||
|
|
9ee1465d3c | ||
|
|
52197cf4d2 | ||
|
|
cfbb2afac5 | ||
|
|
8f154f65f9 | ||
|
|
7454664997 | ||
|
|
3393b7aedd | ||
|
|
133ccc95b5 | ||
|
|
c392ff1cd3 | ||
|
|
30a0f831a5 | ||
|
|
541ea4dc63 | ||
|
|
afc5e0e3e5 | ||
|
|
bcb31df10d | ||
|
|
2192c4e269 | ||
|
|
eec17858c4 | ||
|
|
6d696706be | ||
|
|
8cd88b6051 | ||
|
|
9dbf53fdb9 | ||
|
|
38b6963c8b | ||
|
|
7b6248983d | ||
|
|
4d418dee0e | ||
|
|
06fe319347 | ||
|
|
9dd7e3fb24 | ||
|
|
d5a46396b0 | ||
|
|
5e84cb560d | ||
|
|
756c6f8560 | ||
|
|
6fa6ce35da | ||
|
|
b14b97599d | ||
|
|
db6f60d6fc | ||
|
|
25c348d7c8 | ||
|
|
2e4bf8b034 | ||
|
|
c1490e2f7b | ||
|
|
b004fe9556 | ||
|
|
67142ad046 | ||
|
|
3c3ec06b12 | ||
|
|
5b5caa8a16 | ||
|
|
b2cba098bb | ||
|
|
1ec0d47f10 | ||
|
|
f232606ec7 | ||
|
|
fa28cea152 | ||
|
|
c8da1647a1 | ||
|
|
505a0a8718 | ||
|
|
10d3496a17 | ||
|
|
a13c755370 | ||
|
|
62f9996fd7 | ||
|
|
edbcd8a1b2 | ||
|
|
a5308d1689 | ||
|
|
cbfe6e8fcc | ||
|
|
5571ff35d8 | ||
|
|
2a4819f3c8 | ||
|
|
7121866b13 | ||
|
|
d6e05ad9e2 | ||
|
|
993e30a7de | ||
|
|
49cae61254 | ||
|
|
1ea4b2ea91 | ||
|
|
bc1d6e1f90 | ||
|
|
9ec6e68d0c | ||
|
|
341bdc93e2 | ||
|
|
6fb3e1aa15 | ||
|
|
f1f92eb2e2 | ||
|
|
8c2369d40f | ||
|
|
a6d9fc58eb | ||
|
|
f7cd471548 | ||
|
|
5f951faf32 | ||
|
|
b228dfaf2c | ||
|
|
764858fa12 | ||
|
|
5ee976d276 | ||
|
|
8b28b6f2d3 | ||
|
|
fe16df2e6f | ||
|
|
779047f8c9 | ||
|
|
094e9fb45d | ||
|
|
1458bd0e74 | ||
|
|
d2cb05988d | ||
|
|
6e056767b4 | ||
|
|
a10afb1b98 | ||
|
|
bb6d3b6cfd | ||
|
|
c75d4af4bc | ||
|
|
972dc39d00 | ||
|
|
9daac5c178 | ||
|
|
dd2a3f40e1 | ||
|
|
78f76c1690 | ||
|
|
4788066a5f | ||
|
|
10e4254e7d | ||
|
|
0106e4df9d | ||
|
|
8ac718a3a2 | ||
|
|
46d45273a1 | ||
|
|
8da9ec3599 | ||
|
|
01fdf84d69 | ||
|
|
cc78386e75 | ||
|
|
3755157c61 | ||
|
|
80f8436f0a | ||
|
|
f88a4b7760 | ||
|
|
de229b8ab0 | ||
|
|
a3ba37e45e | ||
|
|
50c779b3c6 | ||
|
|
192372e1c3 | ||
|
|
f88fd88c38 | ||
|
|
6e15145af1 | ||
|
|
4b5fad4e48 | ||
|
|
7a13e71c80 | ||
|
|
3c10943900 | ||
|
|
696b8811c2 | ||
|
|
9fd2c8602a | ||
|
|
a3636a5af4 | ||
|
|
f2e5f07718 | ||
|
|
16c6fdde60 | ||
|
|
2155c93426 | ||
|
|
c394631e4c | ||
|
|
8b370b7cc1 | ||
|
|
607db9971c | ||
|
|
6768f64e2f | ||
|
|
f1813b1cc6 | ||
|
|
fb665bd0dd | ||
|
|
65dda2ef3d | ||
|
|
b162b992af | ||
|
|
67a3a3d130 | ||
|
|
92cd9bf7d2 | ||
|
|
bf97034485 | ||
|
|
1ded1fc509 | ||
|
|
e0592c58b3 | ||
|
|
5ead2706b4 | ||
|
|
52ada4853c | ||
|
|
c2b27a8298 | ||
|
|
3934c1d437 | ||
|
|
e366b68ad3 | ||
|
|
fb94fb980a | ||
|
|
b10cc18f53 | ||
|
|
a249de3b72 | ||
|
|
d04e972d65 | ||
|
|
b9f5a18a76 | ||
|
|
d3f157f08a | ||
|
|
2294fdb496 | ||
|
|
d7ba0e01a5 | ||
|
|
b6172b53fd | ||
|
|
477ec611d5 | ||
|
|
b6194edd67 | ||
|
|
dcdbbb3ecb | ||
|
|
7ef99ee4e6 | ||
|
|
1ac1418286 | ||
|
|
8fc854f38e | ||
|
|
1c2360b335 | ||
|
|
dd4477406b | ||
|
|
9d67bbb104 | ||
|
|
d6c8e1df61 | ||
|
|
5ec7c8fece | ||
|
|
86b21eaf83 | ||
|
|
228486a971 | ||
|
|
88c0caab26 | ||
|
|
5cd4679419 | ||
|
|
eeed5e0d19 | ||
|
|
369ab1e0b2 | ||
|
|
2e21519a10 | ||
|
|
ecc001ed08 | ||
|
|
cd96852696 | ||
|
|
b9f7f30158 | ||
|
|
ca5e423331 | ||
|
|
fa9407089c | ||
|
|
66f28e193a | ||
|
|
0d93f89f5c | ||
|
|
154e9a2c47 | ||
|
|
84574a1257 | ||
|
|
bf83527b64 | ||
|
|
12c53622a0 | ||
|
|
d8f54cf891 | ||
|
|
625a671189 | ||
|
|
6ebdad3102 | ||
|
|
9a8f21aa03 | ||
|
|
291dd8edc2 | ||
|
|
de4c1daf29 | ||
|
|
0b55d7d0d8 | ||
|
|
5d86fd8fdb | ||
|
|
1b76eb1f59 | ||
|
|
b05678d8bf | ||
|
|
781f4971c6 | ||
|
|
d02ac7b99a | ||
|
|
b1b6c97f7c | ||
|
|
baee28ab5c | ||
|
|
83edf68ff9 | ||
|
|
c7588f91dd | ||
|
|
30b432adc5 | ||
|
|
7c9733eb5d | ||
|
|
a223c3fea3 | ||
|
|
d5250f4901 | ||
|
|
25f29f4712 | ||
|
|
382af5563d | ||
|
|
8cf3d165d3 | ||
|
|
0fd6ce546f | ||
|
|
b881c372bc | ||
|
|
94c5e7deb0 | ||
|
|
c344766f3c | ||
|
|
67895de0bc | ||
|
|
ff00cb6990 | ||
|
|
2cc75c11ed | ||
|
|
cd79e58eda | ||
|
|
6fa801f3d8 | ||
|
|
684eecba1d | ||
|
|
da9cf7e5de | ||
|
|
f57e7445fd | ||
|
|
fba1388719 | ||
|
|
80ed029c17 | ||
|
|
34a74e81e3 | ||
|
|
cb120ddb15 | ||
|
|
f9ee4395b0 | ||
|
|
71f06d51ed | ||
|
|
217f70952f | ||
|
|
f813d41a76 | ||
|
|
d851289d8a | ||
|
|
b115b8a2ea | ||
|
|
d0f7067471 | ||
|
|
be5b4c38a7 | ||
|
|
d6d597e3dd | ||
|
|
84e348fade | ||
|
|
910054657e | ||
|
|
8357a11249 | ||
|
|
9b021ba057 | ||
|
|
317e588efd | ||
|
|
b1d32a03c7 | ||
|
|
ee6e6529ee | ||
|
|
9d944d6cf9 | ||
|
|
13635d281a | ||
|
|
2493c46970 | ||
|
|
63e4217271 | ||
|
|
f4bd12e8e9 | ||
|
|
df15f46900 | ||
|
|
fb3a732361 | ||
|
|
2d74110feb | ||
|
|
19d102082d | ||
|
|
d2af2c9487 | ||
|
|
82980149fa | ||
|
|
a19bb7b909 | ||
|
|
9d98c3278d | ||
|
|
26376ac1c9 | ||
|
|
8459f99341 | ||
|
|
e5bdb0e0b5 | ||
|
|
1106b7775a | ||
|
|
ae2852156d | ||
|
|
44c6c36c43 | ||
|
|
a81926503d | ||
|
|
af13ccddda | ||
|
|
392e1bc2e8 | ||
|
|
9268d92c70 | ||
|
|
bb3366c07d | ||
|
|
d24d563ebc | ||
|
|
954bd9257b | ||
|
|
5d51a56c02 | ||
|
|
f48648552e | ||
|
|
edb9c3cc9f | ||
|
|
01dc83b936 | ||
|
|
3a8dff3a62 | ||
|
|
13b234ccba | ||
|
|
e451e93664 | ||
|
|
b4f9531475 | ||
|
|
3184ff75c4 | ||
|
|
43243f4d30 | ||
|
|
c975a100b1 | ||
|
|
02bf389425 | ||
|
|
bcb9a3dd04 | ||
|
|
cce3baa275 | ||
|
|
2b48fad426 | ||
|
|
d554b2bc94 | ||
|
|
f66943de43 | ||
|
|
9d1e9bc2fb | ||
|
|
2d6a014920 | ||
|
|
c1952bf257 | ||
|
|
a10227eb03 | ||
|
|
475ae29b85 | ||
|
|
0b9cfc278b | ||
|
|
b57b6b4fba | ||
|
|
7d948f7bc5 | ||
|
|
459023d171 | ||
|
|
fd6570720a | ||
|
|
7831665417 | ||
|
|
7c9920d982 | ||
|
|
cbdccf0a9c | ||
|
|
64fa83ec3f | ||
|
|
faff865cfd | ||
|
|
742ab55a9a | ||
|
|
66e623fb2a | ||
|
|
4ab17ee965 | ||
|
|
7f48ca5132 | ||
|
|
da983848b4 | ||
|
|
bc03f7bad3 | ||
|
|
a1c8bd3846 | ||
|
|
404bc284e0 | ||
|
|
9dee30ff0e | ||
|
|
f91aadbea8 | ||
|
|
aa15a10c91 | ||
|
|
5b03e36351 | ||
|
|
b9ba9ffad2 | ||
|
|
642be5d16c | ||
|
|
ee68d715bf | ||
|
|
224084f056 | ||
|
|
1cd8c849b8 | ||
|
|
169f68bfcd | ||
|
|
d2b7cfa2d1 | ||
|
|
a40c7dff5d | ||
|
|
e8e00630d3 | ||
|
|
e33720c854 | ||
|
|
bd8a4e0d17 | ||
|
|
586a2aef76 | ||
|
|
ce1d8f6754 | ||
|
|
7b0f401065 | ||
|
|
8387016eef | ||
|
|
4e1342b641 | ||
|
|
e45a184d90 | ||
|
|
979e1012d2 | ||
|
|
fe10a50e23 | ||
|
|
8ab6d72519 | ||
|
|
3aada6dd1d | ||
|
|
0933036366 | ||
|
|
05f5abdc06 | ||
|
|
fb875e0709 | ||
|
|
9acdc2f6bf | ||
|
|
028ce4bff6 | ||
|
|
3f245ad6db | ||
|
|
23115f4116 | ||
|
|
cf5f48e6cc | ||
|
|
997fa756ad | ||
|
|
e23f75b1cc | ||
|
|
6531e88761 | ||
|
|
e76a9c2618 | ||
|
|
45be8a836b | ||
|
|
954b6032e7 | ||
|
|
bd95416f27 | ||
|
|
df2577ace2 | ||
|
|
720e6558c9 | ||
|
|
c239f15d8a | ||
|
|
dfa1f80a57 | ||
|
|
15dfb93b17 | ||
|
|
0ec8488c2b | ||
|
|
94b2e29cb1 | ||
|
|
fefa8e9b4d | ||
|
|
32c4c44812 | ||
|
|
05195e2b1d | ||
|
|
4c2ff675b8 | ||
|
|
e5692a4721 | ||
|
|
312e6a0d31 | ||
|
|
5bb8efa41f | ||
|
|
949a835f4a | ||
|
|
85e6042941 | ||
|
|
3cd2f28975 | ||
|
|
2179a72c3a | ||
|
|
a5f282f156 | ||
|
|
40e8631f63 | ||
|
|
9ded05bb97 | ||
|
|
ec8efa35a1 | ||
|
|
f72bf20482 | ||
|
|
ebde2002e8 | ||
|
|
352a66f46f | ||
|
|
d84c5391f7 | ||
|
|
f4c582472b | ||
|
|
1485586f7e | ||
|
|
d5c9024335 | ||
|
|
860cf80703 | ||
|
|
897ff3161f | ||
|
|
b356b2e501 | ||
|
|
1d2733c893 | ||
|
|
32d9126094 | ||
|
|
db43314e50 | ||
|
|
68d2baeb65 | ||
|
|
1fd5f562d3 | ||
|
|
48e02f2086 | ||
|
|
eab7b2b581 | ||
|
|
45abade7fc | ||
|
|
5372fc4b43 | ||
|
|
4e2f240c98 | ||
|
|
bb3605518d | ||
|
|
3ef6d37f27 | ||
|
|
88e9f2f7f4 | ||
|
|
704a447df9 | ||
|
|
a5fcb26a33 | ||
|
|
2491a61481 | ||
|
|
91831d51ed | ||
|
|
174f0c19f7 | ||
|
|
de6fadfb4f | ||
|
|
f946db3e00 | ||
|
|
8d05e5bc31 | ||
|
|
cfb46820e4 | ||
|
|
081f1cbcc2 | ||
|
|
7bc6da326f | ||
|
|
cd95a0df7b | ||
|
|
82fa497c16 | ||
|
|
44fd345206 | ||
|
|
088e1c9db4 | ||
|
|
d4f16e666e | ||
|
|
8233cfd371 | ||
|
|
ff05e2e30d | ||
|
|
a8ea7dd3fb | ||
|
|
96f70a5303 | ||
|
|
f1604c3e69 | ||
|
|
c42c8c5192 | ||
|
|
5facb53a41 | ||
|
|
d039ce89af | ||
|
|
bc7605103f | ||
|
|
d305d655d4 | ||
|
|
4ef1220b16 | ||
|
|
a4fef143cd | ||
|
|
74ecb724a9 | ||
|
|
af235897ab | ||
|
|
5ec4e458b5 | ||
|
|
2dae63ce21 | ||
|
|
be748fe33b | ||
|
|
7408340b6a | ||
|
|
29eb92446e | ||
|
|
ae6918742e | ||
|
|
863484bb65 | ||
|
|
1cd7ebce4c | ||
|
|
eef8c7862e | ||
|
|
b52375d446 | ||
|
|
6e2babc2ce | ||
|
|
08e253bed1 | ||
|
|
c6661477a2 | ||
|
|
415cfd99a0 | ||
|
|
8c2e37381a | ||
|
|
45df79feba | ||
|
|
5824f992b7 | ||
|
|
b0b60fafd5 | ||
|
|
8d98b02ba2 | ||
|
|
a93fe79bc4 | ||
|
|
4aebd7be37 | ||
|
|
3170a5db32 | ||
|
|
3605b9eef6 | ||
|
|
a945f1fde2 | ||
|
|
461a997b5b | ||
|
|
a80afd7b4e | ||
|
|
aad2b51d85 | ||
|
|
36a9a81ff1 | ||
|
|
42c88546ae | ||
|
|
0f0e86ef9b | ||
|
|
98efd9a857 | ||
|
|
a0c27d95b7 | ||
|
|
984651d99d | ||
|
|
c6f7370b30 | ||
|
|
3e4b8e8985 | ||
|
|
73f08b98d2 | ||
|
|
8607a74206 | ||
|
|
8339f3ceb3 | ||
|
|
c0c9f3cc19 | ||
|
|
81f4813c29 | ||
|
|
94f57745b9 | ||
|
|
54fb2ebbe0 | ||
|
|
02d122b65b | ||
|
|
df0a5561a1 | ||
|
|
f7c55da7d0 | ||
|
|
b385f701ce | ||
|
|
05dd42f443 | ||
|
|
36d816d5cb | ||
|
|
92a6746e70 | ||
|
|
1728848a39 | ||
|
|
f9eb4e7487 | ||
|
|
d0b9f33aeb | ||
|
|
718583b241 | ||
|
|
6737127e9a | ||
|
|
19a7b4479b | ||
|
|
c340647502 | ||
|
|
0f987d2982 | ||
|
|
52bcaed169 | ||
|
|
177bd565ac | ||
|
|
c801c32fc5 | ||
|
|
d090cf3058 | ||
|
|
1e4b82cc94 | ||
|
|
3426f31184 | ||
|
|
b4fb7af1df | ||
|
|
b36647598b | ||
|
|
fd6b94f20e | ||
|
|
296dc0ed8a | ||
|
|
4f869e14d6 | ||
|
|
5704270e9d | ||
|
|
505b381e85 | ||
|
|
da6cb15393 | ||
|
|
16843f6cc8 | ||
|
|
64f3ad1fd4 | ||
|
|
ff4c4f99b3 | ||
|
|
f5d2e09569 | ||
|
|
f2bdbe0d4d | ||
|
|
c51a13caa6 | ||
|
|
7840c78a23 | ||
|
|
c706f3246b | ||
|
|
608eedf88d | ||
|
|
a564ca82be | ||
|
|
c868b1fee2 | ||
|
|
22374f718f | ||
|
|
abe3cfcf41 | ||
|
|
59db4b50cd | ||
|
|
bdae38765d | ||
|
|
66d3ceeb61 | ||
|
|
445dd17db3 | ||
|
|
cff78a2577 | ||
|
|
6a09e64195 | ||
|
|
22eabe5eab | ||
|
|
b69ba36c2d | ||
|
|
5240aad22b | ||
|
|
2897eb3cb3 | ||
|
|
d3f2f00c25 | ||
|
|
bacfb913a0 | ||
|
|
c99d0236a0 | ||
|
|
aac2b655f7 | ||
|
|
126c41e73a | ||
|
|
359ee54f0d | ||
|
|
28ab560907 | ||
|
|
ead252fee4 | ||
|
|
abf67914c4 | ||
|
|
127884e9dd | ||
|
|
654f5049eb | ||
|
|
979ca34259 | ||
|
|
4dd1086805 | ||
|
|
3503d4b72c | ||
|
|
b8d32a0d33 | ||
|
|
45dca55fc8 | ||
|
|
445d8ecd9f | ||
|
|
c980add503 | ||
|
|
133842392a | ||
|
|
8baf2ef155 | ||
|
|
20b71340bc | ||
|
|
61d8baf8b1 | ||
|
|
56a9645aa5 | ||
|
|
85877000a6 | ||
|
|
2f7d2477b6 | ||
|
|
21ea3f05f4 | ||
|
|
79d3492e90 | ||
|
|
5972777abe | ||
|
|
8e373ff868 | ||
|
|
a4db92da3a | ||
|
|
9b777eb281 | ||
|
|
bd3c652184 | ||
|
|
800f747570 | ||
|
|
2b8423437e | ||
|
|
8b4b6945f8 | ||
|
|
e5ecfec5c4 | ||
|
|
f95dbff71f | ||
|
|
098f6830a6 | ||
|
|
d1ecebdb52 | ||
|
|
590b654251 | ||
|
|
3bf190c8ab | ||
|
|
dcca7638e0 | ||
|
|
70e45ad37b | ||
|
|
db88210289 | ||
|
|
d2e0d96cc3 | ||
|
|
3feba82ccc | ||
|
|
db924da231 | ||
|
|
fc55ae7e6d | ||
|
|
86e757a6ad | ||
|
|
4790715cd3 | ||
|
|
e7e9c60042 | ||
|
|
1c3bc52cc4 | ||
|
|
5227dff0e1 | ||
|
|
33f0b5b7c2 | ||
|
|
0a02968303 | ||
|
|
f7bf658c07 | ||
|
|
8d16a0abad | ||
|
|
c974b97ca3 | ||
|
|
b8025bfebd | ||
|
|
30323b253f | ||
|
|
535c3ede96 | ||
|
|
89fed8ca33 | ||
|
|
f43c77aaed | ||
|
|
96c676b371 | ||
|
|
113047e1a2 | ||
|
|
abed57cb53 | ||
|
|
c01a800a6b | ||
|
|
d648832a2d | ||
|
|
f06833fbd2 | ||
|
|
c561addc94 | ||
|
|
702f5f1f4c | ||
|
|
1273f179e8 | ||
|
|
5d02f60bde | ||
|
|
4cf7a108e8 | ||
|
|
42635c3938 | ||
|
|
ed43dc842b | ||
|
|
49d4db6cd2 | ||
|
|
ea80ab2cae | ||
|
|
382e808b8d | ||
|
|
846befa7e0 | ||
|
|
74dd29f843 | ||
|
|
b0473bffcb | ||
|
|
24dd9ab1a7 | ||
|
|
49d3037e87 | ||
|
|
37ad2bd4e8 | ||
|
|
7d7b332b02 | ||
|
|
ac033b8612 | ||
|
|
a7b98dfe25 | ||
|
|
7fb7c86c46 | ||
|
|
ed036598a9 | ||
|
|
160bb70cdf | ||
|
|
c2e61f3c21 | ||
|
|
18218467f3 | ||
|
|
17e298ad2a | ||
|
|
d031a374f9 | ||
|
|
55f69c98cb | ||
|
|
71f2e4306d | ||
|
|
f8af23a025 | ||
|
|
4ef55a6cd3 | ||
|
|
312f866723 | ||
|
|
0ebe1f6dec | ||
|
|
2ad92e0e6e | ||
|
|
ac8823cdcf | ||
|
|
77565f7ee4 | ||
|
|
d656d90fa8 | ||
|
|
175b3b0834 | ||
|
|
7477e6b714 | ||
|
|
cd6568db69 | ||
|
|
6aff325fb2 | ||
|
|
0d603cfe9c | ||
|
|
34a1f14a17 | ||
|
|
efe1c8a070 | ||
|
|
1575844344 | ||
|
|
221ac1c208 | ||
|
|
57442db759 | ||
|
|
5fdb3e7cd6 | ||
|
|
96f259726c | ||
|
|
4936efba5e | ||
|
|
d5a3559a2f | ||
|
|
114a1c7f52 | ||
|
|
ce5265c203 | ||
|
|
1a575d926f | ||
|
|
85c818a39e | ||
|
|
4ffa2defe4 | ||
|
|
8825157fbb | ||
|
|
966d608dc5 | ||
|
|
b808c89471 | ||
|
|
75d4e6490f | ||
|
|
a82775f544 | ||
|
|
6a22ad0171 | ||
|
|
c854e88186 | ||
|
|
d02203060c | ||
|
|
cf703b0433 | ||
|
|
c0197a72d3 | ||
|
|
e5a543e283 | ||
|
|
b8b029b7d3 | ||
|
|
370f368b1a | ||
|
|
8288b45b4f | ||
|
|
fe529faf8e | ||
|
|
ab931b177d | ||
|
|
9aa3465513 | ||
|
|
6c70fc1a6c | ||
|
|
1ccc39962a | ||
|
|
99c941fc85 | ||
|
|
19729fdcc2 | ||
|
|
02e17998ce | ||
|
|
459e00c67a | ||
|
|
292f665650 | ||
|
|
93bbb79569 | ||
|
|
273e724f2b | ||
|
|
5d2615c56f | ||
|
|
bfaaf21330 | ||
|
|
dcb8415b7a | ||
|
|
699e1c75ce | ||
|
|
465b6e613e | ||
|
|
05fa105855 | ||
|
|
d7a0cdebe5 | ||
|
|
b049ab31eb | ||
|
|
6db4dcff7a | ||
|
|
3eeaef00ec | ||
|
|
8bf4c38a00 | ||
|
|
3a32b09ad1 | ||
|
|
6315982752 | ||
|
|
374a171e82 | ||
|
|
fc5d801f91 | ||
|
|
5146641848 | ||
|
|
cdd0ac42cf | ||
|
|
e5895500a2 | ||
|
|
9cb4dde3fa | ||
|
|
3c2a4370a5 | ||
|
|
e7a360dd6f | ||
|
|
c814c2fd35 | ||
|
|
fefa7fe262 | ||
|
|
26f01a29d1 | ||
|
|
169d4090ab | ||
|
|
0b43754d60 | ||
|
|
8b3b26b813 | ||
|
|
5426af4f81 | ||
|
|
4e2c3a579d | ||
|
|
5ae2693241 | ||
|
|
41c86b0d19 | ||
|
|
40788e8c3d | ||
|
|
0d29120033 | ||
|
|
4be598f865 | ||
|
|
558a6d509e | ||
|
|
75cd02aad2 | ||
|
|
e4c4451482 | ||
|
|
0671632477 | ||
|
|
54c230c264 | ||
|
|
64ba878eda | ||
|
|
01acd6dd76 | ||
|
|
9d819b52d3 | ||
|
|
37bac5cdc9 | ||
|
|
78c718c591 | ||
|
|
284b8bf6ca | ||
|
|
5a5084b837 | ||
|
|
3b8058e1f1 | ||
|
|
2a3168e0d6 | ||
|
|
a8ac6e4a15 | ||
|
|
6172cf9fba | ||
|
|
b728ec3909 | ||
|
|
61a53bbcff | ||
|
|
17d13dd084 | ||
|
|
edcb28d591 | ||
|
|
ad101119a7 | ||
|
|
bc36676d31 | ||
|
|
d76fe120ab | ||
|
|
2e95949b80 | ||
|
|
ae14d85e24 | ||
|
|
fad6304c60 | ||
|
|
a4dd3c8ce9 | ||
|
|
6d1a5d45e2 | ||
|
|
a6c7043e03 | ||
|
|
bcc400dafa | ||
|
|
8fbedf3441 | ||
|
|
2e8a9c9874 | ||
|
|
44fc41b3e5 | ||
|
|
7212c20a1b | ||
|
|
7ff142de1c | ||
|
|
e67efb199d | ||
|
|
20128bd04b | ||
|
|
c0fefdde28 | ||
|
|
f6ee160e66 | ||
|
|
06acc2004f | ||
|
|
43ac2ce4c8 | ||
|
|
b32bf72b5f | ||
|
|
c6880c957e | ||
|
|
095b71ed96 | ||
|
|
9160e496bc | ||
|
|
2a7ac78f02 | ||
|
|
64efa4627d | ||
|
|
f7e35569ce | ||
|
|
e8af32ec2b | ||
|
|
e092ce51f6 | ||
|
|
7b78edb1b7 | ||
|
|
b332e7090e | ||
|
|
67eb7723d6 | ||
|
|
251d138474 | ||
|
|
1170dfac05 | ||
|
|
4157f141c7 | ||
|
|
f569abd28a | ||
|
|
088f9687c0 | ||
|
|
e23df1f07a | ||
|
|
c818540dfd | ||
|
|
21365cbe1a | ||
|
|
5471a80a96 | ||
|
|
d7b6fa9cd0 | ||
|
|
dfdc2e02ef | ||
|
|
893ec9a302 | ||
|
|
05f65c38e6 | ||
|
|
2e9d062ec0 | ||
|
|
6b0b394e61 | ||
|
|
25621396c9 | ||
|
|
82aa0271f3 | ||
|
|
653cab13f8 | ||
|
|
b526f86b49 | ||
|
|
53c0f00888 | ||
|
|
f0c4d9de40 | ||
|
|
03ef8cec83 | ||
|
|
85f2a2e8c2 | ||
|
|
584b3e6642 | ||
|
|
39b7ef841d | ||
|
|
aa16a9098d | ||
|
|
7b8c2707bc | ||
|
|
60e26a31a7 | ||
|
|
3473c25c14 | ||
|
|
e52f022026 | ||
|
|
b1a7df8e43 | ||
|
|
0fd2479b7c | ||
|
|
273857f914 | ||
|
|
a08b85dbc8 | ||
|
|
a0aedf299a | ||
|
|
3c61426844 | ||
|
|
786f228076 | ||
|
|
004da28792 | ||
|
|
6e2be6efb6 | ||
|
|
a994dfcfbc | ||
|
|
7a8ea2ac93 | ||
|
|
0da3965d19 | ||
|
|
885fd7bb46 | ||
|
|
08771f9c89 | ||
|
|
8be48195a5 | ||
|
|
98ce2d650e | ||
|
|
3af327116a | ||
|
|
b75434db93 | ||
|
|
04e912aacd | ||
|
|
d7be352f87 | ||
|
|
96be3ec22c | ||
|
|
32e7e0d790 | ||
|
|
becc320e62 | ||
|
|
7666ed57d1 | ||
|
|
5e61d0955e | ||
|
|
e8a4662ae7 | ||
|
|
a48da3bd3b | ||
|
|
5f1a5d7b99 | ||
|
|
3e28a9db8f | ||
|
|
ebf6071d77 | ||
|
|
47a35fb9fb | ||
|
|
48e88aba44 | ||
|
|
b85f99c140 | ||
|
|
0a5e0e1f71 | ||
|
|
85dc22ebb7 | ||
|
|
5c21526009 | ||
|
|
14dff1cefc | ||
|
|
39fbb844f9 | ||
|
|
ca4e0c973a | ||
|
|
ecb42bee80 | ||
|
|
674ed2a9f3 | ||
|
|
252daf9717 | ||
|
|
196b8eaad3 | ||
|
|
8e526ba1bf | ||
|
|
19225828d9 | ||
|
|
7e594126be | ||
|
|
d2529e6334 | ||
|
|
97344f18e2 | ||
|
|
33934db629 | ||
|
|
6c6165c9f5 | ||
|
|
853460b20d | ||
|
|
cc4d9676c5 | ||
|
|
1cf1b819f4 | ||
|
|
f916c66d2b | ||
|
|
550aa86b45 | ||
|
|
014e764758 | ||
|
|
d1fc28432b | ||
|
|
879576f0a2 | ||
|
|
69098210be | ||
|
|
99df4f892d | ||
|
|
7bc04fbad3 | ||
|
|
8a74ce578d | ||
|
|
0805e4e5de | ||
|
|
f1060fc88e | ||
|
|
7d3d3d0a3a | ||
|
|
40377032e3 | ||
|
|
b2971edd7d | ||
|
|
c37d723692 | ||
|
|
30f9026e1d | ||
|
|
332286072e | ||
|
|
d6da172a2a | ||
|
|
ebfe584afc | ||
|
|
6250023583 | ||
|
|
6b4f3d63b8 | ||
|
|
56db773a09 | ||
|
|
fc6c472401 | ||
|
|
2cd42a6866 | ||
|
|
36a90c345c | ||
|
|
ef1e82c72c | ||
|
|
88f9534685 | ||
|
|
68254a052a | ||
|
|
2425b3a166 | ||
|
|
5524ed753b | ||
|
|
89711723da | ||
|
|
bed2740ffd | ||
|
|
751d633c3d | ||
|
|
45952cbdf2 | ||
|
|
b355dd7b23 | ||
|
|
48a186f172 | ||
|
|
39dc7ec2ab | ||
|
|
2fedabd3b9 | ||
|
|
6d719e9480 | ||
|
|
05e278afda | ||
|
|
87dbf462cb | ||
|
|
40e896bc5b | ||
|
|
3e940f80c7 | ||
|
|
dbf2888d43 | ||
|
|
d412355324 | ||
|
|
178732217f | ||
|
|
de17b95c3d | ||
|
|
d14e774525 | ||
|
|
ca5402a7fa | ||
|
|
7a6fa7c5b4 | ||
|
|
da36c286a6 | ||
|
|
d3901bcf2e | ||
|
|
94c8d4fdfb | ||
|
|
ab8bdc18bb | ||
|
|
c9dcd7442a | ||
|
|
34c8f13346 | ||
|
|
7a8ccda95c | ||
|
|
44a1448542 | ||
|
|
c87d89ffaf | ||
|
|
0868749d42 | ||
|
|
1d40ee23f0 | ||
|
|
8893f32603 | ||
|
|
adcf7e8dc3 | ||
|
|
901f7c5c36 | ||
|
|
775bb413b3 | ||
|
|
64cd5b5a46 | ||
|
|
ae356609b1 | ||
|
|
6102a5d2b0 | ||
|
|
f8782ee2d7 | ||
|
|
6181ec4c77 | ||
|
|
e0e7a685ef | ||
|
|
ae1f8cdad2 | ||
|
|
a4cf792e6d | ||
|
|
89109ded53 | ||
|
|
e20e52a4b2 | ||
|
|
20c4b1cbec | ||
|
|
5238b0241d | ||
|
|
9cdf6c203d | ||
|
|
839335cae6 | ||
|
|
a99b2ce167 | ||
|
|
b695141d87 | ||
|
|
92d5c9f866 | ||
|
|
7f18a1ffe0 | ||
|
|
8c3fdaaa62 | ||
|
|
5ac1c69710 | ||
|
|
de2d5fba63 | ||
|
|
33d516748f | ||
|
|
de17f6f0fd | ||
|
|
756731fc02 | ||
|
|
e46be0415f | ||
|
|
aa02fb50bf | ||
|
|
8b6cd9c772 | ||
|
|
cdd0d3351a | ||
|
|
8b6d584529 | ||
|
|
f49fdd4141 | ||
|
|
b26e1be81a | ||
|
|
bacab38d7f | ||
|
|
701c05ce96 | ||
|
|
438c452585 | ||
|
|
0a7a1eff3f | ||
|
|
87e743e381 | ||
|
|
a03f1b3d55 | ||
|
|
2d8dc3d243 | ||
|
|
b982232cc5 | ||
|
|
61c8d728ac | ||
|
|
851a2bf855 | ||
|
|
e0bdde3630 | ||
|
|
6a0dcd7f0e | ||
|
|
75f0b4c879 | ||
|
|
db536a9504 | ||
|
|
0fb114dede | ||
|
|
e703342179 | ||
|
|
35c8f4a611 | ||
|
|
7c89ae44a9 | ||
|
|
84fe06da22 | ||
|
|
806318c8b3 | ||
|
|
3aac2e1822 | ||
|
|
168baef433 | ||
|
|
6dba6cd78d | ||
|
|
502250d08f | ||
|
|
7395f0e680 | ||
|
|
494d3fdaca | ||
|
|
7b86a157de | ||
|
|
0988c41785 | ||
|
|
522db1bf01 | ||
|
|
06f066f90d | ||
|
|
f37b20677b | ||
|
|
cd2eac1032 | ||
|
|
8ac38d58d7 | ||
|
|
4c80cc313a | ||
|
|
1c65fee9b4 | ||
|
|
90dda7edc1 | ||
|
|
da054fae20 | ||
|
|
bdb6611e30 | ||
|
|
9284f973f1 | ||
|
|
2bfd64c3c9 | ||
|
|
939d24cce5 | ||
|
|
27b0183c46 | ||
|
|
d14efacac7 | ||
|
|
150a002c40 | ||
|
|
ce0def3bd8 | ||
|
|
ee20fa97c2 | ||
|
|
7403b7d700 | ||
|
|
87ef173e0a | ||
|
|
52a3fb6bc7 | ||
|
|
92e2a257a6 | ||
|
|
32e175752c | ||
|
|
d43f7180dc | ||
|
|
0129c2b0fc | ||
|
|
4ed1990001 | ||
|
|
5bd6ab27ae | ||
|
|
f3593b89fa | ||
|
|
23d84b2310 | ||
|
|
fdc49402ec | ||
|
|
5457c133e1 | ||
|
|
292e588ee3 | ||
|
|
243494c25e | ||
|
|
e4365f3706 | ||
|
|
310f3038d3 | ||
|
|
4e6033273d | ||
|
|
73718586d3 | ||
|
|
011abe61e8 | ||
|
|
fe3a37f89d | ||
|
|
8aea44e77b | ||
|
|
5529aec0d6 | ||
|
|
369549d23f | ||
|
|
181ea9a381 | ||
|
|
76b8f2854e | ||
|
|
320e5198f9 | ||
|
|
e522539e2d | ||
|
|
7c996b83d2 | ||
|
|
3dd354d7aa | ||
|
|
f4ad6e2157 | ||
|
|
8b170dc2bf | ||
|
|
dcb9d779bf | ||
|
|
80f736d670 | ||
|
|
8502c6da3c | ||
|
|
b131449422 | ||
|
|
6eebc4a620 | ||
|
|
4661ab1179 | ||
|
|
86046445ed | ||
|
|
baea9bf944 | ||
|
|
0951ee9e63 | ||
|
|
5492528287 | ||
|
|
14dbd220c2 | ||
|
|
babc890c59 | ||
|
|
6f7b47ff40 | ||
|
|
3991f03202 | ||
|
|
27271d5da7 | ||
|
|
627312e1de | ||
|
|
bfc9550e4e | ||
|
|
2b9c21268b | ||
|
|
3dce4ed6f1 | ||
|
|
0f16c2ea87 | ||
|
|
9a635f0686 | ||
|
|
6a0d4b2baa | ||
|
|
ac017098ad | ||
|
|
98fef2640d | ||
|
|
8bb66e133a | ||
|
|
68a582901d | ||
|
|
c094f4c06e | ||
|
|
f7ca545544 | ||
|
|
69b4716894 | ||
|
|
7e44dcc5bf | ||
|
|
ab9843e183 | ||
|
|
01af706ade | ||
|
|
9ebdb08e99 | ||
|
|
a74ffe25d9 | ||
|
|
7f95e27707 | ||
|
|
1facf5bba3 | ||
|
|
03d77009eb | ||
|
|
8afd6812b5 | ||
|
|
ec9ad78fcf | ||
|
|
6f4e93dc90 | ||
|
|
a38e43862d | ||
|
|
39294bb037 | ||
|
|
edc5e59b78 | ||
|
|
c00fd9fd37 | ||
|
|
b3e621dd9f | ||
|
|
6e8c49b978 | ||
|
|
398d57133d | ||
|
|
16521a6feb | ||
|
|
3ca0b37a3e | ||
|
|
cf2ec1229d | ||
|
|
fe9b1e5f9b | ||
|
|
f5b96ddf01 | ||
|
|
2fe076fb27 | ||
|
|
99249cff04 | ||
|
|
0cdf7b0613 | ||
|
|
90bcf4f157 | ||
|
|
03c3ec4e12 | ||
|
|
ca9bb20d64 | ||
|
|
c6bc078fd9 | ||
|
|
2f4bd6e52c | ||
|
|
2affe53727 | ||
|
|
09654d7dd8 | ||
|
|
90a4e37815 | ||
|
|
60889c0c79 | ||
|
|
20f3408d96 | ||
|
|
e9d86789db | ||
|
|
5152b7c66c | ||
|
|
c494c4e12c | ||
|
|
54d58ccb7e | ||
|
|
714a77bfbe | ||
|
|
d48f8bf5cc | ||
|
|
99d97754a6 | ||
|
|
b9d437de2a | ||
|
|
11403f2019 | ||
|
|
1ca102d639 | ||
|
|
339ba55111 | ||
|
|
14ae59885a | ||
|
|
e3ef54f99b | ||
|
|
001901f9a9 | ||
|
|
6a98f60e2e | ||
|
|
6f2e24c47d | ||
|
|
aafa368923 | ||
|
|
eb783cab4c | ||
|
|
6533aa865a | ||
|
|
f1a1e1bc07 | ||
|
|
953f4838dd | ||
|
|
130b892d34 | ||
|
|
6ad525c77e | ||
|
|
d0ca74ad27 | ||
|
|
9806f69b4d | ||
|
|
34d9b5e3d7 | ||
|
|
3bf5189d86 | ||
|
|
12e5b0681b | ||
|
|
8c0285d608 | ||
|
|
36558fa3b8 | ||
|
|
235f940cde | ||
|
|
803d61fcbc | ||
|
|
ffbd7d8de4 | ||
|
|
4ed924d7c7 | ||
|
|
798dc9948b | ||
|
|
13515f7ee4 | ||
|
|
ef80824c26 | ||
|
|
c8503fd65e | ||
|
|
b3c454fb1c | ||
|
|
1d7723e873 | ||
|
|
77100b2365 | ||
|
|
259a788134 | ||
|
|
39511455cb | ||
|
|
b04c16178e | ||
|
|
49a959c06e | ||
|
|
096a8932b4 | ||
|
|
e39e66df93 | ||
|
|
513633f49a | ||
|
|
eb3740daaf | ||
|
|
f7947b148a | ||
|
|
9a2a702f3f | ||
|
|
c65d95bf29 | ||
|
|
753a5edc4f | ||
|
|
0b3f853c2d | ||
|
|
3527fcf1d5 | ||
|
|
4544a89c7a | ||
|
|
ffeae9005e | ||
|
|
47217bcfb7 | ||
|
|
80ff58b57a | ||
|
|
d15dd368f1 | ||
|
|
8a2ec32bd8 | ||
|
|
410496ed52 | ||
|
|
b7b07552e5 | ||
|
|
44486e80d9 | ||
|
|
7890c527d8 | ||
|
|
2c82ab79a7 | ||
|
|
e3ebe5fc53 | ||
|
|
0ac430892e | ||
|
|
a7739c942c | ||
|
|
24581482d0 | ||
|
|
0571c3b453 | ||
|
|
73e7f5a0b0 | ||
|
|
20c0adb961 | ||
|
|
a01e03562f | ||
|
|
d184ed0130 | ||
|
|
089e1c2aee | ||
|
|
ebab0e91ee | ||
|
|
858a2b1b88 | ||
|
|
02bd59827c | ||
|
|
4991428510 | ||
|
|
3b245f5dc1 | ||
|
|
c9c81da901 | ||
|
|
4919cdc3fb | ||
|
|
e90e1f577d | ||
|
|
afd4284403 | ||
|
|
150b350d31 | ||
|
|
2818520bd1 | ||
|
|
2819952292 | ||
|
|
5af71af51c | ||
|
|
07a55b51df | ||
|
|
66dd68b49d | ||
|
|
9812657777 | ||
|
|
0b09312fc6 | ||
|
|
d0a7ac6b74 | ||
|
|
ff9a238fbd | ||
|
|
359fffa5f1 | ||
|
|
5bf92ced1a | ||
|
|
340bcc7b45 | ||
|
|
ef03742bd4 | ||
|
|
20431ec16d | ||
|
|
becba8157b | ||
|
|
51fd3bb0eb | ||
|
|
4bbd3acb4e | ||
|
|
3bc930ea7b | ||
|
|
d1b26f8e86 | ||
|
|
fdf15caaff | ||
|
|
c7b4a53c0b | ||
|
|
af78dc0308 | ||
|
|
5ad39493c4 | ||
|
|
61f597b408 | ||
|
|
2162825240 | ||
|
|
2b780e70d1 | ||
|
|
a3823f818e | ||
|
|
1f7c47bcaf | ||
|
|
ec53c365a2 | ||
|
|
793ad1f2d4 | ||
|
|
9bc733b76c | ||
|
|
21b28f0217 | ||
|
|
d3e23caa52 | ||
|
|
9e7518de67 | ||
|
|
679f0047aa | ||
|
|
d77d5ce14b | ||
|
|
33ec22a2af | ||
|
|
353053225f | ||
|
|
b7f3d6f7f7 | ||
|
|
e34577499d | ||
|
|
4cf8960c0c | ||
|
|
1f93ea0675 | ||
|
|
25b705c3a8 | ||
|
|
0725588731 | ||
|
|
fc5c61cc8b | ||
|
|
ac282e63c6 | ||
|
|
c3941941ce | ||
|
|
46cdd53323 | ||
|
|
3ff3e302c3 | ||
|
|
f2ceecf95c | ||
|
|
9314c7c881 | ||
|
|
54abb2c572 | ||
|
|
8fa3bdd025 | ||
|
|
5e7a308528 | ||
|
|
7952177786 | ||
|
|
9afbe49c84 | ||
|
|
9f06ba2db3 | ||
|
|
fe55bfddcf | ||
|
|
c0842e6444 | ||
|
|
3fed20d06a | ||
|
|
5e8f2e2c04 | ||
|
|
e4df99ea84 | ||
|
|
b3276f5f11 | ||
|
|
32667ca256 | ||
|
|
bed122a170 | ||
|
|
14adc9b875 | ||
|
|
a8778bbc5a | ||
|
|
a54e641f44 | ||
|
|
5c99efe87a | ||
|
|
7da1d731ff | ||
|
|
af9828e819 | ||
|
|
7a27136142 | ||
|
|
012ad2d423 | ||
|
|
ef3bdbf4da | ||
|
|
b3bb698f7b | ||
|
|
1ed5d1e4c1 | ||
|
|
bdee01a03d | ||
|
|
458f7376d7 | ||
|
|
cb3a00e027 | ||
|
|
482eb1f3fb | ||
|
|
6e0f638f5e | ||
|
|
bab349047d | ||
|
|
28ea6b8de8 | ||
|
|
9d51bbdae8 | ||
|
|
d622f79533 | ||
|
|
04c8515ad1 | ||
|
|
53bc4251d1 | ||
|
|
a5a751f02f | ||
|
|
66ed5f82c4 | ||
|
|
c802a9e6aa | ||
|
|
880f210946 | ||
|
|
4f9f7eb6a6 | ||
|
|
f910c4a8e7 | ||
|
|
529686d965 | ||
|
|
84dfd1536f | ||
|
|
85dedc324c | ||
|
|
d639237411 | ||
|
|
449aaf75f1 | ||
|
|
b1fda66caa | ||
|
|
66a8e90fd9 | ||
|
|
37b487d191 | ||
|
|
6c59fe3577 | ||
|
|
1cbb70c992 | ||
|
|
e06b39f882 | ||
|
|
2602b1493e | ||
|
|
989d14502d | ||
|
|
f78a550282 | ||
|
|
54a1abb284 | ||
|
|
97b492a8e2 | ||
|
|
0873bd14a9 | ||
|
|
eff6ba429a | ||
|
|
8c18064be4 | ||
|
|
44a1ac0cf3 | ||
|
|
28dc8d88dd | ||
|
|
2c0c2b64ba | ||
|
|
bd3e0f5248 | ||
|
|
cd52d98938 | ||
|
|
894c70e7f8 | ||
|
|
51d70c2edd | ||
|
|
7d4b355240 | ||
|
|
3b56193b98 | ||
|
|
b16045b57d | ||
|
|
9e8b0fca5b | ||
|
|
35cf1b3b5b | ||
|
|
83f788af57 | ||
|
|
2ffe378d3f | ||
|
|
38b33a4a5e | ||
|
|
60bf9ed0a0 | ||
|
|
16adf4de1b | ||
|
|
80de983023 | ||
|
|
8703ca623f | ||
|
|
286253a73f | ||
|
|
bd806a41df | ||
|
|
b89c4e9002 | ||
|
|
6dbf31c0c3 | ||
|
|
060c45d8a1 | ||
|
|
33d3e82e4d | ||
|
|
4bb074514d | ||
|
|
e3f8892003 | ||
|
|
9d00ad5f18 | ||
|
|
dae4344850 | ||
|
|
aa7f3fabe2 | ||
|
|
f93434a8ce | ||
|
|
25dee56be9 | ||
|
|
ce9a3f3797 | ||
|
|
11e384920a | ||
|
|
a0a1f1e536 | ||
|
|
3b3d0ea9eb | ||
|
|
2f4d78286d | ||
|
|
677dc6f985 | ||
|
|
d52057e732 | ||
|
|
fa2a1cb1fb | ||
|
|
19a0fb04ad | ||
|
|
947352f2fe | ||
|
|
adcbedb686 | ||
|
|
7732f92acd | ||
|
|
ad8a001688 | ||
|
|
9121eada08 | ||
|
|
49bd4d25a2 | ||
|
|
d80b4129c6 | ||
|
|
7edb4172d5 | ||
|
|
c3a4677990 | ||
|
|
5cbb893a3b | ||
|
|
f28a2a432b | ||
|
|
03b75a2d27 | ||
|
|
859fe69083 | ||
|
|
f6f2205ddb | ||
|
|
0f9a03ef61 | ||
|
|
9aa417c084 | ||
|
|
7b70952f5d | ||
|
|
edd3d07b49 | ||
|
|
5293d0a4ec | ||
|
|
3c8c7beae1 | ||
|
|
9c3ba9fdcd | ||
|
|
fb1748fb0f | ||
|
|
0a109fbd03 | ||
|
|
5cf64db74e | ||
|
|
488cc94f36 | ||
|
|
e15846bf79 | ||
|
|
752bd00674 | ||
|
|
7fadfcbe32 | ||
|
|
41141e75bb | ||
|
|
50f641e627 | ||
|
|
c7883fd093 | ||
|
|
4fcb24b2b1 | ||
|
|
5003557935 | ||
|
|
bdf1ba84da | ||
|
|
b0b4def983 | ||
|
|
cc184bbe9e | ||
|
|
ad30c830aa | ||
|
|
1d791a8af4 | ||
|
|
e63c51cd97 | ||
|
|
f202e32908 | ||
|
|
26e1a08e82 | ||
|
|
4d5119d435 | ||
|
|
75e34ea62e | ||
|
|
0a183d6274 | ||
|
|
21d8060aea | ||
|
|
9cbe906f60 | ||
|
|
8ce4137399 | ||
|
|
5f8a139347 | ||
|
|
9bb009a3fe | ||
|
|
726d65923f | ||
|
|
8a6be4cb2d | ||
|
|
10b06beb8e | ||
|
|
81318c7968 | ||
|
|
47a2c1c6e5 | ||
|
|
39cee65c6b | ||
|
|
8582ec724e | ||
|
|
b0139682e8 | ||
|
|
d39c475a6d | ||
|
|
48f38354c6 | ||
|
|
cd5a920ed5 | ||
|
|
71bc1f378d | ||
|
|
0ee6c31cff | ||
|
|
af89a9971e | ||
|
|
c718a8ef72 | ||
|
|
8c8ad0faf0 | ||
|
|
314d5bbb7f | ||
|
|
102255757a | ||
|
|
914067a0d0 | ||
|
|
06e3ae2536 | ||
|
|
7f9b252556 | ||
|
|
3d700e243f | ||
|
|
bcfc78ce11 | ||
|
|
09241765d5 | ||
|
|
671c83c265 | ||
|
|
772d28b766 | ||
|
|
c26fcea58d | ||
|
|
1e5e26dbff | ||
|
|
742fc54864 | ||
|
|
49738f43c0 | ||
|
|
9f85f61010 | ||
|
|
239f422039 | ||
|
|
67af3c37be | ||
|
|
a9442385c4 | ||
|
|
8c9cd10b8b | ||
|
|
72542059dd | ||
|
|
a843fc6d40 | ||
|
|
4beed60c08 | ||
|
|
4049c1e480 | ||
|
|
8449314da2 | ||
|
|
63ad057028 | ||
|
|
e720464330 | ||
|
|
24036afef9 | ||
|
|
c78fa1a1bc | ||
|
|
faa8b9022c | ||
|
|
729bafef7a | ||
|
|
590b028632 | ||
|
|
8150d00f36 | ||
|
|
060065926f | ||
|
|
70babe8a28 | ||
|
|
c36e09664f | ||
|
|
a9672246f3 | ||
|
|
ff571884e9 | ||
|
|
475138bceb | ||
|
|
4a8af199c2 | ||
|
|
bdabf5db72 | ||
|
|
6a5f21b34e | ||
|
|
d608be103c | ||
|
|
374bb5d18a | ||
|
|
031d6c25ff | ||
|
|
223fb7b075 | ||
|
|
a746741971 | ||
|
|
120faf2a58 | ||
|
|
990bca0dc6 | ||
|
|
3406472db7 | ||
|
|
1bd733c9f6 | ||
|
|
238c7f982e | ||
|
|
fcb81147cb | ||
|
|
1915b73783 | ||
|
|
ee79e621fb | ||
|
|
d203275a3b | ||
|
|
9e8a996222 | ||
|
|
0126b0b3ed | ||
|
|
458928612c | ||
|
|
e33f88e28d | ||
|
|
be570bbf9e | ||
|
|
f59b4be110 | ||
|
|
37336e41be | ||
|
|
d24a1a3f0a | ||
|
|
f7258955bd | ||
|
|
2a1eae5d6f | ||
|
|
50ee0a4adb | ||
|
|
955a26584e | ||
|
|
1d3e407c8f | ||
|
|
cb809c4596 | ||
|
|
53bbe2888e | ||
|
|
7246f476a5 | ||
|
|
0785d1c390 | ||
|
|
85d2c49d14 | ||
|
|
8b77d62b7f | ||
|
|
373058a32a | ||
|
|
e6293c2c8c | ||
|
|
eff181c959 | ||
|
|
54752c2305 | ||
|
|
b4753c044f | ||
|
|
26493424ae | ||
|
|
0282fd1332 | ||
|
|
b9a019a08b | ||
|
|
66f6a0e687 | ||
|
|
2dd1b9f97d | ||
|
|
89615f3045 | ||
|
|
7e46192f67 | ||
|
|
e78d985cdf | ||
|
|
e8c4bf56fe | ||
|
|
e6aa7d323d | ||
|
|
fca8e25929 | ||
|
|
8e8ac286b4 | ||
|
|
7d9770b9a2 | ||
|
|
1996230460 | ||
|
|
de7897a864 | ||
|
|
e2884dcdb7 | ||
|
|
544a53a42b | ||
|
|
2e4787bfc8 | ||
|
|
1829eeb171 | ||
|
|
c7488e3c4a | ||
|
|
3bf9606383 | ||
|
|
4f43f18f0a | ||
|
|
5b7f197397 | ||
|
|
018141c97f | ||
|
|
4d7813e57c | ||
|
|
605c60208f | ||
|
|
884fafcc30 | ||
|
|
56baa90320 | ||
|
|
6bb20ee09e | ||
|
|
541356430c | ||
|
|
2f4d91fd69 | ||
|
|
f58c5e6b30 | ||
|
|
0311d0132c | ||
|
|
c946c97402 | ||
|
|
84a6f51318 | ||
|
|
24a1501b0d | ||
|
|
383b6f5fcc | ||
|
|
633dd7ff9b | ||
|
|
580624fad6 | ||
|
|
a8190f7efa | ||
|
|
dd2157534b | ||
|
|
38a90e7669 | ||
|
|
6bfc526dcd | ||
|
|
aadb8a7405 | ||
|
|
27082bf77e | ||
|
|
a2903c80cd | ||
|
|
9a77c5369c | ||
|
|
3c30741a19 | ||
|
|
7028ad4ec0 | ||
|
|
8de750c6aa | ||
|
|
04f98de9ee | ||
|
|
a1a019784b | ||
|
|
4aeeae77bd | ||
|
|
651cfc2b78 | ||
|
|
2ef8af25e2 | ||
|
|
0b13852a5b | ||
|
|
13427578c9 | ||
|
|
d89ca2087e | ||
|
|
8b0ea9fba6 | ||
|
|
9f0b653d5a | ||
|
|
659a339233 | ||
|
|
4c29f177a0 | ||
|
|
d664e63d55 | ||
|
|
2493509dbe | ||
|
|
1c8b27f554 | ||
|
|
68297b7186 | ||
|
|
34dd8d0a91 | ||
|
|
81c44790d5 | ||
|
|
d557b335cf | ||
|
|
e2adc28cff | ||
|
|
0fef6a6ecc | ||
|
|
f2fd4b8a1f | ||
|
|
95bd5605a8 | ||
|
|
497cca7eca | ||
|
|
54f78feedd | ||
|
|
76408e53ae | ||
|
|
be19e74d30 | ||
|
|
dac578a775 | ||
|
|
04732ce74b | ||
|
|
a6c95a2374 | ||
|
|
f68622abe9 | ||
|
|
83a9a7bdb2 | ||
|
|
6500afc0ca | ||
|
|
c69b7ecc96 | ||
|
|
615ef1e2d2 | ||
|
|
cf69a0cd7f | ||
|
|
06e892fb33 | ||
|
|
e6c5dd6865 | ||
|
|
247efdebdb | ||
|
|
76f3792287 | ||
|
|
64d8e2c727 | ||
|
|
ead0bd9cb0 | ||
|
|
66fc13b2ec | ||
|
|
f3af4128b0 | ||
|
|
0e43107c87 | ||
|
|
1ee3e7997e | ||
|
|
50fd61d91f | ||
|
|
e4cdc051a9 | ||
|
|
778e846e96 | ||
|
|
a27759b647 | ||
|
|
b75eceab41 | ||
|
|
e748a5d5f4 | ||
|
|
99c5a3ae46 | ||
|
|
51da710f5a | ||
|
|
569d69b3d2 | ||
|
|
059a6b1d90 | ||
|
|
990af7548a | ||
|
|
a38aefdfc8 | ||
|
|
3bcb12e7d1 | ||
|
|
7904ecb462 | ||
|
|
9ba4d45109 | ||
|
|
56b8afe19d | ||
|
|
f7aed9a94c | ||
|
|
e12a7e881d | ||
|
|
5afb65325d | ||
|
|
135f520f32 | ||
|
|
bc251f4ff6 | ||
|
|
b8769751f6 | ||
|
|
eff96d839e | ||
|
|
aa34c23807 | ||
|
|
195acdac8c | ||
|
|
903e03c56c | ||
|
|
0892767b8a | ||
|
|
83ebfa772c | ||
|
|
1583641322 | ||
|
|
9510e2c256 | ||
|
|
a9dbabe07e | ||
|
|
12884008fa | ||
|
|
02543bad1c | ||
|
|
a8c56a5251 | ||
|
|
4e5a855f3f | ||
|
|
7e497a951e | ||
|
|
cd08eabbfa | ||
|
|
f7e62d9f81 | ||
|
|
9a3761e86e | ||
|
|
3619a68693 | ||
|
|
efaf3c3bf9 | ||
|
|
0e4e6a6f67 | ||
|
|
42458e6278 | ||
|
|
41ec995377 | ||
|
|
4f37599326 | ||
|
|
4144520e5c | ||
|
|
6c4800546c | ||
|
|
733733c8a7 | ||
|
|
2aa67cc946 | ||
|
|
9385981a9d | ||
|
|
fff780035d | ||
|
|
46127e673d | ||
|
|
70df59b224 | ||
|
|
0fdbaa803f | ||
|
|
6af1830eff | ||
|
|
6f860e2bd5 | ||
|
|
20a492f7ee | ||
|
|
63875e7591 | ||
|
|
0ad98cabde | ||
|
|
668879d2e1 | ||
|
|
2e09783302 | ||
|
|
49734114b3 | ||
|
|
950d9d6ee7 | ||
|
|
f7974aee2e | ||
|
|
c870a82621 | ||
|
|
984929a001 | ||
|
|
7f9e2c1db8 | ||
|
|
324e8389dc | ||
|
|
6f448c5a38 | ||
|
|
ec43efbb20 | ||
|
|
3ed065de37 | ||
|
|
8152f0d72c | ||
|
|
f8047f4736 | ||
|
|
b93c66dc2d | ||
|
|
ac877b3065 | ||
|
|
dee8abfdde | ||
|
|
cef3841d73 | ||
|
|
3cd5e8a041 | ||
|
|
515b5f866e | ||
|
|
321f62bf92 | ||
|
|
f94fa47b52 | ||
|
|
c502f8a722 | ||
|
|
59b4868ac3 | ||
|
|
3634e12cce | ||
|
|
6d45445391 | ||
|
|
4f47e268cc | ||
|
|
0035b31cdb | ||
|
|
f2565aee03 | ||
|
|
5bd85668dd | ||
|
|
20f990b6ce | ||
|
|
6821379586 | ||
|
|
73b040eb49 | ||
|
|
49aa4b2e1e | ||
|
|
972241c74c | ||
|
|
680750e3c2 | ||
|
|
5e7d4d9d15 | ||
|
|
1e57e60613 | ||
|
|
3ac7ce605a | ||
|
|
b720dea9f0 | ||
|
|
c80722aefe | ||
|
|
a84fa69f28 | ||
|
|
e33781e59f | ||
|
|
8824bc7ece | ||
|
|
c2e3b0e448 | ||
|
|
f61a38e85a | ||
|
|
d23e948216 | ||
|
|
58bdaa31f0 | ||
|
|
b6491d88a6 | ||
|
|
f6061ba62e | ||
|
|
427899ddce | ||
|
|
c4ab7d2dbd | ||
|
|
0fd2ba033f | ||
|
|
ed38939a93 | ||
|
|
c7ee26ce5a | ||
|
|
909b8cb303 | ||
|
|
b0277370cf | ||
|
|
2ec8656bea | ||
|
|
b2ef256910 | ||
|
|
63d6ce95db | ||
|
|
a9532b189c | ||
|
|
844545411f | ||
|
|
4e23a2b9b8 | ||
|
|
5deba027eb | ||
|
|
fc8b7efc6f | ||
|
|
a1c2d9c0f3 | ||
|
|
4ca49a0501 | ||
|
|
493c53d090 | ||
|
|
b27e956d35 | ||
|
|
35ebed75c6 | ||
|
|
7bfdb5f77f | ||
|
|
8d8c02317f | ||
|
|
a34482feab | ||
|
|
cbdc8fd4a6 | ||
|
|
8d3afaa53c | ||
|
|
7ced9ef3df | ||
|
|
e8a9ae7e80 | ||
|
|
73a88ab3d3 | ||
|
|
aaed82738a | ||
|
|
de7f7b96db | ||
|
|
1a669b3e68 | ||
|
|
333af9b13a | ||
|
|
a5bca5e240 | ||
|
|
c885633e02 | ||
|
|
ca7e20b7ca | ||
|
|
545e11a3d7 | ||
|
|
44f5287664 | ||
|
|
cf510897f1 | ||
|
|
1d171345f8 | ||
|
|
4fa7e1cd49 | ||
|
|
acd008298e | ||
|
|
83a8021515 | ||
|
|
cf88dfb1db | ||
|
|
8937c4b481 | ||
|
|
cc6af10a4d | ||
|
|
6d94578955 | ||
|
|
08442ab71e | ||
|
|
10d91d213f | ||
|
|
b7a3b06994 | ||
|
|
5f12c37f23 | ||
|
|
585edebccd | ||
|
|
9921c62234 | ||
|
|
1ac76d2e16 | ||
|
|
6e983bf400 | ||
|
|
6a8fd4fa6e | ||
|
|
3698eaa2d2 | ||
|
|
8d97ca433c | ||
|
|
23cc65e537 | ||
|
|
2f5a3c2bbe | ||
|
|
f6485616cd | ||
|
|
6544fb43d9 | ||
|
|
a954b32dcc | ||
|
|
426dc7836c | ||
|
|
ff941ffc16 | ||
|
|
a063c201df | ||
|
|
e2be3fa0aa | ||
|
|
609da6fb50 | ||
|
|
fc9f3ccec3 | ||
|
|
f7baa67a0a | ||
|
|
e8d78c2cdb | ||
|
|
9d33366092 | ||
|
|
f5d61515c2 | ||
|
|
711a04a972 | ||
|
|
e5b470a3f1 | ||
|
|
31820e1e22 | ||
|
|
4849e8cd6d | ||
|
|
77e3b460aa | ||
|
|
b5321001f8 | ||
|
|
38eba9f5ea | ||
|
|
ea6f399454 | ||
|
|
f8bf2d7b7d | ||
|
|
c4856caebb | ||
|
|
fc1030bb22 | ||
|
|
9eb6cad8dc | ||
|
|
0fa2a78dce | ||
|
|
a56fa1558b | ||
|
|
261c73a997 | ||
|
|
929c1333ca | ||
|
|
286a79d94d | ||
|
|
8b951f99da | ||
|
|
abb449bca0 | ||
|
|
bd084028d1 | ||
|
|
138a27570b | ||
|
|
c2ed40a74f | ||
|
|
a7e7a00cab | ||
|
|
64a31ab3cd | ||
|
|
71958bc0f1 | ||
|
|
366ec35612 | ||
|
|
3738f6e8ae | ||
|
|
051a8e2af1 | ||
|
|
2f43f28d5e | ||
|
|
b64769754b | ||
|
|
a97daa18d1 | ||
|
|
b6556dce8b | ||
|
|
aa8d8bc8b5 | ||
|
|
0800dcfdc4 | ||
|
|
12b0101e94 | ||
|
|
021b391a02 | ||
|
|
d11e2b6057 | ||
|
|
264d90e7e5 | ||
|
|
f9f3da9e78 | ||
|
|
6435b49153 | ||
|
|
f9aa2941cf | ||
|
|
5a933d4bee | ||
|
|
5536aea0df | ||
|
|
976666d216 | ||
|
|
9a5bcd4392 | ||
|
|
812060a118 | ||
|
|
089b5052e6 | ||
|
|
874e5d72f4 | ||
|
|
6b11de1329 | ||
|
|
2245a7ad8d | ||
|
|
ee5ec1b870 | ||
|
|
74ccfe851b | ||
|
|
e1c24bd5a2 | ||
|
|
1349b79728 | ||
|
|
d294d7604c | ||
|
|
01df2cf464 | ||
|
|
45b7322488 | ||
|
|
b3055e992f | ||
|
|
3da548565c | ||
|
|
a975e85548 | ||
|
|
c4b5ade752 | ||
|
|
a4b61b0794 | ||
|
|
f6011184b8 | ||
|
|
74de118c6e | ||
|
|
9c25e77c17 | ||
|
|
440113e67e | ||
|
|
a11b60c445 | ||
|
|
a6052681ad | ||
|
|
482d50536a | ||
|
|
25c79a4fcd | ||
|
|
02946144ac | ||
|
|
71a360e9a3 | ||
|
|
f7912d88b1 | ||
|
|
975101d7d2 | ||
|
|
ef58c5ff55 | ||
|
|
e10221804a | ||
|
|
284ed9ee0e | ||
|
|
5d7b961997 | ||
|
|
c699a5c4b4 | ||
|
|
1f4ceb89cf | ||
|
|
0934ca0040 | ||
|
|
4738f892c2 | ||
|
|
33004fcf33 | ||
|
|
34d214c166 | ||
|
|
a56cd92a1e | ||
|
|
7251348507 | ||
|
|
01cd5c84d6 | ||
|
|
e210599fa6 | ||
|
|
dbe7cee7e9 | ||
|
|
7370d88ceb | ||
|
|
34458e0c57 | ||
|
|
05c8c3abf2 | ||
|
|
e9d464b4d3 | ||
|
|
6968c3ab9b | ||
|
|
131a8a9650 | ||
|
|
379ecbf9a9 | ||
|
|
7b9dfa9a28 | ||
|
|
fbd0f5eed2 | ||
|
|
5970f904ae | ||
|
|
8cbcb2868d | ||
|
|
8ff2a4b026 | ||
|
|
ae14d205a5 | ||
|
|
ec5d560ec5 | ||
|
|
fb543b53c0 | ||
|
|
39c16422e2 | ||
|
|
4d5b273ebe | ||
|
|
ed6a860fad | ||
|
|
423e579292 | ||
|
|
ee11aa9e75 | ||
|
|
c46d20fa92 | ||
|
|
dc8d17574c | ||
|
|
5c17cd04c8 | ||
|
|
67ada02076 | ||
|
|
32d94c2eaf | ||
|
|
687b39a12a | ||
|
|
705af407bf | ||
|
|
080052da2e | ||
|
|
ef735fd92a | ||
|
|
17c16dcafc | ||
|
|
a89b3018fb | ||
|
|
851e2ebd32 | ||
|
|
1225ce7fe8 | ||
|
|
7e77a31b96 | ||
|
|
d146b9002f | ||
|
|
1f9d567b23 | ||
|
|
ed1b3a023c | ||
|
|
1ca18f501a | ||
|
|
49588ccd98 | ||
|
|
098dedc092 | ||
|
|
b06f6b9545 | ||
|
|
ba3cb94999 | ||
|
|
74c67fbf4b | ||
|
|
32b46e4910 | ||
|
|
ecf5539ed2 | ||
|
|
ac9db4e4d5 | ||
|
|
0eb96094b0 | ||
|
|
30b3ac7dc5 | ||
|
|
0092790c7d | ||
|
|
28909d8a51 | ||
|
|
b20cfbb7b6 | ||
|
|
97639bd0a8 | ||
|
|
161ec73c96 | ||
|
|
957d6bea15 | ||
|
|
f8b6e5b414 | ||
|
|
1ab450870e | ||
|
|
de45f4884c | ||
|
|
5da1f3e7c8 | ||
|
|
983014952b | ||
|
|
55298019a3 | ||
|
|
a1ffc3f271 | ||
|
|
2fb60aa997 | ||
|
|
f5ec76537a | ||
|
|
728491fd2b | ||
|
|
d9d3f2b9e4 | ||
|
|
3fe4864f65 | ||
|
|
0b156f22a4 | ||
|
|
35b1d93813 | ||
|
|
d770851ac0 | ||
|
|
989e7b1033 | ||
|
|
c4e0eb7b49 | ||
|
|
71f5d0dac7 | ||
|
|
561b0c4381 | ||
|
|
995fbc7330 | ||
|
|
10ab8949c4 | ||
|
|
c441202fea | ||
|
|
ca261b0bee | ||
|
|
52f3709f67 | ||
|
|
c2ca6187fe | ||
|
|
671a13d295 | ||
|
|
14c3e2eccf | ||
|
|
08e5b852c2 | ||
|
|
1c9606c824 | ||
|
|
3cd47b5c9b | ||
|
|
aedc729087 | ||
|
|
5f7cfa3fa9 | ||
|
|
0083f30af5 | ||
|
|
4a06f05ef5 | ||
|
|
8f37cadce8 | ||
|
|
a11603ca6c | ||
|
|
86274842e9 | ||
|
|
cf9c955a44 | ||
|
|
55d828c35f | ||
|
|
cdff28aca6 | ||
|
|
b9da39274f | ||
|
|
c379aa5782 | ||
|
|
9dcabac9dd | ||
|
|
794f3a2b9f | ||
|
|
2066121b7c | ||
|
|
0c4067f143 | ||
|
|
8aa69243b7 | ||
|
|
8697263bde | ||
|
|
ea25c4f65c | ||
|
|
82ac3ebd7e | ||
|
|
13cb94909c | ||
|
|
b57ca2a763 | ||
|
|
83c49e9745 | ||
|
|
e15771d78d | ||
|
|
6edc4920ba | ||
|
|
302bb1bd93 | ||
|
|
529b1bceee | ||
|
|
42cd47d32e | ||
|
|
711d884c2e | ||
|
|
183d1c4674 | ||
|
|
faed63a0bb | ||
|
|
53bff262f8 | ||
|
|
3251a708e4 | ||
|
|
b5dbdbf7b2 | ||
|
|
a9649e92c9 | ||
|
|
b561f1fa8b | ||
|
|
cecd7491b5 | ||
|
|
55a66322b5 | ||
|
|
155c31a2d7 | ||
|
|
a89ce91089 | ||
|
|
b897fe6700 | ||
|
|
548a351b06 | ||
|
|
4b1da57ca1 | ||
|
|
529aec7f25 | ||
|
|
1661e545cb | ||
|
|
ec71d08878 | ||
|
|
ac258b7dd7 | ||
|
|
0f57876233 | ||
|
|
1d25a3693d | ||
|
|
45fa428bf1 | ||
|
|
177fa80f1a | ||
|
|
3261261bfe | ||
|
|
d4de7934f8 | ||
|
|
c3475af809 | ||
|
|
b12f707812 | ||
|
|
22c0c34d60 | ||
|
|
a60b66f230 | ||
|
|
83f6e93628 | ||
|
|
222b5f0229 | ||
|
|
30aa383e26 | ||
|
|
676b401294 | ||
|
|
ebf57159de | ||
|
|
199d2aafec | ||
|
|
81952f56fd | ||
|
|
c5bac82b43 | ||
|
|
081b86109c | ||
|
|
8ac2028a75 | ||
|
|
264fed1c9f | ||
|
|
dd59f7b2c7 | ||
|
|
9245a760db | ||
|
|
b61b32bbc3 | ||
|
|
09b3914f5d | ||
|
|
fe644e4c9e | ||
|
|
7b09bf2156 | ||
|
|
987d0aae66 | ||
|
|
9cbcbc1c22 | ||
|
|
cfc4e2bc60 | ||
|
|
a03405fa81 | ||
|
|
d5c9ccbe6e | ||
|
|
e52772d65f | ||
|
|
1e3259e728 | ||
|
|
e905a20a60 | ||
|
|
88e2be7a33 | ||
|
|
8939131600 | ||
|
|
ba37ebff8b | ||
|
|
28f4cb7e07 | ||
|
|
db1e7102cd | ||
|
|
07eb7a5830 | ||
|
|
b7c6c685fa | ||
|
|
212134df70 | ||
|
|
6eeb5528f5 | ||
|
|
54fad845c9 | ||
|
|
d6c0de6fc7 | ||
|
|
649c8649f7 | ||
|
|
da2f53d1b1 | ||
|
|
405139e3b8 | ||
|
|
4f8d347171 | ||
|
|
bf0db4876c | ||
|
|
47a14884d6 | ||
|
|
3a7bbc8b08 | ||
|
|
1b1d65372c | ||
|
|
fd2faaa16e | ||
|
|
0609cdb9ea | ||
|
|
d3bb140f89 | ||
|
|
b31dc66628 | ||
|
|
09476171a6 | ||
|
|
33dee813b5 | ||
|
|
bb4e73c40b | ||
|
|
b1f23ffa94 | ||
|
|
b0e8cec1e7 | ||
|
|
5077ae19bc | ||
|
|
0d8447bf59 | ||
|
|
c6cf08a274 | ||
|
|
dc49ae519e | ||
|
|
904539476a | ||
|
|
3fbf02dc82 | ||
|
|
c9392a840d | ||
|
|
d164e8ab72 | ||
|
|
6dc62c9fb6 | ||
|
|
87a9684d66 | ||
|
|
94525e2f44 | ||
|
|
b408b1b3b9 | ||
|
|
27c2f09e32 | ||
|
|
19bc4d3349 | ||
|
|
f2b6c424d6 | ||
|
|
a49d4453e9 | ||
|
|
65e50087b9 | ||
|
|
2d90f759d9 | ||
|
|
4230ac7674 | ||
|
|
d96e9182e9 | ||
|
|
68c87b9616 | ||
|
|
7f8e9a0b6d | ||
|
|
81a229f2a5 | ||
|
|
8be7ae2733 | ||
|
|
846bca4cb1 | ||
|
|
f36f353789 | ||
|
|
939a2731ed | ||
|
|
835dab97ff | ||
|
|
fa904b53be | ||
|
|
0ec52dddce | ||
|
|
c289355a3a | ||
|
|
02a13a5a18 | ||
|
|
6cf2a0281b | ||
|
|
120d35f9af | ||
|
|
2b15d5e7b3 | ||
|
|
fc167bd3f0 | ||
|
|
91b04abf05 | ||
|
|
77faac8740 | ||
|
|
43b3d54855 | ||
|
|
69e9b85700 | ||
|
|
0b6d132759 | ||
|
|
7c233c6c0c | ||
|
|
c35b290fa4 | ||
|
|
3d95cfb367 | ||
|
|
b90fc3a56e | ||
|
|
1ef3fdccf5 | ||
|
|
02b7f77bd8 | ||
|
|
0ac7ead922 | ||
|
|
da9d0e03ce | ||
|
|
120f65f672 | ||
|
|
200a14caa4 | ||
|
|
35bf6da8e2 | ||
|
|
f08f70276c | ||
|
|
1ae50fd95b | ||
|
|
40512beb47 | ||
|
|
0d7f9b2c94 | ||
|
|
52f42140a7 | ||
|
|
3f6c50297f | ||
|
|
f72d80afc5 | ||
|
|
7c5cb13b22 | ||
|
|
d728750eb2 | ||
|
|
02a70e5667 | ||
|
|
44e51ea5fa | ||
|
|
87e201460a | ||
|
|
039bd945e2 | ||
|
|
e9e52d2b4b | ||
|
|
2bf92e7399 | ||
|
|
5b0df241f0 | ||
|
|
76f5b05eff | ||
|
|
40fb6c998f | ||
|
|
33f50a342d | ||
|
|
81523ab68a | ||
|
|
2bf8cc62cf | ||
|
|
1ae8247af3 | ||
|
|
5ef32227ec | ||
|
|
6456e773bd | ||
|
|
234fe53ca3 | ||
|
|
7c93e7a7b3 | ||
|
|
8afc6c7f4b | ||
|
|
4609d0fa3a | ||
|
|
d452c035c6 | ||
|
|
45113c8f5a | ||
|
|
0acdd3c62b | ||
|
|
96d7d0a33e | ||
|
|
b6b280267b | ||
|
|
6e6d253b1a | ||
|
|
d92c105db2 | ||
|
|
906db728d6 | ||
|
|
c4b7411565 | ||
|
|
de06396046 | ||
|
|
ee6bfeb8e3 | ||
|
|
058347321f | ||
|
|
feefe49324 | ||
|
|
187381a9a2 | ||
|
|
993dfa4368 | ||
|
|
7e35a16440 | ||
|
|
e4eeb15926 | ||
|
|
634e0db26d | ||
|
|
56855c23e1 | ||
|
|
0b00f742e3 | ||
|
|
b7ab3f673c | ||
|
|
be04ea1e35 | ||
|
|
1f8e695802 | ||
|
|
2d82b2c64f | ||
|
|
d076caf473 | ||
|
|
c7abdefa31 | ||
|
|
ba772c0bca | ||
|
|
5bad234119 | ||
|
|
c7e7baaf23 | ||
|
|
36658a671b | ||
|
|
045f2e10ba | ||
|
|
fb5a7db66d | ||
|
|
ba7d33982e | ||
|
|
c62279a755 | ||
|
|
17fa1a7ffb | ||
|
|
e89ceac351 | ||
|
|
0b8c30c109 | ||
|
|
9ab0f463cc | ||
|
|
6433dda7b8 | ||
|
|
fa7a2f4be4 | ||
|
|
ba90e16505 | ||
|
|
008f710203 | ||
|
|
df2740f126 | ||
|
|
2db89d143e | ||
|
|
0525d49da3 | ||
|
|
e2b0745882 | ||
|
|
92e804fc50 | ||
|
|
67abf45576 | ||
|
|
d2c9c814e7 | ||
|
|
22f8881a64 | ||
|
|
4ab20322fe | ||
|
|
5370eeecea | ||
|
|
ba71cb5dd7 | ||
|
|
9aad6c2c52 | ||
|
|
4d9627f20c | ||
|
|
c142492e91 | ||
|
|
6bf8d9e207 | ||
|
|
4f9a6168c1 | ||
|
|
38397f99aa | ||
|
|
f8686d0e75 | ||
|
|
549e3c8f9d | ||
|
|
bb56225b95 | ||
|
|
f00be261ba | ||
|
|
9cd94f26d0 | ||
|
|
4d8f5c80a7 | ||
|
|
24a23acc3d | ||
|
|
ca8703cfd8 | ||
|
|
6dcbb5b2f8 | ||
|
|
a84fdddb2a | ||
|
|
38bb2f8ceb | ||
|
|
23f5ef4345 | ||
|
|
ef8a2a9054 | ||
|
|
96103d0e36 | ||
|
|
ff5f6748df | ||
|
|
1c1fd6c366 | ||
|
|
32d37d00cb | ||
|
|
82f6cda966 | ||
|
|
f1ff8ff0d0 | ||
|
|
756c72902f | ||
|
|
73f8f0bbd0 | ||
|
|
18ed528f5d | ||
|
|
8fd2f136bc | ||
|
|
0524b1bf67 | ||
|
|
15716f65ce | ||
|
|
d46bdba332 | ||
|
|
760728110a | ||
|
|
12d0a194ca | ||
|
|
4104543508 | ||
|
|
5c211db015 | ||
|
|
2dc6180f8d | ||
|
|
e222a34b69 | ||
|
|
ef17d95063 | ||
|
|
853502e5d7 | ||
|
|
c18e297e77 | ||
|
|
c5a49599ba | ||
|
|
df9da9edf5 | ||
|
|
e2200fd050 | ||
|
|
c6207f5d9c | ||
|
|
4302b7ff6b | ||
|
|
50a7923438 | ||
|
|
ab416445c8 | ||
|
|
a54698d43c | ||
|
|
c5a77cc1c0 | ||
|
|
a9ffa811fc | ||
|
|
080a2608e0 | ||
|
|
57f2e83d6a | ||
|
|
5b030139d3 | ||
|
|
0da1ff42d1 | ||
|
|
2c599b7baa | ||
|
|
5c8af8d21a | ||
|
|
026f3cfde2 | ||
|
|
f6349180e8 | ||
|
|
aa6421921c | ||
|
|
7d41d2dab2 | ||
|
|
f0b4d18f93 | ||
|
|
6750f06e10 | ||
|
|
b2bd38fa9e | ||
|
|
3482a01e22 | ||
|
|
6335467552 | ||
|
|
4a39e65b62 | ||
|
|
c50a23e918 | ||
|
|
1e76b72b98 | ||
|
|
b94cf39eef | ||
|
|
fef254ffff | ||
|
|
e5495863a2 | ||
|
|
3b4df2abf0 | ||
|
|
aef2aee6a4 | ||
|
|
d0d9519149 | ||
|
|
685df1d2c5 | ||
|
|
08e6b6f2e7 | ||
|
|
66c887d0f3 | ||
|
|
22e9960697 | ||
|
|
64aa6e1f2d | ||
|
|
7a93ed9d04 | ||
|
|
a905e922e9 | ||
|
|
f9f08fc720 | ||
|
|
8d402d76d0 | ||
|
|
46fda6281c | ||
|
|
a14dbe1ea6 | ||
|
|
18810a4c16 | ||
|
|
147bc80dba | ||
|
|
c7a484195a | ||
|
|
4968eb6503 | ||
|
|
a6f2d698a9 | ||
|
|
ea5ed93ea5 | ||
|
|
e1140134c6 | ||
|
|
5ed11e012e | ||
|
|
5380bd39ca | ||
|
|
2ee2685688 | ||
|
|
782002245b | ||
|
|
7fc0905843 | ||
|
|
72ecb99e54 | ||
|
|
c863507d08 | ||
|
|
cff86c9093 | ||
|
|
0479dfcc54 | ||
|
|
68dd67f21c | ||
|
|
540f6858b5 | ||
|
|
b61e791a4f | ||
|
|
d0986f9482 | ||
|
|
112cb0dc28 | ||
|
|
0d3d7fdcf2 | ||
|
|
5d6b89ef3b | ||
|
|
ed0b26c09e | ||
|
|
ae292bd920 | ||
|
|
6c85a90723 | ||
|
|
852592066c | ||
|
|
96e1bc9b44 | ||
|
|
b41d81ed31 | ||
|
|
e241ec2244 | ||
|
|
16e1f1a94c | ||
|
|
7a68c42b26 | ||
|
|
37ccc2e118 | ||
|
|
4192fe1ab2 | ||
|
|
d5c743d7bb | ||
|
|
11814d63e8 | ||
|
|
b753656d50 | ||
|
|
f7e87611fc | ||
|
|
1fb0e1900e | ||
|
|
954a9731e0 | ||
|
|
65c3364ad8 | ||
|
|
3d72b7dccc | ||
|
|
13ee569f06 | ||
|
|
d79ef23a75 | ||
|
|
5d0797d4ba | ||
|
|
47a8d7475f | ||
|
|
4939053121 | ||
|
|
b525bf554e | ||
|
|
f00285d2b2 | ||
|
|
040f8d6eda | ||
|
|
66d905325c | ||
|
|
8b0cd95e73 | ||
|
|
d867cca6d9 | ||
|
|
a28f736369 | ||
|
|
5c3a71cc59 | ||
|
|
cef6dadb08 | ||
|
|
36be817a3e | ||
|
|
02f571f081 | ||
|
|
157159e487 | ||
|
|
02ada9f800 | ||
|
|
6fcf9a97bb | ||
|
|
17a5d8799f | ||
|
|
31f3fe7a22 | ||
|
|
89e46d3d83 | ||
|
|
885795e67d | ||
|
|
92bfb53dd4 | ||
|
|
4cecbeb115 | ||
|
|
5971480f55 | ||
|
|
05bebea511 | ||
|
|
76fa6c5cfb | ||
|
|
633b68b518 | ||
|
|
6913d8e995 | ||
|
|
f3654e6f8d | ||
|
|
d685dbcf22 | ||
|
|
6a57fa079e | ||
|
|
0a91d145ba | ||
|
|
c2866e799d | ||
|
|
d8cffcaae7 | ||
|
|
30abca7be2 | ||
|
|
edce87f3fb | ||
|
|
66bac98fc2 | ||
|
|
59156de92b | ||
|
|
e0d7d10600 | ||
|
|
daaf862257 | ||
|
|
9de53d4b59 | ||
|
|
f1571e2d46 | ||
|
|
bd28d06298 | ||
|
|
a24e4655eb | ||
|
|
20a6c8d8e5 | ||
|
|
98d264faf4 | ||
|
|
321902a9b5 | ||
|
|
8df5d06f9a | ||
|
|
e69ea529cc | ||
|
|
15405b1119 | ||
|
|
d2f97ce2da | ||
|
|
543ca631e9 | ||
|
|
f184886db1 | ||
|
|
8432ab4324 | ||
|
|
6c05b37ca3 | ||
|
|
35f4beeb47 | ||
|
|
cbad7caa68 | ||
|
|
b0388a4012 | ||
|
|
df3fab4d55 | ||
|
|
da49f88a03 | ||
|
|
e28feceb06 | ||
|
|
50496a164d | ||
|
|
6f1dce1572 | ||
|
|
6847776ae7 | ||
|
|
67bd53bdd8 | ||
|
|
e735abfdfd | ||
|
|
1de93a2d6d | ||
|
|
36f9e7c742 | ||
|
|
9462763bbb | ||
|
|
4ae0880ea6 | ||
|
|
6ae2b6c835 | ||
|
|
a0f180fd48 | ||
|
|
bf1cf89914 | ||
|
|
297a047fb4 | ||
|
|
52ffc15ffc | ||
|
|
e478c9c693 | ||
|
|
d004f28074 | ||
|
|
bc68ed8b1d | ||
|
|
04555ae650 | ||
|
|
e8f62085be | ||
|
|
f430bffe2a | ||
|
|
1f0520634f | ||
|
|
902d4c31fb | ||
|
|
17364ac09f | ||
|
|
0b889f8f81 | ||
|
|
40e349ff35 | ||
|
|
c943b1b1df | ||
|
|
912bc1d4e1 | ||
|
|
cacb1533a3 | ||
|
|
f0feaca9d7 | ||
|
|
b6656f171b | ||
|
|
6206ab3931 | ||
|
|
c35fc58b1f | ||
|
|
deed8abed7 | ||
|
|
7151ad23f0 | ||
|
|
0166d938af | ||
|
|
6194aeddb0 | ||
|
|
903dbf2c30 | ||
|
|
9380f9ff57 | ||
|
|
259ed95486 | ||
|
|
2ebc92681e | ||
|
|
195a1ffe13 | ||
|
|
a8c2978185 | ||
|
|
140f97a457 | ||
|
|
7f94445a1e | ||
|
|
82a89aec65 | ||
|
|
7e95110232 | ||
|
|
ec4aaaad89 | ||
|
|
1b790fde24 | ||
|
|
aaccea731e | ||
|
|
29e31d7610 | ||
|
|
aa51f4a98f | ||
|
|
e6ccd12f00 | ||
|
|
b134315df1 | ||
|
|
7f34dffa13 | ||
|
|
fa239e78c9 | ||
|
|
707a6c4d6a | ||
|
|
e5da303b43 | ||
|
|
84ccd66331 | ||
|
|
ad8cc2baea | ||
|
|
7c4cf70309 | ||
|
|
c3211e9b4f | ||
|
|
268d94c983 | ||
|
|
0bcacbba58 | ||
|
|
8cdc26add9 | ||
|
|
e0b2238886 | ||
|
|
369a2e4029 | ||
|
|
c4089e3b51 | ||
|
|
9e2e9bc5b8 | ||
|
|
a9e44426ed |
30
.gitignore
vendored
30
.gitignore
vendored
@@ -1,30 +0,0 @@
|
|||||||
*.5
|
|
||||||
*.7
|
|
||||||
*.8
|
|
||||||
*.a
|
|
||||||
*.d
|
|
||||||
*.o
|
|
||||||
*.orig
|
|
||||||
*.pc
|
|
||||||
*.pot
|
|
||||||
*.rej
|
|
||||||
*.so
|
|
||||||
*.so.*
|
|
||||||
*.sw*
|
|
||||||
*~
|
|
||||||
|
|
||||||
.export.sym
|
|
||||||
.exported_symbols_generated
|
|
||||||
.gdb_history
|
|
||||||
|
|
||||||
Makefile
|
|
||||||
make.tmpl
|
|
||||||
|
|
||||||
/autom4te.cache/
|
|
||||||
/autoscan.log
|
|
||||||
/config.log
|
|
||||||
/config.status
|
|
||||||
/configure.scan
|
|
||||||
/cscope.out
|
|
||||||
/tags
|
|
||||||
/tmp/
|
|
||||||
34
INSTALL
34
INSTALL
@@ -1,30 +1,44 @@
|
|||||||
Installation
|
LVM2 installation
|
||||||
============
|
=================
|
||||||
|
|
||||||
1) Generate custom makefiles.
|
1) Install device-mapper
|
||||||
|
|
||||||
|
Ensure the device-mapper has been installed on the machine.
|
||||||
|
|
||||||
|
The device-mapper should be in the kernel (look for 'device-mapper'
|
||||||
|
messages in the kernel logs) and /usr/include/libdevmapper.h
|
||||||
|
and libdevmapper.so should be present.
|
||||||
|
|
||||||
|
The device-mapper is available from:
|
||||||
|
ftp://ftp.sistina.com/pub/LVM2/device-mapper/
|
||||||
|
|
||||||
|
|
||||||
|
2) Generate custom makefiles.
|
||||||
|
|
||||||
Run the 'configure' script from the top directory.
|
Run the 'configure' script from the top directory.
|
||||||
|
|
||||||
|
If you wish to use the built-in LVM2 shell and have GNU readline
|
||||||
|
installed (http://www.gnu.org/directory/readline.html) use:
|
||||||
|
./configure --enable-readline
|
||||||
|
|
||||||
If you don't want to include the LVM1 backwards-compatibility code use:
|
If you don't want to include the LVM1 backwards-compatibility code use:
|
||||||
./configure --with-lvm1=none
|
./configure --with-lvm1=none
|
||||||
|
|
||||||
To separate the LVM1 support into a shared library loaded by lvm.conf use:
|
To separate the LVM1 support into a shared library loaded by lvm.conf use:
|
||||||
./configure --with-lvm1=shared
|
./configure --with-lvm1=shared
|
||||||
|
|
||||||
Use ./configure --help to see other options.
|
|
||||||
|
|
||||||
2) Build and install.
|
3) Build and install LVM2.
|
||||||
|
|
||||||
Run 'make' from the top directory to build everything you configured.
|
Run 'make install' from the top directory.
|
||||||
Run 'make install' to build and install everything you configured.
|
|
||||||
|
|
||||||
If you only want the device-mapper libraries and tools use
|
|
||||||
'make device-mapper' or 'make install_device-mapper'.
|
|
||||||
|
|
||||||
3) If using LVM2, create a configuration file.
|
4) Create a configuration file
|
||||||
|
|
||||||
The tools will work fine without a configuration file being
|
The tools will work fine without a configuration file being
|
||||||
present, but you ought to review the example file in doc/example.conf.
|
present, but you ought to review the example file in doc/example.conf.
|
||||||
|
For example, specifying the devices that LVM2 is to use can
|
||||||
|
make the tools run more efficiently - and avoid scanning /dev/cdrom!
|
||||||
|
|
||||||
Please also refer to the WHATS_NEW file and the manual pages for the
|
Please also refer to the WHATS_NEW file and the manual pages for the
|
||||||
individual commands.
|
individual commands.
|
||||||
|
|||||||
239
Makefile.in
239
Makefile.in
@@ -1,6 +1,6 @@
|
|||||||
#
|
#
|
||||||
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||||
# Copyright (C) 2004-2015 Red Hat, Inc. All rights reserved.
|
# Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
|
||||||
#
|
#
|
||||||
# This file is part of LVM2.
|
# This file is part of LVM2.
|
||||||
#
|
#
|
||||||
@@ -14,227 +14,94 @@
|
|||||||
|
|
||||||
srcdir = @srcdir@
|
srcdir = @srcdir@
|
||||||
top_srcdir = @top_srcdir@
|
top_srcdir = @top_srcdir@
|
||||||
top_builddir = @top_builddir@
|
VPATH = @srcdir@
|
||||||
abs_top_builddir = @abs_top_builddir@
|
|
||||||
abs_top_srcdir = @abs_top_srcdir@
|
|
||||||
|
|
||||||
SUBDIRS = conf daemons include lib libdaemon libdm man scripts tools
|
SUBDIRS = doc include man scripts
|
||||||
|
|
||||||
ifeq ("@UDEV_RULES@", "yes")
|
|
||||||
SUBDIRS += udev
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ("@INTL@", "yes")
|
ifeq ("@INTL@", "yes")
|
||||||
SUBDIRS += po
|
SUBDIRS += po
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ("@APPLIB@", "yes")
|
SUBDIRS += lib tools daemons
|
||||||
SUBDIRS += liblvm
|
|
||||||
|
ifeq ("@DMEVENTD@", "yes")
|
||||||
|
SUBDIRS += dmeventd
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ("@PYTHON_BINDINGS@", "yes")
|
|
||||||
SUBDIRS += python
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(MAKECMDGOALS),clean)
|
|
||||||
SUBDIRS += test
|
|
||||||
endif
|
|
||||||
# FIXME Should use intermediate Makefiles here!
|
|
||||||
ifeq ($(MAKECMDGOALS),distclean)
|
ifeq ($(MAKECMDGOALS),distclean)
|
||||||
SUBDIRS = conf include man test scripts \
|
SUBDIRS += daemons/clvmd \
|
||||||
libdaemon lib tools daemons libdm \
|
dmeventd \
|
||||||
udev po liblvm python \
|
lib/format1 \
|
||||||
unit-tests/datastruct unit-tests/mm unit-tests/regex
|
lib/format_pool \
|
||||||
tools.distclean: test.distclean
|
lib/locking \
|
||||||
|
lib/mirror \
|
||||||
|
lib/snapshot \
|
||||||
|
test \
|
||||||
|
po
|
||||||
|
DISTCLEAN_TARGETS += lib/misc/configure.h
|
||||||
|
DISTCLEAN_DIRS += lcov_reports*
|
||||||
endif
|
endif
|
||||||
DISTCLEAN_DIRS += lcov_reports*
|
|
||||||
DISTCLEAN_TARGETS += config.cache config.log config.status make.tmpl
|
|
||||||
|
|
||||||
include make.tmpl
|
include make.tmpl
|
||||||
|
|
||||||
libdm: include
|
daemons: lib
|
||||||
libdaemon: include
|
lib: include
|
||||||
lib: libdm libdaemon
|
tools: lib
|
||||||
liblvm: lib
|
dmeventd: tools
|
||||||
daemons: lib libdaemon tools
|
po: tools daemons dmeventd
|
||||||
tools: lib libdaemon device-mapper
|
|
||||||
po: tools daemons
|
|
||||||
scripts: liblvm libdm
|
|
||||||
|
|
||||||
lib.device-mapper: include.device-mapper
|
|
||||||
libdm.device-mapper: include.device-mapper
|
|
||||||
liblvm.device-mapper: include.device-mapper
|
|
||||||
daemons.device-mapper: libdm.device-mapper
|
|
||||||
tools.device-mapper: libdm.device-mapper
|
|
||||||
scripts.device-mapper: include.device-mapper
|
|
||||||
device-mapper: tools.device-mapper daemons.device-mapper man.device-mapper
|
|
||||||
|
|
||||||
ifeq ("@INTL@", "yes")
|
ifeq ("@INTL@", "yes")
|
||||||
lib.pofile: include.pofile
|
lib.pofile: include.pofile
|
||||||
tools.pofile: lib.pofile
|
tools.pofile: lib.pofile
|
||||||
daemons.pofile: lib.pofile
|
daemons.pofile: lib.pofile
|
||||||
po.pofile: tools.pofile daemons.pofile
|
dmeventd.pofile: tools.pofile
|
||||||
|
po.pofile: tools.pofile daemons.pofile dmeventd.pofile
|
||||||
pofile: po.pofile
|
pofile: po.pofile
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ("@PYTHON_BINDINGS@", "yes")
|
ifneq ("@CFLOW_CMD@", "")
|
||||||
python: liblvm
|
tools.cflow: lib.cflow
|
||||||
endif
|
cflow: tools.cflow
|
||||||
|
|
||||||
ifneq ("$(CFLOW_CMD)", "")
|
|
||||||
tools.cflow: libdm.cflow lib.cflow
|
|
||||||
daemons.cflow: tools.cflow
|
|
||||||
cflow: include.cflow
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ("@CSCOPE_CMD@", "")
|
ifneq ("@CSCOPE_CMD@", "")
|
||||||
cscope.out:
|
cscope.out: tools
|
||||||
@CSCOPE_CMD@ -b -R -s$(top_srcdir)
|
@CSCOPE_CMD@ -b -R
|
||||||
all: cscope.out
|
all: cscope.out
|
||||||
endif
|
endif
|
||||||
DISTCLEAN_TARGETS += cscope.out
|
|
||||||
CLEAN_DIRS += autom4te.cache
|
|
||||||
|
|
||||||
check check_system check_cluster check_local check_lvmetad check_lvmpolld unit: all
|
check: all
|
||||||
$(MAKE) -C test $(@)
|
$(MAKE) -C test all
|
||||||
|
|
||||||
conf.generate: tools
|
ifneq ("@LCOV@", "")
|
||||||
|
.PHONY: lcov-reset lcov lcov-dated
|
||||||
# how to use parenthesis in makefiles
|
|
||||||
leftparen:=(
|
|
||||||
LVM_VER := $(firstword $(subst $(leftparen), ,$(LVM_VERSION)))
|
|
||||||
VER := LVM2.$(LVM_VER)
|
|
||||||
# release file name
|
|
||||||
FILE_VER := $(VER).tgz
|
|
||||||
CLEAN_TARGETS += $(FILE_VER)
|
|
||||||
CLEAN_DIRS += $(rpmbuilddir)
|
|
||||||
|
|
||||||
dist:
|
|
||||||
@echo "Generating $(FILE_VER)";\
|
|
||||||
(cd $(top_srcdir); git ls-tree -r HEAD --name-only | xargs tar --transform "s,^,$(VER)/," -c) | gzip >$(FILE_VER)
|
|
||||||
|
|
||||||
rpm: dist
|
|
||||||
$(RM) -r $(rpmbuilddir)/SOURCES
|
|
||||||
$(MKDIR_P) $(rpmbuilddir)/SOURCES
|
|
||||||
$(LN_S) -f $(abs_top_builddir)/$(FILE_VER) $(rpmbuilddir)/SOURCES
|
|
||||||
$(LN_S) -f $(abs_top_srcdir)/spec/build.inc $(rpmbuilddir)/SOURCES
|
|
||||||
$(LN_S) -f $(abs_top_srcdir)/spec/macros.inc $(rpmbuilddir)/SOURCES
|
|
||||||
$(LN_S) -f $(abs_top_srcdir)/spec/packages.inc $(rpmbuilddir)/SOURCES
|
|
||||||
DM_VER=$$(cut -d- -f1 $(top_srcdir)/VERSION_DM);\
|
|
||||||
GIT_VER=$$(cd $(top_srcdir); git describe | cut -d- --output-delimiter=. -f2,3 || echo 0);\
|
|
||||||
sed -e "s,\(device_mapper_version\) [0-9.]*$$,\1 $$DM_VER," \
|
|
||||||
-e "s,^\(Version:[^0-9%]*\)[0-9.]*$$,\1 $(LVM_VER)," \
|
|
||||||
-e "s,^\(Release:[^0-9%]*\)[0-9.]\+,\1 $$GIT_VER," \
|
|
||||||
$(top_srcdir)/spec/source.inc >$(rpmbuilddir)/SOURCES/source.inc
|
|
||||||
rpmbuild -v --define "_topdir $(rpmbuilddir)" -ba $(top_srcdir)/spec/lvm2.spec
|
|
||||||
|
|
||||||
generate: conf.generate
|
|
||||||
$(MAKE) -C conf generate
|
|
||||||
|
|
||||||
all_man:
|
|
||||||
$(MAKE) -C man all_man
|
|
||||||
|
|
||||||
install_system_dirs:
|
|
||||||
$(INSTALL_DIR) $(DESTDIR)$(DEFAULT_SYS_DIR)
|
|
||||||
$(INSTALL_ROOT_DIR) $(DESTDIR)$(DEFAULT_ARCHIVE_DIR)
|
|
||||||
$(INSTALL_ROOT_DIR) $(DESTDIR)$(DEFAULT_BACKUP_DIR)
|
|
||||||
$(INSTALL_ROOT_DIR) $(DESTDIR)$(DEFAULT_CACHE_DIR)
|
|
||||||
$(INSTALL_ROOT_DIR) $(DESTDIR)$(DEFAULT_LOCK_DIR)
|
|
||||||
$(INSTALL_ROOT_DIR) $(DESTDIR)$(DEFAULT_RUN_DIR)
|
|
||||||
$(INSTALL_ROOT_DATA) /dev/null $(DESTDIR)$(DEFAULT_CACHE_DIR)/.cache
|
|
||||||
|
|
||||||
install_initscripts:
|
|
||||||
$(MAKE) -C scripts install_initscripts
|
|
||||||
|
|
||||||
install_systemd_generators:
|
|
||||||
$(MAKE) -C scripts install_systemd_generators
|
|
||||||
$(MAKE) -C man install_systemd_generators
|
|
||||||
|
|
||||||
install_systemd_units:
|
|
||||||
$(MAKE) -C scripts install_systemd_units
|
|
||||||
|
|
||||||
install_all_man:
|
|
||||||
$(MAKE) -C man install_all_man
|
|
||||||
|
|
||||||
ifeq ("@PYTHON_BINDINGS@", "yes")
|
|
||||||
install_python_bindings:
|
|
||||||
$(MAKE) -C liblvm/python install_python_bindings
|
|
||||||
endif
|
|
||||||
|
|
||||||
install_tmpfiles_configuration:
|
|
||||||
$(MAKE) -C scripts install_tmpfiles_configuration
|
|
||||||
|
|
||||||
LCOV_TRACES = libdm.info lib.info liblvm.info tools.info \
|
|
||||||
libdaemon/client.info libdaemon/server.info \
|
|
||||||
daemons/clvmd.info daemons/dmeventd.info \
|
|
||||||
daemons/lvmetad.info
|
|
||||||
|
|
||||||
CLEAN_TARGETS += $(LCOV_TRACES)
|
|
||||||
|
|
||||||
ifneq ("$(LCOV)", "")
|
|
||||||
.PHONY: lcov-reset lcov lcov-dated $(LCOV_TRACES)
|
|
||||||
|
|
||||||
ifeq ($(MAKECMDGOALS),lcov-dated)
|
ifeq ($(MAKECMDGOALS),lcov-dated)
|
||||||
LCOV_REPORTS_DIR := lcov_reports-$(shell date +%Y%m%d%k%M%S)
|
LCOV_REPORTS_DIR=$(top_srcdir)/lcov_reports-$(shell date +%Y%m%d%k%M%S)
|
||||||
lcov-dated: lcov
|
|
||||||
else
|
else
|
||||||
LCOV_REPORTS_DIR := lcov_reports
|
LCOV_REPORTS_DIR=$(top_srcdir)/lcov_reports
|
||||||
endif
|
endif
|
||||||
|
|
||||||
lcov-reset:
|
lcov-reset:
|
||||||
$(LCOV) --zerocounters $(addprefix -d , $(basename $(LCOV_TRACES)))
|
$(LCOV) -d $(top_srcdir)/dmeventd --zerocounters
|
||||||
|
$(LCOV) -d $(top_srcdir)/lib --zerocounters
|
||||||
|
$(LCOV) -d $(top_srcdir)/tools --zerocounters
|
||||||
|
|
||||||
# maybe use subdirs processing to create tracefiles...
|
lcov: all
|
||||||
$(LCOV_TRACES):
|
$(RM) -rf $(LCOV_REPORTS_DIR)
|
||||||
$(LCOV) -b $(basename $@) -d $(basename $@) \
|
|
||||||
--ignore-errors source -c -o - | $(SED) \
|
|
||||||
-e "s/\(dmeventd_lvm.[ch]\)/plugins\/lvm2\/\1/" \
|
|
||||||
-e "s/dmeventd_\(mirror\|snapshot\|thin\|raid\)\.c/plugins\/\1\/dmeventd_\1\.c/" \
|
|
||||||
>$@
|
|
||||||
|
|
||||||
ifneq ("$(GENHTML)", "")
|
|
||||||
lcov: $(LCOV_TRACES)
|
|
||||||
$(RM) -r $(LCOV_REPORTS_DIR)
|
|
||||||
$(MKDIR_P) $(LCOV_REPORTS_DIR)
|
$(MKDIR_P) $(LCOV_REPORTS_DIR)
|
||||||
for i in $(LCOV_TRACES); do \
|
$(LCOV) -b $(top_srcdir)/lib -d $(top_srcdir)/lib -c -o $(LCOV_REPORTS_DIR)/lib.info
|
||||||
test -s $$i -a $$(wc -w <$$i) -ge 100 && lc="$$lc $$i"; \
|
$(LCOV) -b $(top_srcdir)/tools -d $(top_srcdir)/tools -c -o $(LCOV_REPORTS_DIR)/tools.info
|
||||||
done; \
|
DMEVENTD_INFO="$(LCOV_REPORTS_DIR)/dmeventd.info" ;\
|
||||||
test -z "$$lc" || $(GENHTML) -p @abs_top_builddir@ \
|
DMEVENTD_INFO_A="-a $$DMEVENTDINFO" ;\
|
||||||
-o $(LCOV_REPORTS_DIR) $$lc
|
$(LCOV) -b $(top_srcdir)/dmeventd -d $(top_srcdir)/dmeventd -c -o $$DMEVENTD_INFO || DMEVENTD_INFO_A="" ;\
|
||||||
|
$(LCOV) $$DMEVENTD_INFO_A -a $(LCOV_REPORTS_DIR)/lib.info \
|
||||||
|
-a $(LCOV_REPORTS_DIR)/tools.info \
|
||||||
|
-o $(LCOV_REPORTS_DIR)/lvm.info
|
||||||
|
ifneq ("@GENHTML@", "")
|
||||||
|
$(GENHTML) -o $(LCOV_REPORTS_DIR) -p $(top_srcdir) $(LCOV_REPORTS_DIR)/lvm.info
|
||||||
endif
|
endif
|
||||||
|
|
||||||
endif
|
lcov-dated: lcov
|
||||||
|
|
||||||
ifeq ("$(TESTING)", "yes")
|
|
||||||
# testing and report generation
|
|
||||||
RUBY=ruby1.9 -Ireport-generators/lib -Ireport-generators/test
|
|
||||||
|
|
||||||
.PHONY: unit-test ruby-test test-programs
|
|
||||||
|
|
||||||
# FIXME: put dependencies on libdm and liblvm
|
|
||||||
# FIXME: Should be handled by Makefiles in subdirs, not here at top level.
|
|
||||||
test-programs:
|
|
||||||
cd unit-tests/regex && $(MAKE)
|
|
||||||
cd unit-tests/datastruct && $(MAKE)
|
|
||||||
cd unit-tests/mm && $(MAKE)
|
|
||||||
|
|
||||||
unit-test: test-programs
|
|
||||||
$(RUBY) report-generators/unit_test.rb $(shell find . -name TESTS)
|
|
||||||
$(RUBY) report-generators/title_page.rb
|
|
||||||
|
|
||||||
memcheck: test-programs
|
|
||||||
$(RUBY) report-generators/memcheck.rb $(shell find . -name TESTS)
|
|
||||||
$(RUBY) report-generators/title_page.rb
|
|
||||||
|
|
||||||
ruby-test:
|
|
||||||
$(RUBY) report-generators/test/ts.rb
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifneq ($(shell which ctags),)
|
|
||||||
.PHONY: tags
|
|
||||||
tags:
|
|
||||||
test -z "$(shell find $(top_srcdir) -type f -name '*.[ch]' -newer tags 2>/dev/null | head -1)" || $(RM) tags
|
|
||||||
test -f tags || find $(top_srcdir) -maxdepth 5 -type f -name '*.[ch]' -exec ctags -a '{}' +
|
|
||||||
|
|
||||||
CLEAN_TARGETS += tags
|
|
||||||
endif
|
endif
|
||||||
|
|||||||
32
README
32
README
@@ -1,33 +1,23 @@
|
|||||||
This tree contains the LVM2 and device-mapper tools and libraries.
|
This directory contains LVM2, the new version of the userland LVM
|
||||||
|
tools designed for the new device-mapper for the Linux kernel.
|
||||||
|
|
||||||
For more information about LVM2 read the changelog in the WHATS_NEW file.
|
The device-mapper needs to be installed before compiling these LVM2 tools.
|
||||||
|
|
||||||
|
For more information about LVM2 read the WHATS_NEW file.
|
||||||
Installation instructions are in INSTALL.
|
Installation instructions are in INSTALL.
|
||||||
|
|
||||||
There is no warranty - see COPYING and COPYING.LIB.
|
There is no warranty - see COPYING and COPYING.LIB.
|
||||||
|
|
||||||
Tarballs are available from:
|
Tarballs are available from:
|
||||||
ftp://sources.redhat.com/pub/lvm2/
|
ftp://sources.redhat.com/pub/lvm2/
|
||||||
|
ftp://sources.redhat.com/pub/dm/
|
||||||
|
|
||||||
The source code is stored in git:
|
To access the CVS tree use:
|
||||||
http://git.fedorahosted.org/git/lvm2.git
|
cvs -d :pserver:cvs@sources.redhat.com:/cvs/lvm2 login
|
||||||
git clone git://git.fedorahosted.org/git/lvm2.git
|
CVS password: cvs
|
||||||
|
cvs -d :pserver:cvs@sources.redhat.com:/cvs/lvm2 co LVM2
|
||||||
|
|
||||||
Mailing list for general discussion related to LVM2:
|
Mailing list for discussion/bug reports etc.
|
||||||
linux-lvm@redhat.com
|
linux-lvm@redhat.com
|
||||||
Subscribe from https://www.redhat.com/mailman/listinfo/linux-lvm
|
Subscribe from https://www.redhat.com/mailman/listinfo/linux-lvm
|
||||||
|
|
||||||
Mailing lists for LVM2 development, patches and commits:
|
|
||||||
lvm-devel@redhat.com
|
|
||||||
Subscribe from https://www.redhat.com/mailman/listinfo/lvm-devel
|
|
||||||
|
|
||||||
lvm2-commits@lists.fedorahosted.org (Read-only archive of commits)
|
|
||||||
Subscribe from https://fedorahosted.org/mailman/listinfo/lvm2-commits
|
|
||||||
|
|
||||||
Mailing list for device-mapper development, including kernel patches
|
|
||||||
and multipath-tools:
|
|
||||||
dm-devel@redhat.com
|
|
||||||
Subscribe from https://www.redhat.com/mailman/listinfo/dm-devel
|
|
||||||
|
|
||||||
The source code repository used until 7th June 2012 is accessible here:
|
|
||||||
http://sources.redhat.com/cgi-bin/cvsweb.cgi/LVM2/?cvsroot=lvm2.
|
|
||||||
|
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
1.02.111-git (2015-10-30)
|
|
||||||
805
WHATS_NEW_DM
805
WHATS_NEW_DM
@@ -1,808 +1,5 @@
|
|||||||
Version 1.02.111 -
|
Version 1.02.29 -
|
||||||
====================================
|
|
||||||
|
|
||||||
Version 1.02.110 - 30th October 2015
|
|
||||||
====================================
|
|
||||||
Disable thin monitoring plugin when it fails too often (>10 times).
|
|
||||||
Fix/restore parsing of empty field '-' when processing dmeventd event.
|
|
||||||
Enhance dm_tree_node_size_changed() to recognize size reduction.
|
|
||||||
Support exit on idle for dmenventd (1 hour).
|
|
||||||
Add support to allow unmonitor device from plugin itself.
|
|
||||||
New design for thread co-operation in dmeventd.
|
|
||||||
Dmeventd read device status with 'noflush'.
|
|
||||||
Dmeventd closes control device when no device is monitored.
|
|
||||||
Thin plugin for dmeventd improved percentage usage.
|
|
||||||
Snapshot plugin for dmeventd improved percentage usage.
|
|
||||||
Add dm_hold_control_dev to allow holding of control device open.
|
|
||||||
Add dm_report_compact_given_fields to remove given empty fields from report.
|
|
||||||
Use libdm status parsing and local mem raid dmeventd plugin.
|
|
||||||
Use local mem pool and lock only lvm2 execution for mirror dmeventd plugin.
|
|
||||||
Lock protect only lvm2 execution for snapshot and thin dmeventd plugin.
|
|
||||||
Use local mempool for raid and mirror plugins.
|
|
||||||
Reworked thread initialization for dmeventd plugins.
|
|
||||||
Dmeventd handles snapshot overflow for now equally as invalid.
|
|
||||||
Convert dmeventd to use common logging macro system from libdm.
|
|
||||||
Return -ENOMEM when device registration fails instead of 0 (=success).
|
|
||||||
Enforce writethrough mode for cleaner policy.
|
|
||||||
Add support for recognition and deactivation of MD devices to blkdeactivate.
|
|
||||||
Move target status functions out of libdm-deptree.
|
|
||||||
Correct use of max_write_behind parameter when generating raid target line.
|
|
||||||
Fix dm-event systemd service to make sure it is executed before mounting.
|
|
||||||
|
|
||||||
Version 1.02.109 - 22nd September 2016
|
|
||||||
======================================
|
|
||||||
Update man pages for dmsetup and dmstats.
|
|
||||||
Improve help text for dmsetup.
|
|
||||||
Use --noflush and --nolockfs when removing device with --force.
|
|
||||||
Parse new Overflow status string for snapshot target.
|
|
||||||
Check dir path components are valid if using dm_create_dir, error out if not.
|
|
||||||
Fix /dev/mapper handling to remove dangling entries if symlinks are found.
|
|
||||||
Make it possible to use blank value as selection for string list report field.
|
|
||||||
|
|
||||||
Version 1.02.108 - 15th September 2015
|
|
||||||
======================================
|
|
||||||
Do not check for full thin pool when activating without messages (1.02.107).
|
|
||||||
|
|
||||||
Version 1.02.107 - 5th September 2015
|
|
||||||
=====================================
|
=====================================
|
||||||
Parse thin-pool status with one single routine internally.
|
|
||||||
Add --histogram to select default histogram fields for list and report.
|
|
||||||
Add report fields for displaying latency histogram configuration and data.
|
|
||||||
Add dmstats --bounds to specify histogram boundaries for a new region.
|
|
||||||
Add dm_histogram_to_string() to format histogram data in string form.
|
|
||||||
Add public methods to libdm to access numerical histogram config and data.
|
|
||||||
Parse and store histogram data in dm_stats_list() and dm_stats_populate().
|
|
||||||
Add an argument to specify histogram bounds to dm_stats_create_region().
|
|
||||||
Add dm_histogram_bounds_from_{string,uint64_t}() to parse histogram bounds.
|
|
||||||
Add dm_histogram handle type to represent a latency histogram and its bounds.
|
|
||||||
Fix devmapper.pc pkgconfig file to not reference non-existent rt.pc file.
|
|
||||||
Reinstate dm_task_get_info@Base to libdevmapper exports. (1.02.106)
|
|
||||||
|
|
||||||
Version 1.02.106 - 26th August 2015
|
|
||||||
===================================
|
|
||||||
Add 'precise' column to statistics reports.
|
|
||||||
Add --precise switch to 'dmstats create' to request nanosecond counters.
|
|
||||||
Add precise argument to dm_stats_create_region().
|
|
||||||
Add support to libdm-stats for precise_timestamps
|
|
||||||
|
|
||||||
Version 1.02.105 - 17th August 2015
|
|
||||||
===================================
|
|
||||||
Fix 'dmstats list -o all' segfault.
|
|
||||||
Separate dmstats statistics fields from region information fields.
|
|
||||||
Add interval and interval_ns fields to dmstats reports.
|
|
||||||
Do not include internal glibc headers in libdm-timestamp.c (1.02.104)
|
|
||||||
Exit immediately if no device is supplied to dmsetup wipe_table.
|
|
||||||
Suppress dmsetup report headings when no data is output. (1.02.104)
|
|
||||||
Adjust dmsetup usage/help output selection to match command invoked.
|
|
||||||
Fix dmsetup -o all to select correct fields in splitname report.
|
|
||||||
Restructure internal dmsetup argument handling across all commands.
|
|
||||||
Add dm_report_is_empty() to indicate there is no data awaiting output.
|
|
||||||
Add more arg validation for dm_tree_node_add_cache_target().
|
|
||||||
Add --alldevices switch to replace use of --force for stats create / delete.
|
|
||||||
|
|
||||||
Version 1.02.104 - 10th August 2015
|
|
||||||
===================================
|
|
||||||
Add dmstats.8 man page
|
|
||||||
Add dmstats --segments switch to create one region per device segment.
|
|
||||||
Add dmstats --regionid, --allregions to specify a single / all stats regions.
|
|
||||||
Add dmstats --allprograms for stats commands that filter by program ID.
|
|
||||||
Add dmstats --auxdata and --programid args to specify aux data and program ID.
|
|
||||||
Add report stats sub-command to provide repeating stats reports.
|
|
||||||
Add clear, delete, list, and print stats sub-commands.
|
|
||||||
Add create stats sub-command and --start, --length, --areas and --areasize.
|
|
||||||
Recognize 'dmstats' as an alias for 'dmsetup stats' when run with this name.
|
|
||||||
Add a 'stats' command to dmsetup to configure, manage and report stats data.
|
|
||||||
Add statistics fields to dmsetup -o.
|
|
||||||
Add libdm-stats library to allow management of device-mapper statistics.
|
|
||||||
Add --nosuffix to suppress dmsetup unit suffixes in report output.
|
|
||||||
Add --units to control dmsetup report field output units.
|
|
||||||
Add support to redisplay column headings for repeating column reports.
|
|
||||||
Fix report header and row resource leaks.
|
|
||||||
Report timestamps of ioctls with dmsetup -vvv.
|
|
||||||
Recognize report field name variants without any underscores too.
|
|
||||||
Add dmsetup --interval and --count to repeat reports at specified intervals.
|
|
||||||
Add dm_timestamp functions to libdevmapper.
|
|
||||||
Recognise vg/lv name format in dmsetup.
|
|
||||||
Move size display code to libdevmapper as dm_size_to_string.
|
|
||||||
|
|
||||||
Version 1.02.103 - 24th July 2015
|
|
||||||
=================================
|
|
||||||
Introduce libdevmapper wrappers for all malloc-related functions.
|
|
||||||
|
|
||||||
Version 1.02.102 - 7th July 2015
|
|
||||||
================================
|
|
||||||
Include tool.h for default non-library use.
|
|
||||||
Introduce format macros with embedded % such as FMTu64.
|
|
||||||
|
|
||||||
Version 1.02.101 - 3rd July 2015
|
|
||||||
================================
|
|
||||||
Add experimental support to passing messages in suspend tree.
|
|
||||||
Add dm_report_value_cache_{set,get} to support caching during report/select.
|
|
||||||
Add dm_report_reserved_handler to handle report reserved value actions.
|
|
||||||
Support dynamic value in select: DM_REPORT_FIELD_RESERVED_VALUE_DYNAMIC_VALUE.
|
|
||||||
Support fuzzy names in select: DM_REPORT_FIELD_RESERVED_VALUE_FUZZY_NAMES.
|
|
||||||
Thin pool trace messages show a device name and major:minor.
|
|
||||||
|
|
||||||
Version 1.02.100 - 30th June 2015
|
|
||||||
=================================
|
|
||||||
Add since, after, until and before time operators to be used in selection.
|
|
||||||
Add support for time in reports and selection: DM_REPORT_FIELD_TYPE_TIME.
|
|
||||||
Support report reserved value ranges: DM_REPORT_FIELD_RESERVED_VALUE_RANGE.
|
|
||||||
Support report reserved value names: DM_REPORT_FIELD_RESERVED_VALUE_NAMED.
|
|
||||||
Add DM_CONFIG_VALUE_FMT_{INT_OCTAL,STRING_NO_QUOTES} config value format flag.
|
|
||||||
Add DM_CONFIG_VALUE_FMT_COMMON_{ARRAY,EXTRA_SPACE} config value format flag.
|
|
||||||
Add dm_config_value_{get,set}_format_flags to get and set config value format.
|
|
||||||
|
|
||||||
Version 1.02.99 - 20th June 2015
|
|
||||||
================================
|
|
||||||
New dm_tree_node_set_thin_pool_read_only(DM_1_02_99) for read-only thin pool.
|
|
||||||
Enhance error message when thin-pool message fails.
|
|
||||||
Fix dmeventd logging to avoid threaded use of static variable.
|
|
||||||
Remove redundant dmeventd SIGALRM coded.
|
|
||||||
|
|
||||||
Version 1.02.98 - 12th June 2015
|
|
||||||
================================
|
|
||||||
Add dm_task_get_errno() to return any unexpected errno from a dm ioctl call.
|
|
||||||
Use copy of errno made after each dm ioctl call in case errno changes later.
|
|
||||||
|
|
||||||
Version 1.02.97 - 15th May 2015
|
|
||||||
===============================
|
|
||||||
New dm_task_get_info(DM_1_02_97) supports internal_suspend state.
|
|
||||||
New symbols are versioned and comes with versioned symbol name (DM_1_02_97).
|
|
||||||
|
|
||||||
Version 1.02.96 - 2nd May 2015
|
|
||||||
==============================
|
|
||||||
Fix selection to not match if using reserved value in criteria with >,<,>=,<.
|
|
||||||
Fix selection to not match reserved values for size fields if using >,<,>=,<.
|
|
||||||
Include uuid or device number in log message after ioctl failure.
|
|
||||||
Add DM_INTERNAL_SUSPEND_FLAG to dm-ioctl.h.
|
|
||||||
Install blkdeactivate script and its man page with make install_device-mapper.
|
|
||||||
|
|
||||||
Version 1.02.95 - 15th March 2015
|
|
||||||
=================================
|
|
||||||
Makefile regenerated.
|
|
||||||
|
|
||||||
Version 1.02.94 - 4th March 2015
|
|
||||||
================================
|
|
||||||
Add dm_report_object_is_selected for generalized interface for report/select.
|
|
||||||
|
|
||||||
Version 1.02.93 - 21st January 2015
|
|
||||||
===================================
|
|
||||||
Reduce severity of ioctl error message when dmeventd waitevent is interrupted.
|
|
||||||
Report 'unknown version' when incompatible version numbers were not obtained.
|
|
||||||
Report more info from thin pool status (out of data, metadata-ro, fail).
|
|
||||||
Support error_if_no_space for thin pool target.
|
|
||||||
Fix segfault while using selection with regex and unbuffered reporting.
|
|
||||||
Add dm_report_compact_fields to remove empty fields from report output.
|
|
||||||
Remove unimplemented dm_report_set_output_selection from libdevmapper.h.
|
|
||||||
|
|
||||||
Version 1.02.92 - 24th November 2014
|
|
||||||
====================================
|
|
||||||
Fix memory corruption with sorting empty string lists (1.02.86).
|
|
||||||
Fix man dmsetup.8 syntax warning of Groff
|
|
||||||
Accept unquoted strings and / in place of {} when parsing configs.
|
|
||||||
|
|
||||||
Version 1.02.91 - 11th November 2014
|
|
||||||
====================================
|
|
||||||
Update cache creation and dm_config_node to pass policy.
|
|
||||||
Allow activation of any thin-pool if transaction_id supplied is 0.
|
|
||||||
Don't print uninitialized stack bytes when non-root uses dm_check_version().
|
|
||||||
Fix selection criteria to not match reserved values when using >, <, >=, <.
|
|
||||||
Add DM_LIST_HEAD_INIT macro to libdevmapper.h.
|
|
||||||
Fix dm_is_dm_major to not issue error about missing /proc lines for dm module.
|
|
||||||
|
|
||||||
Version 1.02.90 - 1st September 2014
|
|
||||||
====================================
|
|
||||||
Restore proper buffer size for parsing mountinfo line (1.02.89)
|
|
||||||
|
|
||||||
Version 1.02.89 - 26th August 2014
|
|
||||||
==================================
|
|
||||||
Improve libdevmapper-event select() error handling.
|
|
||||||
Add extra check for matching transation_id after message submitting.
|
|
||||||
Add dm_report_field_string_list_unsorted for str. list report without sorting.
|
|
||||||
Support --deferred with dmsetup remove to defer removal of open devices.
|
|
||||||
Update dm-ioctl.h to include DM_DEFERRED_REMOVE flag.
|
|
||||||
Add support for selection to match string list subset, recognize { } operator.
|
|
||||||
Fix string list selection with '[value]' to not match list that's superset.
|
|
||||||
Fix string list selection to match whole words only, not prefixes.
|
|
||||||
|
|
||||||
Version 1.02.88 - 5th August 2014
|
|
||||||
=================================
|
|
||||||
Add dm_tree_set_optional_uuid_suffixes to handle upgrades.
|
|
||||||
|
|
||||||
Version 1.02.87 - 23rd July 2014
|
|
||||||
================================
|
|
||||||
Fix dm_report_field_string_list to handle delimiter with multiple chars.
|
|
||||||
Add dm_report_field_reserved_value for per-field reserved value definition.
|
|
||||||
|
|
||||||
Version 1.02.86 - 23rd June 2014
|
|
||||||
================================
|
|
||||||
Make "help" and "?" reporting fields implicit.
|
|
||||||
Recognize implicit "selected" field if using dm_report_init_with_selection.
|
|
||||||
Add support for implicit reporting fields which are predefined in libdm.
|
|
||||||
Add DM_REPORT_FIELD_TYPE_PERCENT: separate number and percent fields.
|
|
||||||
Add dm_percent_range_t,dm_percent_to_float,dm_make_percent to libdm for reuse.
|
|
||||||
Add dm_report_reserved_value to libdevmapper for reserved value definition.
|
|
||||||
Also display field types when listing all fields in selection help.
|
|
||||||
Recognize "help" keyword in selection string to show brief help for selection.
|
|
||||||
Always order items reported as string list field lexicographically.
|
|
||||||
Add dm_report_field_string_list to libdevmapper for direct string list report.
|
|
||||||
Add DM_REPORT_FIELD_TYPE_STRING_LIST: separate string and string list fields.
|
|
||||||
Add dm_str_list to libdevmapper for string list type definition and its reuse.
|
|
||||||
Add dmsetup -S/--select to define selection criteria for dmsetup reports.
|
|
||||||
Add dm_report_init_with_selection to intialize report with selection criteria.
|
|
||||||
Add DM_REPORT_FIELD_TYPE_SIZE: separate number and size reporting fields.
|
|
||||||
Use RemoveOnStop for dm-event.socket systemd unit.
|
|
||||||
Document env var 'DM_DEFAULT_NAME_MANGLING_MODE' in dmsetup man page.
|
|
||||||
Warn user about incorrect use of cookie with 'dmsetup remove --force'.
|
|
||||||
Also recognize 'help'/'?' as reserved sort key name to show help.
|
|
||||||
Add dm_units_to_factor for size unit parsing.
|
|
||||||
Increase bitset size for minors for thin dmeventd plugin.
|
|
||||||
|
|
||||||
Version 1.02.85 - 10th April 2014
|
|
||||||
=================================
|
|
||||||
Check for sprintf error when building internal device path.
|
|
||||||
Check for sprintf error when creating path for dm control node.
|
|
||||||
When buffer for dm_get_library_version() is too small, return error code.
|
|
||||||
Always reinitialize _name_mangling_mode in dm_lib_init().
|
|
||||||
Add tracking flag about implicitly added devices into dm_tree.
|
|
||||||
Stop timeout thread immediately when the last worker thread is finished.
|
|
||||||
Fix dmeventd logging with parallel wait event processing.
|
|
||||||
Reuse _node_send_messages() for validation of transaction_id in preload.
|
|
||||||
Transaction_id could be lower by one only when messages are prepared.
|
|
||||||
Do not call callback when preload fails.
|
|
||||||
Wrap is_selinux_enabled() to be called just once.
|
|
||||||
Use correctly signed 64b constant when working with raid volumes.
|
|
||||||
Exit dmeventd with pidfile cleanup instead of raising SIGKILL on DIE request.
|
|
||||||
Add new DM_EVENT_GET_PARAMETERS request to dmeventd protocol.
|
|
||||||
Do not use systemd's reload for dmeventd restart, use dmeventd -R instead.
|
|
||||||
Drop cryptsetup rules from 10-dm.rules - cryptsetup >= 1.1.3 sets them.
|
|
||||||
|
|
||||||
Version 1.02.84 - 20th January 2014
|
|
||||||
===================================
|
|
||||||
Revert activation of activated nodes if a node preload callback fails.
|
|
||||||
Avoid busy looping on CPU when dmeventd reads event DM_WAIT_RETRY.
|
|
||||||
Ensure global mutex is held when working with dmeventd thread.
|
|
||||||
Drop taking timeout mutex for un/registering dmeventd monitor.
|
|
||||||
Allow section names in config file data to be quoted strings.
|
|
||||||
Close fifos before exiting in dmeventd restart() error path.
|
|
||||||
Move printf format string directly into dm_asprintf args list.
|
|
||||||
Catch invalid use of string sort values when reporting numerical fields.
|
|
||||||
|
|
||||||
Version 1.02.83 - 13th November 2013
|
|
||||||
====================================
|
|
||||||
Consistently report on stderr when device is not found for dmsetup info.
|
|
||||||
Skip race errors when non-udev dmsetup build runs on udev-enabled system.
|
|
||||||
Skip error message when holders are not present in sysfs.
|
|
||||||
Use __linux__ instead of linux define to make libdevmapper.h C compliant.
|
|
||||||
Use mutex to avoid possible race while creating/destroying memory pools.
|
|
||||||
Require libpthread to build now.
|
|
||||||
|
|
||||||
Version 1.02.82 - 4th October 2013
|
|
||||||
==================================
|
|
||||||
Define symbolic names for subsystem udev flags in libdevmapper for easier use.
|
|
||||||
Make subsystem udev rules responsible for importing DM_SUBSYSTEM_UDEV_FLAG*.
|
|
||||||
|
|
||||||
Version 1.02.81 - 23rd September 2013
|
|
||||||
=====================================
|
|
||||||
Tidy dmeventd fifo initialisation.
|
|
||||||
|
|
||||||
Version 1.02.80 - 20th September 2013
|
|
||||||
=====================================
|
|
||||||
Detect invalid sector supplied to 'dmsetup message'.
|
|
||||||
Free any previously-set string if a dm_task_set_* function is called again.
|
|
||||||
Do not allow passing empty new name for dmsetup rename.
|
|
||||||
Display any output returned by 'dmsetup message'.
|
|
||||||
Add dm_task_get_message_response to libdevmapper.
|
|
||||||
|
|
||||||
Version 1.02.79 - 13th August 2013
|
|
||||||
==================================
|
|
||||||
Create dmeventd timeout threads as "detached" so exit status is freed.
|
|
||||||
Add DM_ABORT_ON_INTERNAL_ERRORS env var support to abort on internal errors.
|
|
||||||
|
|
||||||
Version 1.02.78 - 24th July 2013
|
|
||||||
================================
|
|
||||||
Process thin messages once to active thin pool target for dm_tree.
|
|
||||||
Optimize out setting the same value or read_ahead.
|
|
||||||
Add DM_ARRAY_SIZE public macro.
|
|
||||||
Move syslog code out of signal handle in dmeventd.
|
|
||||||
Add DM_TO_STRING public macro.
|
|
||||||
Always return success on dmeventd -V command call.
|
|
||||||
Fix parsing of 64bit snapshot status in dmeventd snapshot plugin.
|
|
||||||
Add dm_get_status_snapshot() for parsing snapshot status.
|
|
||||||
Detecte mounted fs also via reading /proc/self/mountinfo.
|
|
||||||
Add dm_mountinfo_read() for parsing /proc/self/mountinfo.
|
|
||||||
Report error for nonexisting devices in dmeventd communication.
|
|
||||||
Prevent double free error after dmeventd call of _fill_device_data().
|
|
||||||
Update dmevent structure message_data to simplify/fix error path handling.
|
|
||||||
Validate passed params to dm_get_status_raid/thin/thin_pool().
|
|
||||||
Fix 'dmsetup splitname -o' to not fail if used without '-c' switch (1.02.68).
|
|
||||||
Add dm_config_write_{node_out/one_node_out} for enhanced config output.
|
|
||||||
Add dm_config_value_is_bool to check for boolean value in supported formats.
|
|
||||||
Fix config node lookup inside empty sections to not return the section itself.
|
|
||||||
Append discards and read-only fields to exported struct dm_status_thin_pool.
|
|
||||||
Fix segfault for truncated string token in config file after the first '"'.
|
|
||||||
Close open dmeventd FIFO file descriptors on exec (FD_CLOEXEC).
|
|
||||||
Fix resource leak in error path of dmeventd's umount of thin volume.
|
|
||||||
Automatically deactivate failed preloaded dm tree node.
|
|
||||||
Add DM_DISABLE_UDEV environment variable to manage dev nodes by libdm only.
|
|
||||||
Fix dm_task_set_cookie to properly process udev flags if udev_sync disabled.
|
|
||||||
|
|
||||||
Version 1.02.77 - 15th October 2012
|
|
||||||
===================================
|
|
||||||
Support unmount of thin volumes from pool above thin pool threshold.
|
|
||||||
Update man page to reflect that dm UUIDs are being mangled as well.
|
|
||||||
Apply 'dmsetup mangle' for dm UUIDs besides dm names.
|
|
||||||
Add 'mangled_uuid' and 'unmangled_uuid' fields to dmsetup info -c -o.
|
|
||||||
Mangle device UUID on dm_task_set_uuid/newuuid call if necessary.
|
|
||||||
Add dm_task_get_uuid_mangled/unmangled to libdevmapper.
|
|
||||||
Always reset delay_resume_if_new flag when stacking thin pool over anything.
|
|
||||||
Don't create value for dm_config_node and require dm_config_create_value call.
|
|
||||||
Check for existing new_name for dmsetup rename.
|
|
||||||
Fix memory leak in dmsetup _get_split_name() error path.
|
|
||||||
|
|
||||||
Version 1.02.76 - 7th August 2012
|
|
||||||
=================================
|
|
||||||
Add dm_vasprintf to libdevmapper.
|
|
||||||
Allow --noflush with dmsetup status and wait (for thin target).
|
|
||||||
Add dm_config_write_one_node to libdevmapper.
|
|
||||||
Support thin pool message release/reserve_metadata_snap in libdevmapper.
|
|
||||||
Support thin pool discards and external origin features in libdevmapper.
|
|
||||||
Add configure --enable-udev-rule-exec-detection to detect exec path in rules.
|
|
||||||
Use sbindir in udev rules by default and remove executable path detection.
|
|
||||||
Remove hard-coded paths for dmeventd fifos and use default-dm-run-dir.
|
|
||||||
Add configure --with-lvmetad-pidfile to remove hard-coded value.
|
|
||||||
Add configure --with-default-pid-dir for common directory with pid files.
|
|
||||||
Add configure --with-default-dm-run-dir to set run directory for dm tools.
|
|
||||||
Detect kernel_send() errors in cmirrord.
|
|
||||||
Add __attribute__ instrumentation to libdevmapper.h.
|
|
||||||
Print clean_bits instead of sync_bits in pull_state in cmirrord.
|
|
||||||
Add tests for errors from closedir(), close() in cmirrord.
|
|
||||||
Add documentation references in systemd units.
|
|
||||||
Remove veritysetup. Now maintained with cryptsetup.
|
|
||||||
|
|
||||||
Version 1.02.75 - 8th June 2012
|
|
||||||
===============================
|
|
||||||
Upstream source repo now fedorahosted.org git not sources.redhat.com CVS.
|
|
||||||
Remove unsupported udev_get_dev_path libudev call used for checking udev dir.
|
|
||||||
Set delay_resume_if_new on deptree snapshot origin.
|
|
||||||
Log value chosen in _find_config_bool like other variable types do.
|
|
||||||
Wait for dmeventd to exit after sending it DM_EVENT_CMD_DIE when restarting.
|
|
||||||
Append 'Used' to {Blk}DevNames/DevNos dmsetup report headers for clarity.
|
|
||||||
Add configure --with-veritysetup for independent veritysetup tool.
|
|
||||||
Properly support supplied dmevent path in dm_event_register_handler().
|
|
||||||
Remove dmeventd fifos on exit if they are not managed by systemd.
|
|
||||||
Use SD_ACTIVATION environment variable in systemd units to detect systemd.
|
|
||||||
Only start a new dmeventd instance on restart if one was already running.
|
|
||||||
Extend the time waited for input from dmeventd fifo to 5 secs. (1.02.73)
|
|
||||||
|
|
||||||
Version 1.02.74 - 6th March 2012
|
|
||||||
================================
|
|
||||||
Check for multiply-mangled names in auto mangling mode.
|
|
||||||
Fix dm_task_get_name_unmangled to not unmangle already unmangled name.
|
|
||||||
Check whether device names are properly mangled on ioctl return.
|
|
||||||
Deactivation of failed thin check on thin pool returns success.
|
|
||||||
|
|
||||||
Version 1.02.73 - 3rd March 2012
|
|
||||||
================================
|
|
||||||
Test _thread_registry list with holding mutex in dmeventd.
|
|
||||||
Add dm_tree_node_set_callback() for preload and deactivation hooks.
|
|
||||||
Drop unsupported TRIM message for thin pool.
|
|
||||||
Improve logging for fifo startup in dmeventd.
|
|
||||||
Better detection of missing dmeventd fifo connection (1.02.71).
|
|
||||||
Add a few pointer validations in dmsetup.
|
|
||||||
Support dm_task_get_driver_version() query without version string.
|
|
||||||
Log failure of pthread_join when cleaning unused threads in dmeventd.
|
|
||||||
Fix empty string warning logic in _find_config_str. (1.02.68)
|
|
||||||
Fix dm_task_set_name to properly resolve path to dm name (1.02.71).
|
|
||||||
Add dm_strncpy() function as a faster strncpy() replacement.
|
|
||||||
|
|
||||||
Version 1.02.72 - 23rd February 2012
|
|
||||||
====================================
|
|
||||||
Avoid memory reallocation for dm_asprintf.
|
|
||||||
|
|
||||||
Version 1.02.71 - 20th February 2012
|
|
||||||
====================================
|
|
||||||
Switch to using built-in blkid in 13-dm-disk.rules.
|
|
||||||
Add "watch" rule to 13-dm-disk.rules.
|
|
||||||
Detect failing fifo and skip 20s retry communication period.
|
|
||||||
Add DM_DEFAULT_NAME_MANGLING_MODE environment variable as an override.
|
|
||||||
Add dm_lib_init to automatically initialise device-mapper library on load.
|
|
||||||
Replace any '\' char with '\\' in dm table specification on input.
|
|
||||||
Add mangle command to dmsetup to provide renaming to correct mangled form.
|
|
||||||
Add 'mangled_name' and 'unmangled_name' fields to dmsetup info -c -o.
|
|
||||||
Add --manglename option to dmsetup to select the name mangling mode.
|
|
||||||
Add dm_task_get_name_mangled/unmangled to libdevmapper.
|
|
||||||
Mangle device name on dm_task_set_name/newname call if necessary.
|
|
||||||
Add dm_set/get_name_mangling_mode to set/get name mangling in libdevmapper.
|
|
||||||
Add configure --with-default-name-mangling for udev-friendly dev name charset.
|
|
||||||
Test for parsed words in _umount() dmeventd snapshot plugin.
|
|
||||||
Fix memory leak in fail path of parse_loop_device_name() in dmsetup.
|
|
||||||
Check for missing reply_uuid in dm_event_get_registered_device().
|
|
||||||
Check for allocation failure in dmeventd restart().
|
|
||||||
Add few missing allocation failures tests in dmsetup.
|
|
||||||
Fix potential risk of writing in front of buffer in _sysfs_get_dm_name().
|
|
||||||
|
|
||||||
Version 1.02.70 - 12th February 2012
|
|
||||||
====================================
|
|
||||||
Fix dm_event_get_version() check.
|
|
||||||
Add pointer test for dependency check in _add_dev().
|
|
||||||
Validate name and uuid params of dm_tree_add_new_dev_with_udev_flags().
|
|
||||||
Do not crash for dm_report_init() sort_key == NULL and behave like "".
|
|
||||||
Return error for failing allocation in dm_asprintf().
|
|
||||||
Add missing test for failing allocation in dm_realloc() code.
|
|
||||||
Add test for memory allocation failures in regex matcher code.
|
|
||||||
Simplify dm_task_set_geometry() and use dm_asprintf().
|
|
||||||
Set all parameters to 0 for dm_get_next_target() for NULL return.
|
|
||||||
Fix fd resource leak in error path for _udev_notify_sem_create().
|
|
||||||
Leave space for '\0' for readline() call in _sysfs_get_kernel_name().
|
|
||||||
|
|
||||||
Version 1.02.69 - 1st February 2012
|
|
||||||
===================================
|
|
||||||
Clean up dmeventd systemd unit ordering and requirements.
|
|
||||||
|
|
||||||
Version 1.02.68 - 26th January 2012
|
|
||||||
===================================
|
|
||||||
Reset all members of info struct in dm_tree_add_new_dev_with_udev_flags.
|
|
||||||
Add dmsetup wipe_table to replace table with one that uses error target.
|
|
||||||
Add 'blkdevname' and 'blkdevs_used' fields to dmsetup info -c -o.
|
|
||||||
Add 'blkdevname' option to dmsetup ls --tree to see block device names.
|
|
||||||
Add -o devno/blkdevname/devname to dmsetup deps and ls.
|
|
||||||
Add dm_device_get_name to get map name or block device name for given devno.
|
|
||||||
Remove empty devices when clearing left-over inactive tables in deptree.
|
|
||||||
Add dm_uuid_prefix/dm_set_uuid_prefix to override hard-coded LVM- prefix.
|
|
||||||
Improve dmsetup man page description of readahead parameter.
|
|
||||||
Use sysfs to set/get readahead if possible.
|
|
||||||
Fix lvm2-monitor init script to use normalized output when using vgs.
|
|
||||||
Add test for max length (DM_MAX_TYPE_NAME) of target type name.
|
|
||||||
Include a copy of kernel DM documentation in doc/kernel.
|
|
||||||
Improve man page style for dmsetup and mention more targets.
|
|
||||||
Fix _get_proc_number to be tolerant of malformed /proc/misc entries.
|
|
||||||
Fix missing thread list manipulation protection in dmeventd.
|
|
||||||
Add ExecReload to dm-event.service for systemd to reload dmeventd properly.
|
|
||||||
Add dm_config_tree_find_str_allow_empty and dm_config_find_str_allow_empty.
|
|
||||||
Fix compile-time pool memory locking with DEBUG_MEM.
|
|
||||||
Fix valgrind error reports in free of pool chunks with DEBUG_MEM.
|
|
||||||
Align size of structure chunk for fast pool allocator to 8 bytes.
|
|
||||||
Simplify some pointer operations in dm_free_aux() debug code.
|
|
||||||
Remove unused dbg_malloc.h file from source tree.
|
|
||||||
Cleanup backtraces for _create_and_load_v4().
|
|
||||||
Fix alignment warning in bitcount calculation for raid segment.
|
|
||||||
Allocate dm_tree structure from dm_tree pool.
|
|
||||||
Update debug logging for _resume_node.
|
|
||||||
Add functions to support thin provisioning target.
|
|
||||||
Improve libdm-config error path reporting.
|
|
||||||
Update dmsetup resume man with --addnodeonresume/create options.
|
|
||||||
Add dependency for dm man pages to man subdirectory make all target.
|
|
||||||
Add dm_tree_retry_remove to use retry logic for device removal in a dm_tree.
|
|
||||||
Add dm_device_has_mounted_fs fn to check mounted filesystem on a device.
|
|
||||||
Add dm_device_has_holders fn to to check use of the device by another device.
|
|
||||||
Add dm_sysfs_dir to libdevmapper to retrieve sysfs location set.
|
|
||||||
Add dm_set_sysfs_dir to libdevmapper to set sysfs location.
|
|
||||||
Add --retry option for dmsetup remove to retry removal if not successful.
|
|
||||||
Add dm_task_retry_remove fn to use retry logic for device removal.
|
|
||||||
Remove unused passed parameters for _mirror_emit_segment_line().
|
|
||||||
Add dm_config and string character escaping functions to libdevmapper.
|
|
||||||
Mark unreleased memory pools as internal error.
|
|
||||||
|
|
||||||
Version 1.02.67 - 19th August 2011
|
|
||||||
==================================
|
|
||||||
Add dm_tree_node_add_null_area for temporarily-missing raid devs tracked.
|
|
||||||
|
|
||||||
Version 1.02.66 - 12th August 2011
|
|
||||||
==================================
|
|
||||||
Release geometry buffer in dm_task_destroy.
|
|
||||||
Update udev rules to skip DM flags decoding for removed devices.
|
|
||||||
Add compile-time pool memory locking options (to debug shared VG structs).
|
|
||||||
Remove device name prefix from dmsetup line output if -j & -m or -u supplied.
|
|
||||||
Remove support for the original version 1 dm ioctls.
|
|
||||||
Add missing check for allocation failure _create_dir_recursive().
|
|
||||||
Add support for systemd file descriptor handover in dmeventd.
|
|
||||||
Fix memory leak in dmsetup _message() memory allocation error path.
|
|
||||||
Use new oom killer adjustment interface (oom_score_adj) when available.
|
|
||||||
Add systemd unit files for dmeventd.
|
|
||||||
Fix read-only identical table reload supression.
|
|
||||||
|
|
||||||
Version 1.02.65 - 8th July 2011
|
|
||||||
===============================
|
|
||||||
Remove dev name prefix from dmsetup line output if exactly one dev requested.
|
|
||||||
Report internal error if suspending a device using an already-suspended dev.
|
|
||||||
Report error if a table load requiring target parameters has none supplied.
|
|
||||||
Add dmsetup --checks and dm_task_enable_checks framework to validate ioctls.
|
|
||||||
Add age_in_minutes parameter to dmsetup udevcomplete_all.
|
|
||||||
Return immediately from dm_lib_exit() if called more than once.
|
|
||||||
Disable udev fallback by default and add --verifyudev option to dmsetup.
|
|
||||||
Report internal error if any table is loaded while any dev is known suspended.
|
|
||||||
Add dm_get_suspended_counter() for number of devs in suspended state by lib.
|
|
||||||
Fix "all" report field prefix matching to include label fields with pv_all.
|
|
||||||
Delay resuming new preloaded mirror devices with core logs in deptree code.
|
|
||||||
Accept new kernel version 3 uname formats in initialisation.
|
|
||||||
|
|
||||||
Version 1.02.64 - 29th April 2011
|
|
||||||
==================================
|
|
||||||
Require libudev >= 143 when compiling with udev support.
|
|
||||||
Use word alignment for dm_pool_strdup() and dm_pool_strndup().
|
|
||||||
Use dm_snprintf() to fix signedness warning in dm_set_dev_dir().
|
|
||||||
Use unsigned loop counter to fix signedness warning in _other_node_ops().
|
|
||||||
Fix const cast in dmsetup calls of dm_report_field_string().
|
|
||||||
Streamline /dev/mapper/control node code for common cases.
|
|
||||||
Use hard-coded dm control node device number for 2.6.36 kernels and above.
|
|
||||||
Improve stack debug reporting in dm_task_create().
|
|
||||||
Fallback to control node creation only if node doesn't exist yet.
|
|
||||||
Change dm_hash binary functions to take void *key instead of char *.
|
|
||||||
Fix uninitialised memory use with empty params in _reload_with_suppression_v4.
|
|
||||||
Lower severity of selabel_lookup and matchpathcon failure to log_debug.
|
|
||||||
Add test for failed allocation from dm_task_set_uuid() in dmeventd.
|
|
||||||
Add dm_event_get_version to dmeventd for use with -R.
|
|
||||||
Avoid dmeventd core dumps when handling request with unknown command ID.
|
|
||||||
Have dmeventd -R start up even when no existing copy is running.
|
|
||||||
Accept multiple mapped device names on many dmsetup command lines.
|
|
||||||
Fix dm_udev_wait calls in dmsetup to occur before readahead display not after.
|
|
||||||
Include an implicit dm_task_update_nodes() within dm_udev_wait().
|
|
||||||
Fix _create_and_load_v4 not to lose the --addnodeoncreate setting (1.02.62).
|
|
||||||
Add inactive table query support for kernel driver >= 4.11.6 (RHEL 5.7).
|
|
||||||
Log debug open_count in _node_has_closed_parents().
|
|
||||||
Add a const to dm_report_field_string() data parameter.
|
|
||||||
|
|
||||||
Version 1.02.63 - 9th February 2011
|
|
||||||
===================================
|
|
||||||
Reinstate DEBUG_MEM as it's part of the API. (1.02.62)
|
|
||||||
|
|
||||||
Version 1.02.62 - 4th February 2011
|
|
||||||
===================================
|
|
||||||
Add configure --with-device-nodes-on=create for previous behaviour.
|
|
||||||
Move creation of device nodes from 'create' to 'resume'.
|
|
||||||
Add --addnodeonresume and --addnodeoncreate options to dmsetup.
|
|
||||||
Add dm_task_set_add_node to libdevmapper to control dev node creation time.
|
|
||||||
Add dm_task_secure_data to libdevmapper to wipe ioctl buffers in kernel.
|
|
||||||
Log debug message when expected uevent is not generated.
|
|
||||||
Only compile memory debugging code when DEBUG_MEM is set.
|
|
||||||
Set DM_UDEV_DISABLE_OTHER_RULES_FLAG for suspended DM devices in udev rules.
|
|
||||||
Begin a new pool object for each row in _output_as_rows() correctly.
|
|
||||||
|
|
||||||
Version 1.02.61 - 10th January 2011
|
|
||||||
===================================
|
|
||||||
Add DM_COOKIE_AUTO_CREATE to libdevmapper.h.
|
|
||||||
Export DM_CONTROL_NODE_UMASK and use it while creating /dev/mapper/control.
|
|
||||||
|
|
||||||
Version 1.02.60 - 20th December 2010
|
|
||||||
====================================
|
|
||||||
Check for unlink failure in remove_lockfile() in dmeventd.
|
|
||||||
Use dm_free for dm_malloc-ed areas in _clog_ctr/_clog_dtr in cmirrord.
|
|
||||||
Use char* arithmetic in _process_all() & _targets() in dmsetup.
|
|
||||||
Change dm_regex_create() API to accept const char * const *patterns.
|
|
||||||
Add new dm_prepare_selinux_context fn to libdevmapper and use it throughout.
|
|
||||||
Detect existence of new SELinux selabel interface during configure.
|
|
||||||
|
|
||||||
Version 1.02.59 - 6th December 2010
|
|
||||||
===================================
|
|
||||||
Add backtraces to _process_mapper_dir and _create_and_load_v4 error paths.
|
|
||||||
Remove superfluous checks for NULL before calling dm_free.
|
|
||||||
|
|
||||||
Version 1.02.58 - 22nd November 2010
|
|
||||||
====================================
|
|
||||||
Fix _output_field crash from field_id free with DEBUG_MEM. (1.02.57)
|
|
||||||
|
|
||||||
Version 1.02.57 - 8th November 2010
|
|
||||||
===================================
|
|
||||||
Fix regex optimiser not to ignore RHS of OR nodes in _find_leftmost_common.
|
|
||||||
Add dmeventd -R to restart dmeventd without losing monitoring state. (1.02.56)
|
|
||||||
Fix memory leak of field_id in _output_field function.
|
|
||||||
Allocate buffer for reporting functions dynamically to support long outputs.
|
|
||||||
|
|
||||||
Version 1.02.56 - 25th October 2010
|
|
||||||
===================================
|
|
||||||
Return const pointer from dm_basename() in libdevmapper.
|
|
||||||
Implement dmeventd -R to restart without state loss.
|
|
||||||
Add dm_zalloc and use it and dm_pool_zalloc throughout.
|
|
||||||
Add --setuuid to dmsetup rename.
|
|
||||||
Add dm_task_set_newuuid to set uuid of mapped device post-creation.
|
|
||||||
|
|
||||||
Version 1.02.55 - 24th September 2010
|
|
||||||
=====================================
|
|
||||||
Fix the way regions are marked complete to avoid slow --nosync cmirror I/O.
|
|
||||||
Add DM_REPORT_FIELD_TYPE_ID_LEN to libdevmapper.h.
|
|
||||||
|
|
||||||
Version 1.02.54 - 18th August 2010
|
|
||||||
==================================
|
|
||||||
Fix dm-mod autoloading logic to not assume control node is set correctly.
|
|
||||||
Add dmeventd/executable to lvm.conf to test alternative dmeventd.
|
|
||||||
Export dm_event_handler_set_dmeventd_path to override built-in dmeventd path.
|
|
||||||
Generate libdevmapper-event exported symbols.
|
|
||||||
Remove superfluous NULL pointer tests before dm_free from dmeventd.
|
|
||||||
Assume dm-mod autoloading support is in kernel 2.6.36 and higher, not 2.6.35.
|
|
||||||
Fix udev rules to support udev database content generated by older rules.
|
|
||||||
Reinstate detection of inappropriate uevent with DISK_RO set and suppress it.
|
|
||||||
Fix regex ttree off-by-one error.
|
|
||||||
Add --enable-valgrind-pool to configure.
|
|
||||||
Fix segfault in regex matcher with characters of ordinal value > 127.
|
|
||||||
Fix 'void*' arithmetic warnings in dbg_malloc.c and libdm-iface.c.
|
|
||||||
Wait for node creation before displaying debug info in dmsetup.
|
|
||||||
Fix return status 0 for "dmsetup info -c -o help".
|
|
||||||
Add check for kernel semaphore support and disable udev_sync if not available.
|
|
||||||
|
|
||||||
Version 1.02.53 - 28th July 2010
|
|
||||||
================================
|
|
||||||
Revert failed table load preparation after "create, load and resume".
|
|
||||||
Switch dmeventd to use dm_create_lockfile and drop duplicate code.
|
|
||||||
Add dm_create_lockfile to libdm to handle pidfiles for all daemons.
|
|
||||||
Replace lookup with next in struct dfa_state & calculate states on demand.
|
|
||||||
Improve the regex matcher, reducing the number of charset nodes used.
|
|
||||||
Add dm_regex_fingerprint to facilitate regex testing.
|
|
||||||
Skip ffs(0) in _test_word in bitset functions.
|
|
||||||
Use "nowatch" udev rule for inappropriate devices.
|
|
||||||
|
|
||||||
Version 1.02.52 - 6th July 2010
|
|
||||||
===============================
|
|
||||||
Fix dmlosetup snprintf %llu compiler warning.
|
|
||||||
Add parentheses to some libdevmapper.h macro arguments.
|
|
||||||
Add printf format attributes to dm_{sn,as}printf and fix a caller.
|
|
||||||
Move dmeventd man page from install_lvm2 to install_device-mapper. (1.02.50)
|
|
||||||
|
|
||||||
Version 1.02.51 - 30th June 2010
|
|
||||||
================================
|
|
||||||
Generate libdevmapper exported symbols from header file.
|
|
||||||
|
|
||||||
Version 1.02.50 - 23rd June 2010
|
|
||||||
================================
|
|
||||||
Fix INTERNAL_ERROR typo in ioctl iface unknown task message.
|
|
||||||
Fix udev rules to handle spurious events properly.
|
|
||||||
Use C99 [] not [0] in dm_ulog_request struct to avoid abort when fortified.
|
|
||||||
Allow use of devmapper header file in C++ mode (extern "C" and __typeof__).
|
|
||||||
Add dmeventd man page.
|
|
||||||
|
|
||||||
Version 1.02.49 - 4th June 2010
|
|
||||||
===============================
|
|
||||||
Support autoloading of dm-mod module for kernels from 2.6.35.
|
|
||||||
Document 'clear' in dmsetup man page.
|
|
||||||
Fix semctl parameter (union) to avoid misaligned parameter on some arches.
|
|
||||||
Add dm_tree_node_set_presuspend_node() to presuspend child when deactivating.
|
|
||||||
Initial support for replicator target.
|
|
||||||
|
|
||||||
Version 1.02.48 - 17th May 2010
|
|
||||||
================================
|
|
||||||
Use -d to control level of messages sent to syslog by dmeventd.
|
|
||||||
Change -d to -f to run dmeventd in foreground.
|
|
||||||
Do not print encryption key in message debug output (cryptsetup luksResume).
|
|
||||||
Fix dmeventd static build library dependencies.
|
|
||||||
Fix udev flags on remove in create_and_load error path.
|
|
||||||
|
|
||||||
Version 1.02.47 - 30th April 2010
|
|
||||||
=================================
|
|
||||||
Add support for new IMPORT{db} udev rule.
|
|
||||||
Add DM_UDEV_PRIMARY_SOURCE_FLAG udev flag to recognize proper DM events.
|
|
||||||
Also include udev libs in libdevmapper.pc when udev_sync is enabled.
|
|
||||||
Cache bitset locations to speed up _calc_states.
|
|
||||||
Add a regex optimisation pass for shared prefixes and suffixes.
|
|
||||||
Add dm_bit_and and dm_bitset_equal to libdevmapper.
|
|
||||||
Simplify dm_bitset_create.
|
|
||||||
Speed up dm_bit_get_next with ffs().
|
|
||||||
|
|
||||||
Version 1.02.46 - 14th April 2010
|
|
||||||
=================================
|
|
||||||
Change dm_tree_deactivate_children to fail if device is open.
|
|
||||||
Wipe memory buffers for dm-ioctl parameters before releasing.
|
|
||||||
Strictly require libudev if udev_sync is used.
|
|
||||||
Add support for ioctl's DM_UEVENT_GENERATED_FLAG.
|
|
||||||
|
|
||||||
Version 1.02.45 - 9th March 2010
|
|
||||||
================================
|
|
||||||
Add --showkeys parameter description to dmsetup man page.
|
|
||||||
Add --help option as synonym for help command.
|
|
||||||
|
|
||||||
Version 1.02.44 - 15th February 2010
|
|
||||||
====================================
|
|
||||||
Add DM_UDEV_DISABLE_LIBRARY_FALLBACK udev flag to rely on udev only.
|
|
||||||
Export dm_udev_create_cookie function to create new cookies on demand.
|
|
||||||
Add --udevcookie, udevcreatecookie and udevreleasecookie to dmsetup.
|
|
||||||
Set udev state automatically instead of using DM_UDEV_DISABLE_CHECKING.
|
|
||||||
|
|
||||||
Version 1.02.43 - 21st January 2010
|
|
||||||
===================================
|
|
||||||
Remove bitset, hash and pool headers superceded by libdevmapper.h.
|
|
||||||
Fix off-by-one error causing bad cluster mirror table construction.
|
|
||||||
|
|
||||||
Version 1.02.42 - 14th January 2010
|
|
||||||
===================================
|
|
||||||
Add support for the "snapshot-merge" kernel target (2.6.33-rc1).
|
|
||||||
Introduce a third activation_priority level in dm_tree_activate_children.
|
|
||||||
|
|
||||||
Version 1.02.41 - 12th January 2010
|
|
||||||
===================================
|
|
||||||
If DM_UDEV_DISABLE_CHECKING is set in environment, disable udev warnings.
|
|
||||||
Add dm_tree_add_dev_with_udev_flags to provide wider support for udev flags.
|
|
||||||
Add --noudevrules option for dmsetup to disable /dev node management by udev.
|
|
||||||
Fix 'dmsetup info -c -o all' to show all fields.
|
|
||||||
Return errors if dm_tree_*_children functions fail.
|
|
||||||
Fix coredump and memory leak for 'dmsetup help -c'.
|
|
||||||
Disable udev rules for change events with DISK_RO set.
|
|
||||||
|
|
||||||
Version 1.02.40 - 19th November 2009
|
|
||||||
====================================
|
|
||||||
Fix install_device-mapper Makefile target to not build dmeventd plugins.
|
|
||||||
Support udev flags even when udev_sync is disabled or not compiled in.
|
|
||||||
Remove 'last_rule' from udev rules: honour DM_UDEV_DISABLE_OTHER_RULES_FLAG.
|
|
||||||
Add dmsetup --inactive support.
|
|
||||||
Add dm_task_query_inactive_table to libdevmapper for kernel driver >= 4.16.
|
|
||||||
Fix hash lookup segfault when keys compared are different lengths.
|
|
||||||
|
|
||||||
Version 1.02.39 - 26th October 2009
|
|
||||||
===================================
|
|
||||||
Remove strict default permissions for DM devices from 95-dm-notify.rules.
|
|
||||||
Add dmsetup udevflags command to decode udev flags in given cookie value.
|
|
||||||
Support udev flags in libdevmapper incl. dm_tree_add_new_dev_with_udev_flags.
|
|
||||||
Make libdm ABI consistent when built with/without selinux support.
|
|
||||||
|
|
||||||
Version 1.02.38 - 25th September 2009
|
|
||||||
=====================================
|
|
||||||
Export DM_DEV_DIR_UMASK, the default umask for /dev directories created.
|
|
||||||
Handle any path supplied to dm_task_set_name by looking up in /dev/mapper.
|
|
||||||
Add several examples to 12-dm-permissions.rules.
|
|
||||||
Add splitname and --yes to dmsetup man page.
|
|
||||||
Fix _mirror_emit_segment_line return code.
|
|
||||||
Fix dmeventd _temporary_log_fn parameters. (2.02.50)
|
|
||||||
|
|
||||||
Version 1.02.37 - 15th September 2009
|
|
||||||
=====================================
|
|
||||||
Add dmsetup manpage entries for udevcomplete_all and udevcookies.
|
|
||||||
Check udev is running when processing cookies and retain state internally.
|
|
||||||
Add y|--yes option to dmsetup for default 'yes' answer to prompts.
|
|
||||||
Fix tools Makefile to process dmsetup sources separately.
|
|
||||||
Restore umask when device node creation fails.
|
|
||||||
Check kernel vsn to use 'block_on_error' or 'handle_errors' in mirror table.
|
|
||||||
Add dm-log-userspace.h to tree for cmirrord builds.
|
|
||||||
|
|
||||||
Version 1.02.36 - 6th August 2009
|
|
||||||
=================================
|
|
||||||
Add udevcookies, udevcomplete, udevcomplete_all and --noudevwait to dmsetup.
|
|
||||||
Add libdevmapper functions to support synchronisation with udev.
|
|
||||||
|
|
||||||
Version 1.02.35 - 28th July 2009
|
|
||||||
================================
|
|
||||||
Add LOG_LINE_WITH_ERRNO macro.
|
|
||||||
Use log_error macro consistently throughout in place of log_err.
|
|
||||||
|
|
||||||
Version 1.02.34 - 15th July 2009
|
|
||||||
================================
|
|
||||||
Use _exit() not exit() after forking to avoid flushing libc buffers twice.
|
|
||||||
Rename plog macro to LOG_LINE & add LOG_MESG variant for dm_dump_memory_debug.
|
|
||||||
Change plog to use dm_log_with_errno unless deprecated dm_log_init was used.
|
|
||||||
Add dm_log_with_errno and dm_log_with_errno_init, deprecating the old fns.
|
|
||||||
Fix whitespace in linear target line to fix identical table line detection.
|
|
||||||
Add device number to more log messages during activation.
|
|
||||||
|
|
||||||
Version 1.02.33 - 30th June 2009
|
|
||||||
================================
|
|
||||||
Don't fallback to default major number: use dm_task_set_major_minor. (1.02.31)
|
|
||||||
Do not fork daemon when dmeventd cannot be found.
|
|
||||||
Add crypt target handling to libdevmapper tree nodes.
|
|
||||||
Add splitname command to dmsetup.
|
|
||||||
Add subsystem, vg_name, lv_name, lv_layer fields to dmsetup reports.
|
|
||||||
Make mempool optional in dm_split_lvm_name().
|
|
||||||
|
|
||||||
Version 1.02.32 - 21st May 2009
|
|
||||||
===============================
|
|
||||||
Only generate libdevmapper.a when configured to link statically.
|
|
||||||
Export dm_tree_node_size_changed() from libdevmapper.
|
|
||||||
Propagate the table size_changed property up the dm device tree.
|
|
||||||
Detect failure to free memory pools when releasing the library.
|
|
||||||
Fix segfault when getopt processes dmsetup -U, -G and -M options.
|
|
||||||
|
|
||||||
Version 1.02.31 - 3rd March 2009
|
|
||||||
================================
|
|
||||||
If kernel supports only one dm major number, use in place of any supplied.
|
|
||||||
|
|
||||||
Version 1.02.30 - 26th January 2009
|
|
||||||
====================================
|
|
||||||
Add "all" field to reports expanding to all fields of report type.
|
|
||||||
Enforce device name length and character limitations in libdm.
|
|
||||||
Replace _dm_snprintf with EMIT_PARAMS macro for creating target lines.
|
|
||||||
|
|
||||||
Version 1.02.29 - 10th November 2008
|
|
||||||
====================================
|
|
||||||
Merge device-mapper into the LVM2 tree.
|
|
||||||
Split out dm-logging.h from log.h.
|
|
||||||
Use lvm-types.h.
|
|
||||||
Add usrsbindir to configure.
|
Add usrsbindir to configure.
|
||||||
|
|
||||||
Version 1.02.28 - 18th September 2008
|
Version 1.02.28 - 18th September 2008
|
||||||
|
|||||||
63
acinclude.m4
63
acinclude.m4
@@ -1,63 +0,0 @@
|
|||||||
dnl AC_GCC_VERSION
|
|
||||||
dnl check for compiler version
|
|
||||||
dnl sets COMPILER_VERSION and GCC_VERSION
|
|
||||||
|
|
||||||
AC_DEFUN([AC_CC_VERSION],
|
|
||||||
[
|
|
||||||
AC_MSG_CHECKING([C compiler version])
|
|
||||||
COMPILER_VERSION=`$CC -v 2>&1 | grep version`
|
|
||||||
case "$COMPILER_VERSION" in
|
|
||||||
*gcc*)
|
|
||||||
dnl Ok, how to turn $3 into the real $3
|
|
||||||
GCC_VERSION=`echo $COMPILER_VERSION | \
|
|
||||||
sed -e 's/[[^ ]]*\ [[^ ]]*\ \([[^ ]]*\)\ .*/\1/'` ;;
|
|
||||||
*) GCC_VERSION=unknown ;;
|
|
||||||
esac
|
|
||||||
AC_MSG_RESULT($GCC_VERSION)
|
|
||||||
])
|
|
||||||
|
|
||||||
dnl AC_TRY_CCFLAG([CCFLAG], [VAR], [ACTION-IF-WORKS], [ACTION-IF-FAILS])
|
|
||||||
dnl check if $CC supports a given flag
|
|
||||||
|
|
||||||
AC_DEFUN([AC_TRY_CCFLAG],
|
|
||||||
[
|
|
||||||
AC_REQUIRE([AC_PROG_CC])
|
|
||||||
ac_save_CFLAGS=$CFLAGS
|
|
||||||
CFLAGS=$1
|
|
||||||
AC_CACHE_CHECK([whether $CC accepts $1 flag], [ac_cv_flag_$2],
|
|
||||||
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
|
|
||||||
[AS_VAR_SET([ac_cv_flag_$2], [yes])],
|
|
||||||
[AS_VAR_SET([ac_cv_flag_$2], [no])])])
|
|
||||||
CFLAGS=$ac_save_CFLAGS
|
|
||||||
$2=AS_VAR_GET([ac_cv_flag_$2])
|
|
||||||
if test "$2" = yes; then
|
|
||||||
ifelse([$3], [], [:], [$3])
|
|
||||||
else
|
|
||||||
ifelse([$4], [], [:], [$4])
|
|
||||||
fi
|
|
||||||
])
|
|
||||||
|
|
||||||
dnl AC_IF_YES([TEST-FOR-YES], [ACTION-IF-TRUE], [ACTION-IF-FALSE])
|
|
||||||
dnl AS_IF() abstraction, checks shell variable for 'yes'
|
|
||||||
AC_DEFUN([AC_IF_YES], [AS_IF([test $$1 = yes], [$2], [$3])])
|
|
||||||
|
|
||||||
dnl AC_TRY_LDFLAGS([LDFLAGS], [VAR], [ACTION-IF-WORKS], [ACTION-IF-FAILS])
|
|
||||||
dnl check if $CC supports given ld flags
|
|
||||||
|
|
||||||
AC_DEFUN([AC_TRY_LDFLAGS],
|
|
||||||
[
|
|
||||||
AC_REQUIRE([AC_PROG_CC])
|
|
||||||
ac_save_LDFLAGS=$LDFLAGS
|
|
||||||
LDFLAGS=$1
|
|
||||||
AC_CACHE_CHECK([whether $CC accepts $1 ld flags], [ac_cv_flag_$2],
|
|
||||||
[AC_LINK_IFELSE([AC_LANG_PROGRAM()],
|
|
||||||
[AS_VAR_SET([ac_cv_flag_$2], [yes])],
|
|
||||||
[AS_VAR_SET([ac_cv_flag_$2], [no])])])
|
|
||||||
LDFLAGS=$ac_save_LDFLAGS
|
|
||||||
$2=AS_VAR_GET([ac_cv_flag_$2])
|
|
||||||
if test "$2" = yes; then
|
|
||||||
ifelse([$3], [], [:], [$3])
|
|
||||||
else
|
|
||||||
ifelse([$4], [], [:], [$4])
|
|
||||||
fi
|
|
||||||
])
|
|
||||||
230
aclocal.m4
vendored
230
aclocal.m4
vendored
@@ -1,230 +0,0 @@
|
|||||||
# generated automatically by aclocal 1.15 -*- Autoconf -*-
|
|
||||||
|
|
||||||
# Copyright (C) 1996-2014 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
# This file is free software; the Free Software Foundation
|
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
|
||||||
# with or without modifications, as long as this notice is preserved.
|
|
||||||
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
|
||||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
|
||||||
# PARTICULAR PURPOSE.
|
|
||||||
|
|
||||||
m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
|
|
||||||
# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
|
|
||||||
# serial 1 (pkg-config-0.24)
|
|
||||||
#
|
|
||||||
# Copyright (c) 2004 Scott James Remnant <scott@netsplit.com>.
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation; either version 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful, but
|
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
# General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software
|
|
||||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
#
|
|
||||||
# As a special exception to the GNU General Public License, if you
|
|
||||||
# distribute this file as part of a program that contains a
|
|
||||||
# configuration script generated by Autoconf, you may include it under
|
|
||||||
# the same distribution terms that you use for the rest of that program.
|
|
||||||
|
|
||||||
# PKG_PROG_PKG_CONFIG([MIN-VERSION])
|
|
||||||
# ----------------------------------
|
|
||||||
AC_DEFUN([PKG_PROG_PKG_CONFIG],
|
|
||||||
[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
|
|
||||||
m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
|
|
||||||
m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])
|
|
||||||
AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
|
|
||||||
AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
|
|
||||||
AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])
|
|
||||||
|
|
||||||
if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
|
|
||||||
AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
|
|
||||||
fi
|
|
||||||
if test -n "$PKG_CONFIG"; then
|
|
||||||
_pkg_min_version=m4_default([$1], [0.9.0])
|
|
||||||
AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
|
|
||||||
if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
|
|
||||||
AC_MSG_RESULT([yes])
|
|
||||||
else
|
|
||||||
AC_MSG_RESULT([no])
|
|
||||||
PKG_CONFIG=""
|
|
||||||
fi
|
|
||||||
fi[]dnl
|
|
||||||
])# PKG_PROG_PKG_CONFIG
|
|
||||||
|
|
||||||
# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
|
|
||||||
#
|
|
||||||
# Check to see whether a particular set of modules exists. Similar
|
|
||||||
# to PKG_CHECK_MODULES(), but does not set variables or print errors.
|
|
||||||
#
|
|
||||||
# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
|
|
||||||
# only at the first occurence in configure.ac, so if the first place
|
|
||||||
# it's called might be skipped (such as if it is within an "if", you
|
|
||||||
# have to call PKG_CHECK_EXISTS manually
|
|
||||||
# --------------------------------------------------------------
|
|
||||||
AC_DEFUN([PKG_CHECK_EXISTS],
|
|
||||||
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
|
|
||||||
if test -n "$PKG_CONFIG" && \
|
|
||||||
AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
|
|
||||||
m4_default([$2], [:])
|
|
||||||
m4_ifvaln([$3], [else
|
|
||||||
$3])dnl
|
|
||||||
fi])
|
|
||||||
|
|
||||||
# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
|
|
||||||
# ---------------------------------------------
|
|
||||||
m4_define([_PKG_CONFIG],
|
|
||||||
[if test -n "$$1"; then
|
|
||||||
pkg_cv_[]$1="$$1"
|
|
||||||
elif test -n "$PKG_CONFIG"; then
|
|
||||||
PKG_CHECK_EXISTS([$3],
|
|
||||||
[pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`
|
|
||||||
test "x$?" != "x0" && pkg_failed=yes ],
|
|
||||||
[pkg_failed=yes])
|
|
||||||
else
|
|
||||||
pkg_failed=untried
|
|
||||||
fi[]dnl
|
|
||||||
])# _PKG_CONFIG
|
|
||||||
|
|
||||||
# _PKG_SHORT_ERRORS_SUPPORTED
|
|
||||||
# -----------------------------
|
|
||||||
AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
|
|
||||||
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
|
|
||||||
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
|
|
||||||
_pkg_short_errors_supported=yes
|
|
||||||
else
|
|
||||||
_pkg_short_errors_supported=no
|
|
||||||
fi[]dnl
|
|
||||||
])# _PKG_SHORT_ERRORS_SUPPORTED
|
|
||||||
|
|
||||||
|
|
||||||
# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
|
|
||||||
# [ACTION-IF-NOT-FOUND])
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# Note that if there is a possibility the first call to
|
|
||||||
# PKG_CHECK_MODULES might not happen, you should be sure to include an
|
|
||||||
# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# --------------------------------------------------------------
|
|
||||||
AC_DEFUN([PKG_CHECK_MODULES],
|
|
||||||
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
|
|
||||||
AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
|
|
||||||
AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
|
|
||||||
|
|
||||||
pkg_failed=no
|
|
||||||
AC_MSG_CHECKING([for $1])
|
|
||||||
|
|
||||||
_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
|
|
||||||
_PKG_CONFIG([$1][_LIBS], [libs], [$2])
|
|
||||||
|
|
||||||
m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
|
|
||||||
and $1[]_LIBS to avoid the need to call pkg-config.
|
|
||||||
See the pkg-config man page for more details.])
|
|
||||||
|
|
||||||
if test $pkg_failed = yes; then
|
|
||||||
AC_MSG_RESULT([no])
|
|
||||||
_PKG_SHORT_ERRORS_SUPPORTED
|
|
||||||
if test $_pkg_short_errors_supported = yes; then
|
|
||||||
$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
|
|
||||||
else
|
|
||||||
$1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
|
|
||||||
fi
|
|
||||||
# Put the nasty error message in config.log where it belongs
|
|
||||||
echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
|
|
||||||
|
|
||||||
m4_default([$4], [AC_MSG_ERROR(
|
|
||||||
[Package requirements ($2) were not met:
|
|
||||||
|
|
||||||
$$1_PKG_ERRORS
|
|
||||||
|
|
||||||
Consider adjusting the PKG_CONFIG_PATH environment variable if you
|
|
||||||
installed software in a non-standard prefix.
|
|
||||||
|
|
||||||
_PKG_TEXT])[]dnl
|
|
||||||
])
|
|
||||||
elif test $pkg_failed = untried; then
|
|
||||||
AC_MSG_RESULT([no])
|
|
||||||
m4_default([$4], [AC_MSG_FAILURE(
|
|
||||||
[The pkg-config script could not be found or is too old. Make sure it
|
|
||||||
is in your PATH or set the PKG_CONFIG environment variable to the full
|
|
||||||
path to pkg-config.
|
|
||||||
|
|
||||||
_PKG_TEXT
|
|
||||||
|
|
||||||
To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl
|
|
||||||
])
|
|
||||||
else
|
|
||||||
$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
|
|
||||||
$1[]_LIBS=$pkg_cv_[]$1[]_LIBS
|
|
||||||
AC_MSG_RESULT([yes])
|
|
||||||
$3
|
|
||||||
fi[]dnl
|
|
||||||
])# PKG_CHECK_MODULES
|
|
||||||
|
|
||||||
|
|
||||||
# PKG_INSTALLDIR(DIRECTORY)
|
|
||||||
# -------------------------
|
|
||||||
# Substitutes the variable pkgconfigdir as the location where a module
|
|
||||||
# should install pkg-config .pc files. By default the directory is
|
|
||||||
# $libdir/pkgconfig, but the default can be changed by passing
|
|
||||||
# DIRECTORY. The user can override through the --with-pkgconfigdir
|
|
||||||
# parameter.
|
|
||||||
AC_DEFUN([PKG_INSTALLDIR],
|
|
||||||
[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])])
|
|
||||||
m4_pushdef([pkg_description],
|
|
||||||
[pkg-config installation directory @<:@]pkg_default[@:>@])
|
|
||||||
AC_ARG_WITH([pkgconfigdir],
|
|
||||||
[AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],,
|
|
||||||
[with_pkgconfigdir=]pkg_default)
|
|
||||||
AC_SUBST([pkgconfigdir], [$with_pkgconfigdir])
|
|
||||||
m4_popdef([pkg_default])
|
|
||||||
m4_popdef([pkg_description])
|
|
||||||
]) dnl PKG_INSTALLDIR
|
|
||||||
|
|
||||||
|
|
||||||
# PKG_NOARCH_INSTALLDIR(DIRECTORY)
|
|
||||||
# -------------------------
|
|
||||||
# Substitutes the variable noarch_pkgconfigdir as the location where a
|
|
||||||
# module should install arch-independent pkg-config .pc files. By
|
|
||||||
# default the directory is $datadir/pkgconfig, but the default can be
|
|
||||||
# changed by passing DIRECTORY. The user can override through the
|
|
||||||
# --with-noarch-pkgconfigdir parameter.
|
|
||||||
AC_DEFUN([PKG_NOARCH_INSTALLDIR],
|
|
||||||
[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])])
|
|
||||||
m4_pushdef([pkg_description],
|
|
||||||
[pkg-config arch-independent installation directory @<:@]pkg_default[@:>@])
|
|
||||||
AC_ARG_WITH([noarch-pkgconfigdir],
|
|
||||||
[AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],,
|
|
||||||
[with_noarch_pkgconfigdir=]pkg_default)
|
|
||||||
AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir])
|
|
||||||
m4_popdef([pkg_default])
|
|
||||||
m4_popdef([pkg_description])
|
|
||||||
]) dnl PKG_NOARCH_INSTALLDIR
|
|
||||||
|
|
||||||
|
|
||||||
# PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
|
|
||||||
# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
|
|
||||||
# -------------------------------------------
|
|
||||||
# Retrieves the value of the pkg-config variable for the given module.
|
|
||||||
AC_DEFUN([PKG_CHECK_VAR],
|
|
||||||
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
|
|
||||||
AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl
|
|
||||||
|
|
||||||
_PKG_CONFIG([$1], [variable="][$3]["], [$2])
|
|
||||||
AS_VAR_COPY([$1], [pkg_cv_][$1])
|
|
||||||
|
|
||||||
AS_VAR_IF([$1], [""], [$5], [$4])dnl
|
|
||||||
])# PKG_CHECK_VAR
|
|
||||||
|
|
||||||
m4_include([acinclude.m4])
|
|
||||||
644
autoconf/config.guess
vendored
644
autoconf/config.guess
vendored
@@ -1,12 +1,14 @@
|
|||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
# Attempt to guess a canonical system name.
|
# Attempt to guess a canonical system name.
|
||||||
# Copyright 1992-2014 Free Software Foundation, Inc.
|
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||||
|
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
|
||||||
|
# Free Software Foundation, Inc.
|
||||||
|
|
||||||
timestamp='2014-01-01'
|
timestamp='2008-01-23'
|
||||||
|
|
||||||
# This file is free software; you can redistribute it and/or modify it
|
# This file is free software; you can redistribute it and/or modify it
|
||||||
# under the terms of the GNU General Public License as published by
|
# under the terms of the GNU General Public License as published by
|
||||||
# the Free Software Foundation; either version 3 of the License, or
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful, but
|
# This program is distributed in the hope that it will be useful, but
|
||||||
@@ -15,23 +17,27 @@ timestamp='2014-01-01'
|
|||||||
# General Public License for more details.
|
# General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program; if not, see <http://www.gnu.org/licenses/>.
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
|
||||||
|
# 02110-1301, USA.
|
||||||
#
|
#
|
||||||
# As a special exception to the GNU General Public License, if you
|
# As a special exception to the GNU General Public License, if you
|
||||||
# distribute this file as part of a program that contains a
|
# distribute this file as part of a program that contains a
|
||||||
# configuration script generated by Autoconf, you may include it under
|
# configuration script generated by Autoconf, you may include it under
|
||||||
# the same distribution terms that you use for the rest of that
|
# the same distribution terms that you use for the rest of that program.
|
||||||
# program. This Exception is an additional permission under section 7
|
|
||||||
# of the GNU General Public License, version 3 ("GPLv3").
|
|
||||||
#
|
|
||||||
# Originally written by Per Bothner.
|
|
||||||
#
|
|
||||||
# You can get the latest version of this script from:
|
|
||||||
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
|
|
||||||
#
|
|
||||||
# Please send patches with a ChangeLog entry to config-patches@gnu.org.
|
|
||||||
|
|
||||||
|
|
||||||
|
# Originally written by Per Bothner <per@bothner.com>.
|
||||||
|
# Please send patches to <config-patches@gnu.org>. Submit a context
|
||||||
|
# diff and a properly formatted ChangeLog entry.
|
||||||
|
#
|
||||||
|
# This script attempts to guess a canonical system name similar to
|
||||||
|
# config.sub. If it succeeds, it prints the system name on stdout, and
|
||||||
|
# exits with 0. Otherwise, it exits with 1.
|
||||||
|
#
|
||||||
|
# The plan is that this can be called by configure scripts if you
|
||||||
|
# don't specify an explicit build system type.
|
||||||
|
|
||||||
me=`echo "$0" | sed -e 's,.*/,,'`
|
me=`echo "$0" | sed -e 's,.*/,,'`
|
||||||
|
|
||||||
usage="\
|
usage="\
|
||||||
@@ -50,7 +56,8 @@ version="\
|
|||||||
GNU config.guess ($timestamp)
|
GNU config.guess ($timestamp)
|
||||||
|
|
||||||
Originally written by Per Bothner.
|
Originally written by Per Bothner.
|
||||||
Copyright 1992-2014 Free Software Foundation, Inc.
|
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
|
||||||
|
2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This is free software; see the source for copying conditions. There is NO
|
This is free software; see the source for copying conditions. There is NO
|
||||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||||
@@ -132,33 +139,12 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
|
|||||||
UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
|
UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
|
||||||
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
|
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
|
||||||
|
|
||||||
case "${UNAME_SYSTEM}" in
|
|
||||||
Linux|GNU|GNU/*)
|
|
||||||
# If the system lacks a compiler, then just pick glibc.
|
|
||||||
# We could probably try harder.
|
|
||||||
LIBC=gnu
|
|
||||||
|
|
||||||
eval $set_cc_for_build
|
|
||||||
cat <<-EOF > $dummy.c
|
|
||||||
#include <features.h>
|
|
||||||
#if defined(__UCLIBC__)
|
|
||||||
LIBC=uclibc
|
|
||||||
#elif defined(__dietlibc__)
|
|
||||||
LIBC=dietlibc
|
|
||||||
#else
|
|
||||||
LIBC=gnu
|
|
||||||
#endif
|
|
||||||
EOF
|
|
||||||
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# Note: order is significant - the case branches are not exclusive.
|
# Note: order is significant - the case branches are not exclusive.
|
||||||
|
|
||||||
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||||
*:NetBSD:*:*)
|
*:NetBSD:*:*)
|
||||||
# NetBSD (nbsd) targets should (where applicable) match one or
|
# NetBSD (nbsd) targets should (where applicable) match one or
|
||||||
# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
|
# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
|
||||||
# *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
|
# *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
|
||||||
# switched to ELF, *-*-netbsd* would select the old
|
# switched to ELF, *-*-netbsd* would select the old
|
||||||
# object file format. This provides both forward
|
# object file format. This provides both forward
|
||||||
@@ -184,7 +170,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
|||||||
arm*|i386|m68k|ns32k|sh3*|sparc|vax)
|
arm*|i386|m68k|ns32k|sh3*|sparc|vax)
|
||||||
eval $set_cc_for_build
|
eval $set_cc_for_build
|
||||||
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
|
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
|
||||||
| grep -q __ELF__
|
| grep __ELF__ >/dev/null
|
||||||
then
|
then
|
||||||
# Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
|
# Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
|
||||||
# Return netbsd for either. FIX?
|
# Return netbsd for either. FIX?
|
||||||
@@ -194,7 +180,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
|||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
os=netbsd
|
os=netbsd
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
# The OS release
|
# The OS release
|
||||||
@@ -215,10 +201,6 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
|||||||
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
|
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
|
||||||
echo "${machine}-${os}${release}"
|
echo "${machine}-${os}${release}"
|
||||||
exit ;;
|
exit ;;
|
||||||
*:Bitrig:*:*)
|
|
||||||
UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
|
|
||||||
echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
|
|
||||||
exit ;;
|
|
||||||
*:OpenBSD:*:*)
|
*:OpenBSD:*:*)
|
||||||
UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
|
UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
|
||||||
echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
|
echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
|
||||||
@@ -241,7 +223,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
|||||||
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
|
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
|
||||||
;;
|
;;
|
||||||
*5.*)
|
*5.*)
|
||||||
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
|
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
# According to Compaq, /usr/sbin/psrinfo has been available on
|
# According to Compaq, /usr/sbin/psrinfo has been available on
|
||||||
@@ -287,10 +269,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
|||||||
# A Xn.n version is an unreleased experimental baselevel.
|
# A Xn.n version is an unreleased experimental baselevel.
|
||||||
# 1.2 uses "1.2" for uname -r.
|
# 1.2 uses "1.2" for uname -r.
|
||||||
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
|
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
|
||||||
# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
|
exit ;;
|
||||||
exitcode=$?
|
|
||||||
trap '' 0
|
|
||||||
exit $exitcode ;;
|
|
||||||
Alpha\ *:Windows_NT*:*)
|
Alpha\ *:Windows_NT*:*)
|
||||||
# How do we know it's Interix rather than the generic POSIX subsystem?
|
# How do we know it's Interix rather than the generic POSIX subsystem?
|
||||||
# Should we change UNAME_MACHINE based on the output of uname instead
|
# Should we change UNAME_MACHINE based on the output of uname instead
|
||||||
@@ -316,12 +295,12 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
|||||||
echo s390-ibm-zvmoe
|
echo s390-ibm-zvmoe
|
||||||
exit ;;
|
exit ;;
|
||||||
*:OS400:*:*)
|
*:OS400:*:*)
|
||||||
echo powerpc-ibm-os400
|
echo powerpc-ibm-os400
|
||||||
exit ;;
|
exit ;;
|
||||||
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
|
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
|
||||||
echo arm-acorn-riscix${UNAME_RELEASE}
|
echo arm-acorn-riscix${UNAME_RELEASE}
|
||||||
exit ;;
|
exit ;;
|
||||||
arm*:riscos:*:*|arm*:RISCOS:*:*)
|
arm:riscos:*:*|arm:RISCOS:*:*)
|
||||||
echo arm-unknown-riscos
|
echo arm-unknown-riscos
|
||||||
exit ;;
|
exit ;;
|
||||||
SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
|
SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
|
||||||
@@ -345,33 +324,14 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
|||||||
case `/usr/bin/uname -p` in
|
case `/usr/bin/uname -p` in
|
||||||
sparc) echo sparc-icl-nx7; exit ;;
|
sparc) echo sparc-icl-nx7; exit ;;
|
||||||
esac ;;
|
esac ;;
|
||||||
s390x:SunOS:*:*)
|
|
||||||
echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
|
||||||
exit ;;
|
|
||||||
sun4H:SunOS:5.*:*)
|
sun4H:SunOS:5.*:*)
|
||||||
echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||||
exit ;;
|
exit ;;
|
||||||
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
|
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
|
||||||
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||||
exit ;;
|
exit ;;
|
||||||
i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
|
|
||||||
echo i386-pc-auroraux${UNAME_RELEASE}
|
|
||||||
exit ;;
|
|
||||||
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
|
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
|
||||||
eval $set_cc_for_build
|
echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||||
SUN_ARCH="i386"
|
|
||||||
# If there is a compiler, see if it is configured for 64-bit objects.
|
|
||||||
# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
|
|
||||||
# This test works for both compilers.
|
|
||||||
if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
|
|
||||||
if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
|
|
||||||
(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
|
|
||||||
grep IS_64BIT_ARCH >/dev/null
|
|
||||||
then
|
|
||||||
SUN_ARCH="x86_64"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
|
||||||
exit ;;
|
exit ;;
|
||||||
sun4*:SunOS:6*:*)
|
sun4*:SunOS:6*:*)
|
||||||
# According to config.sub, this is the proper way to canonicalize
|
# According to config.sub, this is the proper way to canonicalize
|
||||||
@@ -415,23 +375,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
|||||||
# MiNT. But MiNT is downward compatible to TOS, so this should
|
# MiNT. But MiNT is downward compatible to TOS, so this should
|
||||||
# be no problem.
|
# be no problem.
|
||||||
atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
|
atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
|
||||||
echo m68k-atari-mint${UNAME_RELEASE}
|
echo m68k-atari-mint${UNAME_RELEASE}
|
||||||
exit ;;
|
exit ;;
|
||||||
atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
|
atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
|
||||||
echo m68k-atari-mint${UNAME_RELEASE}
|
echo m68k-atari-mint${UNAME_RELEASE}
|
||||||
exit ;;
|
exit ;;
|
||||||
*falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
|
*falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
|
||||||
echo m68k-atari-mint${UNAME_RELEASE}
|
echo m68k-atari-mint${UNAME_RELEASE}
|
||||||
exit ;;
|
exit ;;
|
||||||
milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
|
milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
|
||||||
echo m68k-milan-mint${UNAME_RELEASE}
|
echo m68k-milan-mint${UNAME_RELEASE}
|
||||||
exit ;;
|
exit ;;
|
||||||
hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
|
hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
|
||||||
echo m68k-hades-mint${UNAME_RELEASE}
|
echo m68k-hades-mint${UNAME_RELEASE}
|
||||||
exit ;;
|
exit ;;
|
||||||
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
|
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
|
||||||
echo m68k-unknown-mint${UNAME_RELEASE}
|
echo m68k-unknown-mint${UNAME_RELEASE}
|
||||||
exit ;;
|
exit ;;
|
||||||
m68k:machten:*:*)
|
m68k:machten:*:*)
|
||||||
echo m68k-apple-machten${UNAME_RELEASE}
|
echo m68k-apple-machten${UNAME_RELEASE}
|
||||||
exit ;;
|
exit ;;
|
||||||
@@ -501,8 +461,8 @@ EOF
|
|||||||
echo m88k-motorola-sysv3
|
echo m88k-motorola-sysv3
|
||||||
exit ;;
|
exit ;;
|
||||||
AViiON:dgux:*:*)
|
AViiON:dgux:*:*)
|
||||||
# DG/UX returns AViiON for all architectures
|
# DG/UX returns AViiON for all architectures
|
||||||
UNAME_PROCESSOR=`/usr/bin/uname -p`
|
UNAME_PROCESSOR=`/usr/bin/uname -p`
|
||||||
if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
|
if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
|
||||||
then
|
then
|
||||||
if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
|
if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
|
||||||
@@ -515,7 +475,7 @@ EOF
|
|||||||
else
|
else
|
||||||
echo i586-dg-dgux${UNAME_RELEASE}
|
echo i586-dg-dgux${UNAME_RELEASE}
|
||||||
fi
|
fi
|
||||||
exit ;;
|
exit ;;
|
||||||
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
|
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
|
||||||
echo m88k-dolphin-sysv3
|
echo m88k-dolphin-sysv3
|
||||||
exit ;;
|
exit ;;
|
||||||
@@ -572,7 +532,7 @@ EOF
|
|||||||
echo rs6000-ibm-aix3.2
|
echo rs6000-ibm-aix3.2
|
||||||
fi
|
fi
|
||||||
exit ;;
|
exit ;;
|
||||||
*:AIX:*:[4567])
|
*:AIX:*:[456])
|
||||||
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
|
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
|
||||||
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
|
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
|
||||||
IBM_ARCH=rs6000
|
IBM_ARCH=rs6000
|
||||||
@@ -615,52 +575,52 @@ EOF
|
|||||||
9000/[678][0-9][0-9])
|
9000/[678][0-9][0-9])
|
||||||
if [ -x /usr/bin/getconf ]; then
|
if [ -x /usr/bin/getconf ]; then
|
||||||
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
|
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
|
||||||
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
|
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
|
||||||
case "${sc_cpu_version}" in
|
case "${sc_cpu_version}" in
|
||||||
523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
|
523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
|
||||||
528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
|
528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
|
||||||
532) # CPU_PA_RISC2_0
|
532) # CPU_PA_RISC2_0
|
||||||
case "${sc_kernel_bits}" in
|
case "${sc_kernel_bits}" in
|
||||||
32) HP_ARCH="hppa2.0n" ;;
|
32) HP_ARCH="hppa2.0n" ;;
|
||||||
64) HP_ARCH="hppa2.0w" ;;
|
64) HP_ARCH="hppa2.0w" ;;
|
||||||
'') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
|
'') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
|
||||||
esac ;;
|
esac ;;
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
if [ "${HP_ARCH}" = "" ]; then
|
if [ "${HP_ARCH}" = "" ]; then
|
||||||
eval $set_cc_for_build
|
eval $set_cc_for_build
|
||||||
sed 's/^ //' << EOF >$dummy.c
|
sed 's/^ //' << EOF >$dummy.c
|
||||||
|
|
||||||
#define _HPUX_SOURCE
|
#define _HPUX_SOURCE
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
int main ()
|
int main ()
|
||||||
{
|
{
|
||||||
#if defined(_SC_KERNEL_BITS)
|
#if defined(_SC_KERNEL_BITS)
|
||||||
long bits = sysconf(_SC_KERNEL_BITS);
|
long bits = sysconf(_SC_KERNEL_BITS);
|
||||||
#endif
|
#endif
|
||||||
long cpu = sysconf (_SC_CPU_VERSION);
|
long cpu = sysconf (_SC_CPU_VERSION);
|
||||||
|
|
||||||
switch (cpu)
|
switch (cpu)
|
||||||
{
|
{
|
||||||
case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
|
case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
|
||||||
case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
|
case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
|
||||||
case CPU_PA_RISC2_0:
|
case CPU_PA_RISC2_0:
|
||||||
#if defined(_SC_KERNEL_BITS)
|
#if defined(_SC_KERNEL_BITS)
|
||||||
switch (bits)
|
switch (bits)
|
||||||
{
|
{
|
||||||
case 64: puts ("hppa2.0w"); break;
|
case 64: puts ("hppa2.0w"); break;
|
||||||
case 32: puts ("hppa2.0n"); break;
|
case 32: puts ("hppa2.0n"); break;
|
||||||
default: puts ("hppa2.0"); break;
|
default: puts ("hppa2.0"); break;
|
||||||
} break;
|
} break;
|
||||||
#else /* !defined(_SC_KERNEL_BITS) */
|
#else /* !defined(_SC_KERNEL_BITS) */
|
||||||
puts ("hppa2.0"); break;
|
puts ("hppa2.0"); break;
|
||||||
#endif
|
#endif
|
||||||
default: puts ("hppa1.0"); break;
|
default: puts ("hppa1.0"); break;
|
||||||
}
|
}
|
||||||
exit (0);
|
exit (0);
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
(CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
|
(CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
|
||||||
test -z "$HP_ARCH" && HP_ARCH=hppa
|
test -z "$HP_ARCH" && HP_ARCH=hppa
|
||||||
@@ -680,7 +640,7 @@ EOF
|
|||||||
# => hppa64-hp-hpux11.23
|
# => hppa64-hp-hpux11.23
|
||||||
|
|
||||||
if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
|
if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
|
||||||
grep -q __LP64__
|
grep __LP64__ >/dev/null
|
||||||
then
|
then
|
||||||
HP_ARCH="hppa2.0w"
|
HP_ARCH="hppa2.0w"
|
||||||
else
|
else
|
||||||
@@ -751,22 +711,22 @@ EOF
|
|||||||
exit ;;
|
exit ;;
|
||||||
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
|
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
|
||||||
echo c1-convex-bsd
|
echo c1-convex-bsd
|
||||||
exit ;;
|
exit ;;
|
||||||
C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
|
C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
|
||||||
if getsysinfo -f scalar_acc
|
if getsysinfo -f scalar_acc
|
||||||
then echo c32-convex-bsd
|
then echo c32-convex-bsd
|
||||||
else echo c2-convex-bsd
|
else echo c2-convex-bsd
|
||||||
fi
|
fi
|
||||||
exit ;;
|
exit ;;
|
||||||
C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
|
C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
|
||||||
echo c34-convex-bsd
|
echo c34-convex-bsd
|
||||||
exit ;;
|
exit ;;
|
||||||
C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
|
C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
|
||||||
echo c38-convex-bsd
|
echo c38-convex-bsd
|
||||||
exit ;;
|
exit ;;
|
||||||
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
|
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
|
||||||
echo c4-convex-bsd
|
echo c4-convex-bsd
|
||||||
exit ;;
|
exit ;;
|
||||||
CRAY*Y-MP:*:*:*)
|
CRAY*Y-MP:*:*:*)
|
||||||
echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
|
echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
|
||||||
exit ;;
|
exit ;;
|
||||||
@@ -790,14 +750,14 @@ EOF
|
|||||||
exit ;;
|
exit ;;
|
||||||
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
|
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
|
||||||
FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
|
FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
|
||||||
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
|
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
|
||||||
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
|
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
|
||||||
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
|
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
|
||||||
exit ;;
|
exit ;;
|
||||||
5000:UNIX_System_V:4.*:*)
|
5000:UNIX_System_V:4.*:*)
|
||||||
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
|
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
|
||||||
FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
|
FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
|
||||||
echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
|
echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
|
||||||
exit ;;
|
exit ;;
|
||||||
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
|
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
|
||||||
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
|
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
|
||||||
@@ -809,39 +769,34 @@ EOF
|
|||||||
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
|
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
|
||||||
exit ;;
|
exit ;;
|
||||||
*:FreeBSD:*:*)
|
*:FreeBSD:*:*)
|
||||||
UNAME_PROCESSOR=`/usr/bin/uname -p`
|
case ${UNAME_MACHINE} in
|
||||||
case ${UNAME_PROCESSOR} in
|
pc98)
|
||||||
|
echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
|
||||||
amd64)
|
amd64)
|
||||||
echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
|
echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
|
||||||
*)
|
*)
|
||||||
echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
|
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
|
||||||
esac
|
esac
|
||||||
exit ;;
|
exit ;;
|
||||||
i*:CYGWIN*:*)
|
i*:CYGWIN*:*)
|
||||||
echo ${UNAME_MACHINE}-pc-cygwin
|
echo ${UNAME_MACHINE}-pc-cygwin
|
||||||
exit ;;
|
exit ;;
|
||||||
*:MINGW64*:*)
|
|
||||||
echo ${UNAME_MACHINE}-pc-mingw64
|
|
||||||
exit ;;
|
|
||||||
*:MINGW*:*)
|
*:MINGW*:*)
|
||||||
echo ${UNAME_MACHINE}-pc-mingw32
|
echo ${UNAME_MACHINE}-pc-mingw32
|
||||||
exit ;;
|
exit ;;
|
||||||
i*:MSYS*:*)
|
|
||||||
echo ${UNAME_MACHINE}-pc-msys
|
|
||||||
exit ;;
|
|
||||||
i*:windows32*:*)
|
i*:windows32*:*)
|
||||||
# uname -m includes "-pc" on this system.
|
# uname -m includes "-pc" on this system.
|
||||||
echo ${UNAME_MACHINE}-mingw32
|
echo ${UNAME_MACHINE}-mingw32
|
||||||
exit ;;
|
exit ;;
|
||||||
i*:PW*:*)
|
i*:PW*:*)
|
||||||
echo ${UNAME_MACHINE}-pc-pw32
|
echo ${UNAME_MACHINE}-pc-pw32
|
||||||
exit ;;
|
exit ;;
|
||||||
*:Interix*:*)
|
*:Interix*:[3456]*)
|
||||||
case ${UNAME_MACHINE} in
|
case ${UNAME_MACHINE} in
|
||||||
x86)
|
x86)
|
||||||
echo i586-pc-interix${UNAME_RELEASE}
|
echo i586-pc-interix${UNAME_RELEASE}
|
||||||
exit ;;
|
exit ;;
|
||||||
authenticamd | genuineintel | EM64T)
|
EM64T | authenticamd)
|
||||||
echo x86_64-unknown-interix${UNAME_RELEASE}
|
echo x86_64-unknown-interix${UNAME_RELEASE}
|
||||||
exit ;;
|
exit ;;
|
||||||
IA64)
|
IA64)
|
||||||
@@ -851,9 +806,6 @@ EOF
|
|||||||
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
|
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
|
||||||
echo i${UNAME_MACHINE}-pc-mks
|
echo i${UNAME_MACHINE}-pc-mks
|
||||||
exit ;;
|
exit ;;
|
||||||
8664:Windows_NT:*)
|
|
||||||
echo x86_64-pc-mks
|
|
||||||
exit ;;
|
|
||||||
i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
|
i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
|
||||||
# How do we know it's Interix rather than the generic POSIX subsystem?
|
# How do we know it's Interix rather than the generic POSIX subsystem?
|
||||||
# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
|
# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
|
||||||
@@ -874,21 +826,100 @@ EOF
|
|||||||
exit ;;
|
exit ;;
|
||||||
*:GNU:*:*)
|
*:GNU:*:*)
|
||||||
# the GNU system
|
# the GNU system
|
||||||
echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
|
echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
|
||||||
exit ;;
|
exit ;;
|
||||||
*:GNU/*:*:*)
|
*:GNU/*:*:*)
|
||||||
# other systems with GNU libc and userland
|
# other systems with GNU libc and userland
|
||||||
echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
|
echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
|
||||||
exit ;;
|
exit ;;
|
||||||
i*86:Minix:*:*)
|
i*86:Minix:*:*)
|
||||||
echo ${UNAME_MACHINE}-pc-minix
|
echo ${UNAME_MACHINE}-pc-minix
|
||||||
exit ;;
|
exit ;;
|
||||||
aarch64:Linux:*:*)
|
arm*:Linux:*:*)
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
eval $set_cc_for_build
|
||||||
|
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
|
||||||
|
| grep -q __ARM_EABI__
|
||||||
|
then
|
||||||
|
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||||
|
else
|
||||||
|
echo ${UNAME_MACHINE}-unknown-linux-gnueabi
|
||||||
|
fi
|
||||||
exit ;;
|
exit ;;
|
||||||
aarch64_be:Linux:*:*)
|
avr32*:Linux:*:*)
|
||||||
UNAME_MACHINE=aarch64_be
|
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
exit ;;
|
||||||
|
cris:Linux:*:*)
|
||||||
|
echo cris-axis-linux-gnu
|
||||||
|
exit ;;
|
||||||
|
crisv32:Linux:*:*)
|
||||||
|
echo crisv32-axis-linux-gnu
|
||||||
|
exit ;;
|
||||||
|
frv:Linux:*:*)
|
||||||
|
echo frv-unknown-linux-gnu
|
||||||
|
exit ;;
|
||||||
|
ia64:Linux:*:*)
|
||||||
|
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||||
|
exit ;;
|
||||||
|
m32r*:Linux:*:*)
|
||||||
|
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||||
|
exit ;;
|
||||||
|
m68*:Linux:*:*)
|
||||||
|
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||||
|
exit ;;
|
||||||
|
mips:Linux:*:*)
|
||||||
|
eval $set_cc_for_build
|
||||||
|
sed 's/^ //' << EOF >$dummy.c
|
||||||
|
#undef CPU
|
||||||
|
#undef mips
|
||||||
|
#undef mipsel
|
||||||
|
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
|
||||||
|
CPU=mipsel
|
||||||
|
#else
|
||||||
|
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
|
||||||
|
CPU=mips
|
||||||
|
#else
|
||||||
|
CPU=
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
EOF
|
||||||
|
eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
|
||||||
|
/^CPU/{
|
||||||
|
s: ::g
|
||||||
|
p
|
||||||
|
}'`"
|
||||||
|
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
|
||||||
|
;;
|
||||||
|
mips64:Linux:*:*)
|
||||||
|
eval $set_cc_for_build
|
||||||
|
sed 's/^ //' << EOF >$dummy.c
|
||||||
|
#undef CPU
|
||||||
|
#undef mips64
|
||||||
|
#undef mips64el
|
||||||
|
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
|
||||||
|
CPU=mips64el
|
||||||
|
#else
|
||||||
|
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
|
||||||
|
CPU=mips64
|
||||||
|
#else
|
||||||
|
CPU=
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
EOF
|
||||||
|
eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
|
||||||
|
/^CPU/{
|
||||||
|
s: ::g
|
||||||
|
p
|
||||||
|
}'`"
|
||||||
|
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
|
||||||
|
;;
|
||||||
|
or32:Linux:*:*)
|
||||||
|
echo or32-unknown-linux-gnu
|
||||||
|
exit ;;
|
||||||
|
ppc:Linux:*:*)
|
||||||
|
echo powerpc-unknown-linux-gnu
|
||||||
|
exit ;;
|
||||||
|
ppc64:Linux:*:*)
|
||||||
|
echo powerpc64-unknown-linux-gnu
|
||||||
exit ;;
|
exit ;;
|
||||||
alpha:Linux:*:*)
|
alpha:Linux:*:*)
|
||||||
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
|
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
|
||||||
@@ -899,132 +930,106 @@ EOF
|
|||||||
EV6) UNAME_MACHINE=alphaev6 ;;
|
EV6) UNAME_MACHINE=alphaev6 ;;
|
||||||
EV67) UNAME_MACHINE=alphaev67 ;;
|
EV67) UNAME_MACHINE=alphaev67 ;;
|
||||||
EV68*) UNAME_MACHINE=alphaev68 ;;
|
EV68*) UNAME_MACHINE=alphaev68 ;;
|
||||||
esac
|
esac
|
||||||
objdump --private-headers /bin/sh | grep -q ld.so.1
|
objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
|
||||||
if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
|
if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
|
||||||
exit ;;
|
|
||||||
arc:Linux:*:* | arceb:Linux:*:*)
|
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
|
||||||
exit ;;
|
|
||||||
arm*:Linux:*:*)
|
|
||||||
eval $set_cc_for_build
|
|
||||||
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
|
|
||||||
| grep -q __ARM_EABI__
|
|
||||||
then
|
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
|
||||||
else
|
|
||||||
if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
|
|
||||||
| grep -q __ARM_PCS_VFP
|
|
||||||
then
|
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
|
|
||||||
else
|
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
exit ;;
|
|
||||||
avr32*:Linux:*:*)
|
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
|
||||||
exit ;;
|
|
||||||
cris:Linux:*:*)
|
|
||||||
echo ${UNAME_MACHINE}-axis-linux-${LIBC}
|
|
||||||
exit ;;
|
|
||||||
crisv32:Linux:*:*)
|
|
||||||
echo ${UNAME_MACHINE}-axis-linux-${LIBC}
|
|
||||||
exit ;;
|
|
||||||
frv:Linux:*:*)
|
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
|
||||||
exit ;;
|
|
||||||
hexagon:Linux:*:*)
|
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
|
||||||
exit ;;
|
|
||||||
i*86:Linux:*:*)
|
|
||||||
echo ${UNAME_MACHINE}-pc-linux-${LIBC}
|
|
||||||
exit ;;
|
|
||||||
ia64:Linux:*:*)
|
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
|
||||||
exit ;;
|
|
||||||
m32r*:Linux:*:*)
|
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
|
||||||
exit ;;
|
|
||||||
m68*:Linux:*:*)
|
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
|
||||||
exit ;;
|
|
||||||
mips:Linux:*:* | mips64:Linux:*:*)
|
|
||||||
eval $set_cc_for_build
|
|
||||||
sed 's/^ //' << EOF >$dummy.c
|
|
||||||
#undef CPU
|
|
||||||
#undef ${UNAME_MACHINE}
|
|
||||||
#undef ${UNAME_MACHINE}el
|
|
||||||
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
|
|
||||||
CPU=${UNAME_MACHINE}el
|
|
||||||
#else
|
|
||||||
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
|
|
||||||
CPU=${UNAME_MACHINE}
|
|
||||||
#else
|
|
||||||
CPU=
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
EOF
|
|
||||||
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
|
|
||||||
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
|
|
||||||
;;
|
|
||||||
or1k:Linux:*:*)
|
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
|
||||||
exit ;;
|
|
||||||
or32:Linux:*:*)
|
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
|
||||||
exit ;;
|
|
||||||
padre:Linux:*:*)
|
|
||||||
echo sparc-unknown-linux-${LIBC}
|
|
||||||
exit ;;
|
|
||||||
parisc64:Linux:*:* | hppa64:Linux:*:*)
|
|
||||||
echo hppa64-unknown-linux-${LIBC}
|
|
||||||
exit ;;
|
exit ;;
|
||||||
parisc:Linux:*:* | hppa:Linux:*:*)
|
parisc:Linux:*:* | hppa:Linux:*:*)
|
||||||
# Look for CPU level
|
# Look for CPU level
|
||||||
case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
|
case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
|
||||||
PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
|
PA7*) echo hppa1.1-unknown-linux-gnu ;;
|
||||||
PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
|
PA8*) echo hppa2.0-unknown-linux-gnu ;;
|
||||||
*) echo hppa-unknown-linux-${LIBC} ;;
|
*) echo hppa-unknown-linux-gnu ;;
|
||||||
esac
|
esac
|
||||||
exit ;;
|
exit ;;
|
||||||
ppc64:Linux:*:*)
|
parisc64:Linux:*:* | hppa64:Linux:*:*)
|
||||||
echo powerpc64-unknown-linux-${LIBC}
|
echo hppa64-unknown-linux-gnu
|
||||||
exit ;;
|
|
||||||
ppc:Linux:*:*)
|
|
||||||
echo powerpc-unknown-linux-${LIBC}
|
|
||||||
exit ;;
|
|
||||||
ppc64le:Linux:*:*)
|
|
||||||
echo powerpc64le-unknown-linux-${LIBC}
|
|
||||||
exit ;;
|
|
||||||
ppcle:Linux:*:*)
|
|
||||||
echo powerpcle-unknown-linux-${LIBC}
|
|
||||||
exit ;;
|
exit ;;
|
||||||
s390:Linux:*:* | s390x:Linux:*:*)
|
s390:Linux:*:* | s390x:Linux:*:*)
|
||||||
echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
|
echo ${UNAME_MACHINE}-ibm-linux
|
||||||
exit ;;
|
exit ;;
|
||||||
sh64*:Linux:*:*)
|
sh64*:Linux:*:*)
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||||
exit ;;
|
exit ;;
|
||||||
sh*:Linux:*:*)
|
sh*:Linux:*:*)
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||||
exit ;;
|
exit ;;
|
||||||
sparc:Linux:*:* | sparc64:Linux:*:*)
|
sparc:Linux:*:* | sparc64:Linux:*:*)
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||||
exit ;;
|
|
||||||
tile*:Linux:*:*)
|
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
|
||||||
exit ;;
|
exit ;;
|
||||||
vax:Linux:*:*)
|
vax:Linux:*:*)
|
||||||
echo ${UNAME_MACHINE}-dec-linux-${LIBC}
|
echo ${UNAME_MACHINE}-dec-linux-gnu
|
||||||
exit ;;
|
exit ;;
|
||||||
x86_64:Linux:*:*)
|
x86_64:Linux:*:*)
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
echo x86_64-unknown-linux-gnu
|
||||||
exit ;;
|
exit ;;
|
||||||
xtensa*:Linux:*:*)
|
xtensa*:Linux:*:*)
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||||
exit ;;
|
exit ;;
|
||||||
|
i*86:Linux:*:*)
|
||||||
|
# The BFD linker knows what the default object file format is, so
|
||||||
|
# first see if it will tell us. cd to the root directory to prevent
|
||||||
|
# problems with other programs or directories called `ld' in the path.
|
||||||
|
# Set LC_ALL=C to ensure ld outputs messages in English.
|
||||||
|
ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
|
||||||
|
| sed -ne '/supported targets:/!d
|
||||||
|
s/[ ][ ]*/ /g
|
||||||
|
s/.*supported targets: *//
|
||||||
|
s/ .*//
|
||||||
|
p'`
|
||||||
|
case "$ld_supported_targets" in
|
||||||
|
elf32-i386)
|
||||||
|
TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
|
||||||
|
;;
|
||||||
|
a.out-i386-linux)
|
||||||
|
echo "${UNAME_MACHINE}-pc-linux-gnuaout"
|
||||||
|
exit ;;
|
||||||
|
coff-i386)
|
||||||
|
echo "${UNAME_MACHINE}-pc-linux-gnucoff"
|
||||||
|
exit ;;
|
||||||
|
"")
|
||||||
|
# Either a pre-BFD a.out linker (linux-gnuoldld) or
|
||||||
|
# one that does not give us useful --help.
|
||||||
|
echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
|
||||||
|
exit ;;
|
||||||
|
esac
|
||||||
|
# Determine whether the default compiler is a.out or elf
|
||||||
|
eval $set_cc_for_build
|
||||||
|
sed 's/^ //' << EOF >$dummy.c
|
||||||
|
#include <features.h>
|
||||||
|
#ifdef __ELF__
|
||||||
|
# ifdef __GLIBC__
|
||||||
|
# if __GLIBC__ >= 2
|
||||||
|
LIBC=gnu
|
||||||
|
# else
|
||||||
|
LIBC=gnulibc1
|
||||||
|
# endif
|
||||||
|
# else
|
||||||
|
LIBC=gnulibc1
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
#if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
|
||||||
|
LIBC=gnu
|
||||||
|
#else
|
||||||
|
LIBC=gnuaout
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifdef __dietlibc__
|
||||||
|
LIBC=dietlibc
|
||||||
|
#endif
|
||||||
|
EOF
|
||||||
|
eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
|
||||||
|
/^LIBC/{
|
||||||
|
s: ::g
|
||||||
|
p
|
||||||
|
}'`"
|
||||||
|
test x"${LIBC}" != x && {
|
||||||
|
echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
|
||||||
|
;;
|
||||||
i*86:DYNIX/ptx:4*:*)
|
i*86:DYNIX/ptx:4*:*)
|
||||||
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
|
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
|
||||||
# earlier versions are messed up and put the nodename in both
|
# earlier versions are messed up and put the nodename in both
|
||||||
@@ -1032,11 +1037,11 @@ EOF
|
|||||||
echo i386-sequent-sysv4
|
echo i386-sequent-sysv4
|
||||||
exit ;;
|
exit ;;
|
||||||
i*86:UNIX_SV:4.2MP:2.*)
|
i*86:UNIX_SV:4.2MP:2.*)
|
||||||
# Unixware is an offshoot of SVR4, but it has its own version
|
# Unixware is an offshoot of SVR4, but it has its own version
|
||||||
# number series starting with 2...
|
# number series starting with 2...
|
||||||
# I am not positive that other SVR4 systems won't match this,
|
# I am not positive that other SVR4 systems won't match this,
|
||||||
# I just have to hope. -- rms.
|
# I just have to hope. -- rms.
|
||||||
# Use sysv4.2uw... so that sysv4* matches it.
|
# Use sysv4.2uw... so that sysv4* matches it.
|
||||||
echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
|
echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
|
||||||
exit ;;
|
exit ;;
|
||||||
i*86:OS/2:*:*)
|
i*86:OS/2:*:*)
|
||||||
@@ -1053,7 +1058,7 @@ EOF
|
|||||||
i*86:syllable:*:*)
|
i*86:syllable:*:*)
|
||||||
echo ${UNAME_MACHINE}-pc-syllable
|
echo ${UNAME_MACHINE}-pc-syllable
|
||||||
exit ;;
|
exit ;;
|
||||||
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
|
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
|
||||||
echo i386-unknown-lynxos${UNAME_RELEASE}
|
echo i386-unknown-lynxos${UNAME_RELEASE}
|
||||||
exit ;;
|
exit ;;
|
||||||
i*86:*DOS:*:*)
|
i*86:*DOS:*:*)
|
||||||
@@ -1068,7 +1073,7 @@ EOF
|
|||||||
fi
|
fi
|
||||||
exit ;;
|
exit ;;
|
||||||
i*86:*:5:[678]*)
|
i*86:*:5:[678]*)
|
||||||
# UnixWare 7.x, OpenUNIX and OpenServer 6.
|
# UnixWare 7.x, OpenUNIX and OpenServer 6.
|
||||||
case `/bin/uname -X | grep "^Machine"` in
|
case `/bin/uname -X | grep "^Machine"` in
|
||||||
*486*) UNAME_MACHINE=i486 ;;
|
*486*) UNAME_MACHINE=i486 ;;
|
||||||
*Pentium) UNAME_MACHINE=i586 ;;
|
*Pentium) UNAME_MACHINE=i586 ;;
|
||||||
@@ -1096,13 +1101,10 @@ EOF
|
|||||||
exit ;;
|
exit ;;
|
||||||
pc:*:*:*)
|
pc:*:*:*)
|
||||||
# Left here for compatibility:
|
# Left here for compatibility:
|
||||||
# uname -m prints for DJGPP always 'pc', but it prints nothing about
|
# uname -m prints for DJGPP always 'pc', but it prints nothing about
|
||||||
# the processor, so we play safe by assuming i586.
|
# the processor, so we play safe by assuming i386.
|
||||||
# Note: whatever this is, it MUST be the same as what config.sub
|
echo i386-pc-msdosdjgpp
|
||||||
# prints for the "djgpp" host, or else GDB configury will decide that
|
exit ;;
|
||||||
# this is a cross-build.
|
|
||||||
echo i586-pc-msdosdjgpp
|
|
||||||
exit ;;
|
|
||||||
Intel:Mach:3*:*)
|
Intel:Mach:3*:*)
|
||||||
echo i386-pc-mach3
|
echo i386-pc-mach3
|
||||||
exit ;;
|
exit ;;
|
||||||
@@ -1137,18 +1139,8 @@ EOF
|
|||||||
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
|
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
|
||||||
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
|
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
|
||||||
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
|
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
|
||||||
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
|
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
|
||||||
&& { echo i486-ncr-sysv4; exit; } ;;
|
&& { echo i486-ncr-sysv4; exit; } ;;
|
||||||
NCR*:*:4.2:* | MPRAS*:*:4.2:*)
|
|
||||||
OS_REL='.3'
|
|
||||||
test -r /etc/.relid \
|
|
||||||
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
|
|
||||||
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
|
|
||||||
&& { echo i486-ncr-sysv4.3${OS_REL}; exit; }
|
|
||||||
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
|
|
||||||
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; }
|
|
||||||
/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
|
|
||||||
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
|
|
||||||
m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
|
m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
|
||||||
echo m68k-unknown-lynxos${UNAME_RELEASE}
|
echo m68k-unknown-lynxos${UNAME_RELEASE}
|
||||||
exit ;;
|
exit ;;
|
||||||
@@ -1161,7 +1153,7 @@ EOF
|
|||||||
rs6000:LynxOS:2.*:*)
|
rs6000:LynxOS:2.*:*)
|
||||||
echo rs6000-unknown-lynxos${UNAME_RELEASE}
|
echo rs6000-unknown-lynxos${UNAME_RELEASE}
|
||||||
exit ;;
|
exit ;;
|
||||||
PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
|
PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
|
||||||
echo powerpc-unknown-lynxos${UNAME_RELEASE}
|
echo powerpc-unknown-lynxos${UNAME_RELEASE}
|
||||||
exit ;;
|
exit ;;
|
||||||
SM[BE]S:UNIX_SV:*:*)
|
SM[BE]S:UNIX_SV:*:*)
|
||||||
@@ -1181,10 +1173,10 @@ EOF
|
|||||||
echo ns32k-sni-sysv
|
echo ns32k-sni-sysv
|
||||||
fi
|
fi
|
||||||
exit ;;
|
exit ;;
|
||||||
PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
|
PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
|
||||||
# says <Richard.M.Bartel@ccMail.Census.GOV>
|
# says <Richard.M.Bartel@ccMail.Census.GOV>
|
||||||
echo i586-unisys-sysv4
|
echo i586-unisys-sysv4
|
||||||
exit ;;
|
exit ;;
|
||||||
*:UNIX_System_V:4*:FTX*)
|
*:UNIX_System_V:4*:FTX*)
|
||||||
# From Gerald Hewes <hewes@openmarket.com>.
|
# From Gerald Hewes <hewes@openmarket.com>.
|
||||||
# How about differentiating between stratus architectures? -djm
|
# How about differentiating between stratus architectures? -djm
|
||||||
@@ -1210,11 +1202,11 @@ EOF
|
|||||||
exit ;;
|
exit ;;
|
||||||
R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
|
R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
|
||||||
if [ -d /usr/nec ]; then
|
if [ -d /usr/nec ]; then
|
||||||
echo mips-nec-sysv${UNAME_RELEASE}
|
echo mips-nec-sysv${UNAME_RELEASE}
|
||||||
else
|
else
|
||||||
echo mips-unknown-sysv${UNAME_RELEASE}
|
echo mips-unknown-sysv${UNAME_RELEASE}
|
||||||
fi
|
fi
|
||||||
exit ;;
|
exit ;;
|
||||||
BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
|
BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
|
||||||
echo powerpc-be-beos
|
echo powerpc-be-beos
|
||||||
exit ;;
|
exit ;;
|
||||||
@@ -1224,12 +1216,6 @@ EOF
|
|||||||
BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
|
BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
|
||||||
echo i586-pc-beos
|
echo i586-pc-beos
|
||||||
exit ;;
|
exit ;;
|
||||||
BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
|
|
||||||
echo i586-pc-haiku
|
|
||||||
exit ;;
|
|
||||||
x86_64:Haiku:*:*)
|
|
||||||
echo x86_64-unknown-haiku
|
|
||||||
exit ;;
|
|
||||||
SX-4:SUPER-UX:*:*)
|
SX-4:SUPER-UX:*:*)
|
||||||
echo sx4-nec-superux${UNAME_RELEASE}
|
echo sx4-nec-superux${UNAME_RELEASE}
|
||||||
exit ;;
|
exit ;;
|
||||||
@@ -1256,31 +1242,9 @@ EOF
|
|||||||
exit ;;
|
exit ;;
|
||||||
*:Darwin:*:*)
|
*:Darwin:*:*)
|
||||||
UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
|
UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
|
||||||
eval $set_cc_for_build
|
case $UNAME_PROCESSOR in
|
||||||
if test "$UNAME_PROCESSOR" = unknown ; then
|
unknown) UNAME_PROCESSOR=powerpc ;;
|
||||||
UNAME_PROCESSOR=powerpc
|
esac
|
||||||
fi
|
|
||||||
if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
|
|
||||||
if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
|
|
||||||
if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
|
|
||||||
(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
|
|
||||||
grep IS_64BIT_ARCH >/dev/null
|
|
||||||
then
|
|
||||||
case $UNAME_PROCESSOR in
|
|
||||||
i386) UNAME_PROCESSOR=x86_64 ;;
|
|
||||||
powerpc) UNAME_PROCESSOR=powerpc64 ;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
elif test "$UNAME_PROCESSOR" = i386 ; then
|
|
||||||
# Avoid executing cc on OS X 10.9, as it ships with a stub
|
|
||||||
# that puts up a graphical alert prompting to install
|
|
||||||
# developer tools. Any system running Mac OS X 10.7 or
|
|
||||||
# later (Darwin 11 and later) is required to have a 64-bit
|
|
||||||
# processor. This is not true of the ARM version of Darwin
|
|
||||||
# that Apple uses in portable devices.
|
|
||||||
UNAME_PROCESSOR=x86_64
|
|
||||||
fi
|
|
||||||
echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
|
echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
|
||||||
exit ;;
|
exit ;;
|
||||||
*:procnto*:*:* | *:QNX:[0123456789]*:*)
|
*:procnto*:*:* | *:QNX:[0123456789]*:*)
|
||||||
@@ -1294,10 +1258,7 @@ EOF
|
|||||||
*:QNX:*:4*)
|
*:QNX:*:4*)
|
||||||
echo i386-pc-qnx
|
echo i386-pc-qnx
|
||||||
exit ;;
|
exit ;;
|
||||||
NEO-?:NONSTOP_KERNEL:*:*)
|
NSE-?:NONSTOP_KERNEL:*:*)
|
||||||
echo neo-tandem-nsk${UNAME_RELEASE}
|
|
||||||
exit ;;
|
|
||||||
NSE-*:NONSTOP_KERNEL:*:*)
|
|
||||||
echo nse-tandem-nsk${UNAME_RELEASE}
|
echo nse-tandem-nsk${UNAME_RELEASE}
|
||||||
exit ;;
|
exit ;;
|
||||||
NSR-?:NONSTOP_KERNEL:*:*)
|
NSR-?:NONSTOP_KERNEL:*:*)
|
||||||
@@ -1342,13 +1303,13 @@ EOF
|
|||||||
echo pdp10-unknown-its
|
echo pdp10-unknown-its
|
||||||
exit ;;
|
exit ;;
|
||||||
SEI:*:*:SEIUX)
|
SEI:*:*:SEIUX)
|
||||||
echo mips-sei-seiux${UNAME_RELEASE}
|
echo mips-sei-seiux${UNAME_RELEASE}
|
||||||
exit ;;
|
exit ;;
|
||||||
*:DragonFly:*:*)
|
*:DragonFly:*:*)
|
||||||
echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
|
echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
|
||||||
exit ;;
|
exit ;;
|
||||||
*:*VMS:*:*)
|
*:*VMS:*:*)
|
||||||
UNAME_MACHINE=`(uname -p) 2>/dev/null`
|
UNAME_MACHINE=`(uname -p) 2>/dev/null`
|
||||||
case "${UNAME_MACHINE}" in
|
case "${UNAME_MACHINE}" in
|
||||||
A*) echo alpha-dec-vms ; exit ;;
|
A*) echo alpha-dec-vms ; exit ;;
|
||||||
I*) echo ia64-dec-vms ; exit ;;
|
I*) echo ia64-dec-vms ; exit ;;
|
||||||
@@ -1363,14 +1324,11 @@ EOF
|
|||||||
i*86:rdos:*:*)
|
i*86:rdos:*:*)
|
||||||
echo ${UNAME_MACHINE}-pc-rdos
|
echo ${UNAME_MACHINE}-pc-rdos
|
||||||
exit ;;
|
exit ;;
|
||||||
i*86:AROS:*:*)
|
|
||||||
echo ${UNAME_MACHINE}-pc-aros
|
|
||||||
exit ;;
|
|
||||||
x86_64:VMkernel:*:*)
|
|
||||||
echo ${UNAME_MACHINE}-unknown-esx
|
|
||||||
exit ;;
|
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
#echo '(No uname command or uname output not recognized.)' 1>&2
|
||||||
|
#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
|
||||||
|
|
||||||
eval $set_cc_for_build
|
eval $set_cc_for_build
|
||||||
cat >$dummy.c <<EOF
|
cat >$dummy.c <<EOF
|
||||||
#ifdef _SEQUENT_
|
#ifdef _SEQUENT_
|
||||||
@@ -1388,11 +1346,11 @@ main ()
|
|||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
printf ("m68k-sony-newsos%s\n",
|
printf ("m68k-sony-newsos%s\n",
|
||||||
#ifdef NEWSOS4
|
#ifdef NEWSOS4
|
||||||
"4"
|
"4"
|
||||||
#else
|
#else
|
||||||
""
|
""
|
||||||
#endif
|
#endif
|
||||||
); exit (0);
|
); exit (0);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
343
autoconf/config.sub
vendored
343
autoconf/config.sub
vendored
@@ -1,40 +1,44 @@
|
|||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
# Configuration validation subroutine script.
|
# Configuration validation subroutine script.
|
||||||
# Copyright 1992-2014 Free Software Foundation, Inc.
|
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||||
|
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
|
||||||
|
# Free Software Foundation, Inc.
|
||||||
|
|
||||||
timestamp='2014-01-01'
|
timestamp='2008-01-16'
|
||||||
|
|
||||||
# This file is free software; you can redistribute it and/or modify it
|
# This file is (in principle) common to ALL GNU software.
|
||||||
# under the terms of the GNU General Public License as published by
|
# The presence of a machine in this file suggests that SOME GNU software
|
||||||
# the Free Software Foundation; either version 3 of the License, or
|
# can handle that machine. It does not imply ALL GNU software can.
|
||||||
|
#
|
||||||
|
# This file is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful, but
|
# This program is distributed in the hope that it will be useful,
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program; if not, see <http://www.gnu.org/licenses/>.
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
|
||||||
|
# 02110-1301, USA.
|
||||||
#
|
#
|
||||||
# As a special exception to the GNU General Public License, if you
|
# As a special exception to the GNU General Public License, if you
|
||||||
# distribute this file as part of a program that contains a
|
# distribute this file as part of a program that contains a
|
||||||
# configuration script generated by Autoconf, you may include it under
|
# configuration script generated by Autoconf, you may include it under
|
||||||
# the same distribution terms that you use for the rest of that
|
# the same distribution terms that you use for the rest of that program.
|
||||||
# program. This Exception is an additional permission under section 7
|
|
||||||
# of the GNU General Public License, version 3 ("GPLv3").
|
|
||||||
|
|
||||||
|
|
||||||
# Please send patches with a ChangeLog entry to config-patches@gnu.org.
|
# Please send patches to <config-patches@gnu.org>. Submit a context
|
||||||
|
# diff and a properly formatted ChangeLog entry.
|
||||||
#
|
#
|
||||||
# Configuration subroutine to validate and canonicalize a configuration type.
|
# Configuration subroutine to validate and canonicalize a configuration type.
|
||||||
# Supply the specified configuration type as an argument.
|
# Supply the specified configuration type as an argument.
|
||||||
# If it is invalid, we print an error message on stderr and exit with code 1.
|
# If it is invalid, we print an error message on stderr and exit with code 1.
|
||||||
# Otherwise, we print the canonical config type on stdout and succeed.
|
# Otherwise, we print the canonical config type on stdout and succeed.
|
||||||
|
|
||||||
# You can get the latest version of this script from:
|
|
||||||
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
|
|
||||||
|
|
||||||
# This file is supposed to be the same for all GNU packages
|
# This file is supposed to be the same for all GNU packages
|
||||||
# and recognize all the CPU types, system types and aliases
|
# and recognize all the CPU types, system types and aliases
|
||||||
# that are meaningful with *any* GNU software.
|
# that are meaningful with *any* GNU software.
|
||||||
@@ -68,7 +72,8 @@ Report bugs and patches to <config-patches@gnu.org>."
|
|||||||
version="\
|
version="\
|
||||||
GNU config.sub ($timestamp)
|
GNU config.sub ($timestamp)
|
||||||
|
|
||||||
Copyright 1992-2014 Free Software Foundation, Inc.
|
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
|
||||||
|
2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This is free software; see the source for copying conditions. There is NO
|
This is free software; see the source for copying conditions. There is NO
|
||||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||||
@@ -115,18 +120,12 @@ esac
|
|||||||
# Here we must recognize all the valid KERNEL-OS combinations.
|
# Here we must recognize all the valid KERNEL-OS combinations.
|
||||||
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
|
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
|
||||||
case $maybe_os in
|
case $maybe_os in
|
||||||
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
|
nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
|
||||||
linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
|
uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
|
||||||
knetbsd*-gnu* | netbsd*-gnu* | \
|
|
||||||
kopensolaris*-gnu* | \
|
|
||||||
storm-chaos* | os2-emx* | rtmk-nova*)
|
storm-chaos* | os2-emx* | rtmk-nova*)
|
||||||
os=-$maybe_os
|
os=-$maybe_os
|
||||||
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
|
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
|
||||||
;;
|
;;
|
||||||
android-linux)
|
|
||||||
os=-linux-android
|
|
||||||
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
|
|
||||||
;;
|
|
||||||
*)
|
*)
|
||||||
basic_machine=`echo $1 | sed 's/-[^-]*$//'`
|
basic_machine=`echo $1 | sed 's/-[^-]*$//'`
|
||||||
if [ $basic_machine != $1 ]
|
if [ $basic_machine != $1 ]
|
||||||
@@ -149,13 +148,10 @@ case $os in
|
|||||||
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
|
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
|
||||||
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
|
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
|
||||||
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
|
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
|
||||||
-apple | -axis | -knuth | -cray | -microblaze*)
|
-apple | -axis | -knuth | -cray)
|
||||||
os=
|
os=
|
||||||
basic_machine=$1
|
basic_machine=$1
|
||||||
;;
|
;;
|
||||||
-bluegene*)
|
|
||||||
os=-cnk
|
|
||||||
;;
|
|
||||||
-sim | -cisco | -oki | -wec | -winbond)
|
-sim | -cisco | -oki | -wec | -winbond)
|
||||||
os=
|
os=
|
||||||
basic_machine=$1
|
basic_machine=$1
|
||||||
@@ -170,10 +166,10 @@ case $os in
|
|||||||
os=-chorusos
|
os=-chorusos
|
||||||
basic_machine=$1
|
basic_machine=$1
|
||||||
;;
|
;;
|
||||||
-chorusrdb)
|
-chorusrdb)
|
||||||
os=-chorusrdb
|
os=-chorusrdb
|
||||||
basic_machine=$1
|
basic_machine=$1
|
||||||
;;
|
;;
|
||||||
-hiux*)
|
-hiux*)
|
||||||
os=-hiuxwe2
|
os=-hiuxwe2
|
||||||
;;
|
;;
|
||||||
@@ -218,12 +214,6 @@ case $os in
|
|||||||
-isc*)
|
-isc*)
|
||||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||||
;;
|
;;
|
||||||
-lynx*178)
|
|
||||||
os=-lynxos178
|
|
||||||
;;
|
|
||||||
-lynx*5)
|
|
||||||
os=-lynxos5
|
|
||||||
;;
|
|
||||||
-lynx*)
|
-lynx*)
|
||||||
os=-lynxos
|
os=-lynxos
|
||||||
;;
|
;;
|
||||||
@@ -248,35 +238,24 @@ case $basic_machine in
|
|||||||
# Some are omitted here because they have special meanings below.
|
# Some are omitted here because they have special meanings below.
|
||||||
1750a | 580 \
|
1750a | 580 \
|
||||||
| a29k \
|
| a29k \
|
||||||
| aarch64 | aarch64_be \
|
|
||||||
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
|
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
|
||||||
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
|
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
|
||||||
| am33_2.0 \
|
| am33_2.0 \
|
||||||
| arc | arceb \
|
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
|
||||||
| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
|
|
||||||
| avr | avr32 \
|
|
||||||
| be32 | be64 \
|
|
||||||
| bfin \
|
| bfin \
|
||||||
| c4x | c8051 | clipper \
|
| c4x | clipper \
|
||||||
| d10v | d30v | dlx | dsp16xx \
|
| d10v | d30v | dlx | dsp16xx \
|
||||||
| epiphany \
|
|
||||||
| fido | fr30 | frv \
|
| fido | fr30 | frv \
|
||||||
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
|
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
|
||||||
| hexagon \
|
|
||||||
| i370 | i860 | i960 | ia64 \
|
| i370 | i860 | i960 | ia64 \
|
||||||
| ip2k | iq2000 \
|
| ip2k | iq2000 \
|
||||||
| k1om \
|
|
||||||
| le32 | le64 \
|
|
||||||
| lm32 \
|
|
||||||
| m32c | m32r | m32rle | m68000 | m68k | m88k \
|
| m32c | m32r | m32rle | m68000 | m68k | m88k \
|
||||||
| maxq | mb | microblaze | microblazeel | mcore | mep | metag \
|
| maxq | mb | microblaze | mcore | mep \
|
||||||
| mips | mipsbe | mipseb | mipsel | mipsle \
|
| mips | mipsbe | mipseb | mipsel | mipsle \
|
||||||
| mips16 \
|
| mips16 \
|
||||||
| mips64 | mips64el \
|
| mips64 | mips64el \
|
||||||
| mips64octeon | mips64octeonel \
|
|
||||||
| mips64orion | mips64orionel \
|
|
||||||
| mips64r5900 | mips64r5900el \
|
|
||||||
| mips64vr | mips64vrel \
|
| mips64vr | mips64vrel \
|
||||||
|
| mips64orion | mips64orionel \
|
||||||
| mips64vr4100 | mips64vr4100el \
|
| mips64vr4100 | mips64vr4100el \
|
||||||
| mips64vr4300 | mips64vr4300el \
|
| mips64vr4300 | mips64vr4300el \
|
||||||
| mips64vr5000 | mips64vr5000el \
|
| mips64vr5000 | mips64vr5000el \
|
||||||
@@ -287,45 +266,31 @@ case $basic_machine in
|
|||||||
| mipsisa64r2 | mipsisa64r2el \
|
| mipsisa64r2 | mipsisa64r2el \
|
||||||
| mipsisa64sb1 | mipsisa64sb1el \
|
| mipsisa64sb1 | mipsisa64sb1el \
|
||||||
| mipsisa64sr71k | mipsisa64sr71kel \
|
| mipsisa64sr71k | mipsisa64sr71kel \
|
||||||
| mipsr5900 | mipsr5900el \
|
|
||||||
| mipstx39 | mipstx39el \
|
| mipstx39 | mipstx39el \
|
||||||
| mn10200 | mn10300 \
|
| mn10200 | mn10300 \
|
||||||
| moxie \
|
|
||||||
| mt \
|
| mt \
|
||||||
| msp430 \
|
| msp430 \
|
||||||
| nds32 | nds32le | nds32be \
|
| nios | nios2 \
|
||||||
| nios | nios2 | nios2eb | nios2el \
|
|
||||||
| ns16k | ns32k \
|
| ns16k | ns32k \
|
||||||
| open8 \
|
| or32 \
|
||||||
| or1k | or32 \
|
|
||||||
| pdp10 | pdp11 | pj | pjl \
|
| pdp10 | pdp11 | pj | pjl \
|
||||||
| powerpc | powerpc64 | powerpc64le | powerpcle \
|
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
|
||||||
| pyramid \
|
| pyramid \
|
||||||
| rl78 | rx \
|
|
||||||
| score \
|
| score \
|
||||||
| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
|
| sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
|
||||||
| sh64 | sh64le \
|
| sh64 | sh64le \
|
||||||
| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
|
| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
|
||||||
| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
|
| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
|
||||||
| spu \
|
| spu | strongarm \
|
||||||
| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
|
| tahoe | thumb | tic4x | tic80 | tron \
|
||||||
| ubicom32 \
|
| v850 | v850e \
|
||||||
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
|
|
||||||
| we32k \
|
| we32k \
|
||||||
| x86 | xc16x | xstormy16 | xtensa \
|
| x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
|
||||||
| z8k | z80)
|
| z8k)
|
||||||
basic_machine=$basic_machine-unknown
|
basic_machine=$basic_machine-unknown
|
||||||
;;
|
;;
|
||||||
c54x)
|
m6811 | m68hc11 | m6812 | m68hc12)
|
||||||
basic_machine=tic54x-unknown
|
# Motorola 68HC11/12.
|
||||||
;;
|
|
||||||
c55x)
|
|
||||||
basic_machine=tic55x-unknown
|
|
||||||
;;
|
|
||||||
c6x)
|
|
||||||
basic_machine=tic6x-unknown
|
|
||||||
;;
|
|
||||||
m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
|
|
||||||
basic_machine=$basic_machine-unknown
|
basic_machine=$basic_machine-unknown
|
||||||
os=-none
|
os=-none
|
||||||
;;
|
;;
|
||||||
@@ -335,21 +300,6 @@ case $basic_machine in
|
|||||||
basic_machine=mt-unknown
|
basic_machine=mt-unknown
|
||||||
;;
|
;;
|
||||||
|
|
||||||
strongarm | thumb | xscale)
|
|
||||||
basic_machine=arm-unknown
|
|
||||||
;;
|
|
||||||
xgate)
|
|
||||||
basic_machine=$basic_machine-unknown
|
|
||||||
os=-none
|
|
||||||
;;
|
|
||||||
xscaleeb)
|
|
||||||
basic_machine=armeb-unknown
|
|
||||||
;;
|
|
||||||
|
|
||||||
xscaleel)
|
|
||||||
basic_machine=armel-unknown
|
|
||||||
;;
|
|
||||||
|
|
||||||
# We use `pc' rather than `unknown'
|
# We use `pc' rather than `unknown'
|
||||||
# because (1) that's what they normally are, and
|
# because (1) that's what they normally are, and
|
||||||
# (2) the word "unknown" tends to confuse beginning users.
|
# (2) the word "unknown" tends to confuse beginning users.
|
||||||
@@ -364,38 +314,29 @@ case $basic_machine in
|
|||||||
# Recognize the basic CPU types with company name.
|
# Recognize the basic CPU types with company name.
|
||||||
580-* \
|
580-* \
|
||||||
| a29k-* \
|
| a29k-* \
|
||||||
| aarch64-* | aarch64_be-* \
|
|
||||||
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
|
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
|
||||||
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
|
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
|
||||||
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
|
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
|
||||||
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
|
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
|
||||||
| avr-* | avr32-* \
|
| avr-* | avr32-* \
|
||||||
| be32-* | be64-* \
|
|
||||||
| bfin-* | bs2000-* \
|
| bfin-* | bs2000-* \
|
||||||
| c[123]* | c30-* | [cjt]90-* | c4x-* \
|
| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
|
||||||
| c8051-* | clipper-* | craynv-* | cydra-* \
|
| clipper-* | craynv-* | cydra-* \
|
||||||
| d10v-* | d30v-* | dlx-* \
|
| d10v-* | d30v-* | dlx-* \
|
||||||
| elxsi-* \
|
| elxsi-* \
|
||||||
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
|
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
|
||||||
| h8300-* | h8500-* \
|
| h8300-* | h8500-* \
|
||||||
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
|
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
|
||||||
| hexagon-* \
|
|
||||||
| i*86-* | i860-* | i960-* | ia64-* \
|
| i*86-* | i860-* | i960-* | ia64-* \
|
||||||
| ip2k-* | iq2000-* \
|
| ip2k-* | iq2000-* \
|
||||||
| k1om-* \
|
|
||||||
| le32-* | le64-* \
|
|
||||||
| lm32-* \
|
|
||||||
| m32c-* | m32r-* | m32rle-* \
|
| m32c-* | m32r-* | m32rle-* \
|
||||||
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
|
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
|
||||||
| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
|
| m88110-* | m88k-* | maxq-* | mcore-* \
|
||||||
| microblaze-* | microblazeel-* \
|
|
||||||
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
|
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
|
||||||
| mips16-* \
|
| mips16-* \
|
||||||
| mips64-* | mips64el-* \
|
| mips64-* | mips64el-* \
|
||||||
| mips64octeon-* | mips64octeonel-* \
|
|
||||||
| mips64orion-* | mips64orionel-* \
|
|
||||||
| mips64r5900-* | mips64r5900el-* \
|
|
||||||
| mips64vr-* | mips64vrel-* \
|
| mips64vr-* | mips64vrel-* \
|
||||||
|
| mips64orion-* | mips64orionel-* \
|
||||||
| mips64vr4100-* | mips64vr4100el-* \
|
| mips64vr4100-* | mips64vr4100el-* \
|
||||||
| mips64vr4300-* | mips64vr4300el-* \
|
| mips64vr4300-* | mips64vr4300el-* \
|
||||||
| mips64vr5000-* | mips64vr5000el-* \
|
| mips64vr5000-* | mips64vr5000el-* \
|
||||||
@@ -406,37 +347,31 @@ case $basic_machine in
|
|||||||
| mipsisa64r2-* | mipsisa64r2el-* \
|
| mipsisa64r2-* | mipsisa64r2el-* \
|
||||||
| mipsisa64sb1-* | mipsisa64sb1el-* \
|
| mipsisa64sb1-* | mipsisa64sb1el-* \
|
||||||
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
|
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
|
||||||
| mipsr5900-* | mipsr5900el-* \
|
|
||||||
| mipstx39-* | mipstx39el-* \
|
| mipstx39-* | mipstx39el-* \
|
||||||
| mmix-* \
|
| mmix-* \
|
||||||
| mt-* \
|
| mt-* \
|
||||||
| msp430-* \
|
| msp430-* \
|
||||||
| nds32-* | nds32le-* | nds32be-* \
|
| nios-* | nios2-* \
|
||||||
| nios-* | nios2-* | nios2eb-* | nios2el-* \
|
|
||||||
| none-* | np1-* | ns16k-* | ns32k-* \
|
| none-* | np1-* | ns16k-* | ns32k-* \
|
||||||
| open8-* \
|
|
||||||
| orion-* \
|
| orion-* \
|
||||||
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
|
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
|
||||||
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
|
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
|
||||||
| pyramid-* \
|
| pyramid-* \
|
||||||
| rl78-* | romp-* | rs6000-* | rx-* \
|
| romp-* | rs6000-* \
|
||||||
| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
|
| sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
|
||||||
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
|
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
|
||||||
| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
|
| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
|
||||||
| sparclite-* \
|
| sparclite-* \
|
||||||
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
|
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
|
||||||
| tahoe-* \
|
| tahoe-* | thumb-* \
|
||||||
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
|
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
|
||||||
| tile*-* \
|
|
||||||
| tron-* \
|
| tron-* \
|
||||||
| ubicom32-* \
|
| v850-* | v850e-* | vax-* \
|
||||||
| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
|
|
||||||
| vax-* \
|
|
||||||
| we32k-* \
|
| we32k-* \
|
||||||
| x86-* | x86_64-* | xc16x-* | xps100-* \
|
| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
|
||||||
| xstormy16-* | xtensa*-* \
|
| xstormy16-* | xtensa*-* \
|
||||||
| ymp-* \
|
| ymp-* \
|
||||||
| z8k-* | z80-*)
|
| z8k-*)
|
||||||
;;
|
;;
|
||||||
# Recognize the basic CPU types without company name, with glob match.
|
# Recognize the basic CPU types without company name, with glob match.
|
||||||
xtensa*)
|
xtensa*)
|
||||||
@@ -458,7 +393,7 @@ case $basic_machine in
|
|||||||
basic_machine=a29k-amd
|
basic_machine=a29k-amd
|
||||||
os=-udi
|
os=-udi
|
||||||
;;
|
;;
|
||||||
abacus)
|
abacus)
|
||||||
basic_machine=abacus-unknown
|
basic_machine=abacus-unknown
|
||||||
;;
|
;;
|
||||||
adobe68k)
|
adobe68k)
|
||||||
@@ -504,10 +439,6 @@ case $basic_machine in
|
|||||||
basic_machine=m68k-apollo
|
basic_machine=m68k-apollo
|
||||||
os=-bsd
|
os=-bsd
|
||||||
;;
|
;;
|
||||||
aros)
|
|
||||||
basic_machine=i386-pc
|
|
||||||
os=-aros
|
|
||||||
;;
|
|
||||||
aux)
|
aux)
|
||||||
basic_machine=m68k-apple
|
basic_machine=m68k-apple
|
||||||
os=-aux
|
os=-aux
|
||||||
@@ -524,27 +455,10 @@ case $basic_machine in
|
|||||||
basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
|
basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||||
os=-linux
|
os=-linux
|
||||||
;;
|
;;
|
||||||
bluegene*)
|
|
||||||
basic_machine=powerpc-ibm
|
|
||||||
os=-cnk
|
|
||||||
;;
|
|
||||||
c54x-*)
|
|
||||||
basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
|
|
||||||
;;
|
|
||||||
c55x-*)
|
|
||||||
basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
|
|
||||||
;;
|
|
||||||
c6x-*)
|
|
||||||
basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
|
|
||||||
;;
|
|
||||||
c90)
|
c90)
|
||||||
basic_machine=c90-cray
|
basic_machine=c90-cray
|
||||||
os=-unicos
|
os=-unicos
|
||||||
;;
|
;;
|
||||||
cegcc)
|
|
||||||
basic_machine=arm-unknown
|
|
||||||
os=-cegcc
|
|
||||||
;;
|
|
||||||
convex-c1)
|
convex-c1)
|
||||||
basic_machine=c1-convex
|
basic_machine=c1-convex
|
||||||
os=-bsd
|
os=-bsd
|
||||||
@@ -573,7 +487,7 @@ case $basic_machine in
|
|||||||
basic_machine=craynv-cray
|
basic_machine=craynv-cray
|
||||||
os=-unicosmp
|
os=-unicosmp
|
||||||
;;
|
;;
|
||||||
cr16 | cr16-*)
|
cr16)
|
||||||
basic_machine=cr16-unknown
|
basic_machine=cr16-unknown
|
||||||
os=-elf
|
os=-elf
|
||||||
;;
|
;;
|
||||||
@@ -612,10 +526,6 @@ case $basic_machine in
|
|||||||
basic_machine=m88k-motorola
|
basic_machine=m88k-motorola
|
||||||
os=-sysv3
|
os=-sysv3
|
||||||
;;
|
;;
|
||||||
dicos)
|
|
||||||
basic_machine=i686-pc
|
|
||||||
os=-dicos
|
|
||||||
;;
|
|
||||||
djgpp)
|
djgpp)
|
||||||
basic_machine=i586-pc
|
basic_machine=i586-pc
|
||||||
os=-msdosdjgpp
|
os=-msdosdjgpp
|
||||||
@@ -731,6 +641,7 @@ case $basic_machine in
|
|||||||
i370-ibm* | ibm*)
|
i370-ibm* | ibm*)
|
||||||
basic_machine=i370-ibm
|
basic_machine=i370-ibm
|
||||||
;;
|
;;
|
||||||
|
# I'm not sure what "Sysv32" means. Should this be sysv3.2?
|
||||||
i*86v32)
|
i*86v32)
|
||||||
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
|
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
|
||||||
os=-sysv32
|
os=-sysv32
|
||||||
@@ -788,15 +699,8 @@ case $basic_machine in
|
|||||||
basic_machine=ns32k-utek
|
basic_machine=ns32k-utek
|
||||||
os=-sysv
|
os=-sysv
|
||||||
;;
|
;;
|
||||||
microblaze*)
|
|
||||||
basic_machine=microblaze-xilinx
|
|
||||||
;;
|
|
||||||
mingw64)
|
|
||||||
basic_machine=x86_64-pc
|
|
||||||
os=-mingw64
|
|
||||||
;;
|
|
||||||
mingw32)
|
mingw32)
|
||||||
basic_machine=i686-pc
|
basic_machine=i386-pc
|
||||||
os=-mingw32
|
os=-mingw32
|
||||||
;;
|
;;
|
||||||
mingw32ce)
|
mingw32ce)
|
||||||
@@ -831,18 +735,10 @@ case $basic_machine in
|
|||||||
ms1-*)
|
ms1-*)
|
||||||
basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
|
basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
|
||||||
;;
|
;;
|
||||||
msys)
|
|
||||||
basic_machine=i686-pc
|
|
||||||
os=-msys
|
|
||||||
;;
|
|
||||||
mvs)
|
mvs)
|
||||||
basic_machine=i370-ibm
|
basic_machine=i370-ibm
|
||||||
os=-mvs
|
os=-mvs
|
||||||
;;
|
;;
|
||||||
nacl)
|
|
||||||
basic_machine=le32-unknown
|
|
||||||
os=-nacl
|
|
||||||
;;
|
|
||||||
ncr3000)
|
ncr3000)
|
||||||
basic_machine=i486-ncr
|
basic_machine=i486-ncr
|
||||||
os=-sysv4
|
os=-sysv4
|
||||||
@@ -907,12 +803,6 @@ case $basic_machine in
|
|||||||
np1)
|
np1)
|
||||||
basic_machine=np1-gould
|
basic_machine=np1-gould
|
||||||
;;
|
;;
|
||||||
neo-tandem)
|
|
||||||
basic_machine=neo-tandem
|
|
||||||
;;
|
|
||||||
nse-tandem)
|
|
||||||
basic_machine=nse-tandem
|
|
||||||
;;
|
|
||||||
nsr-tandem)
|
nsr-tandem)
|
||||||
basic_machine=nsr-tandem
|
basic_machine=nsr-tandem
|
||||||
;;
|
;;
|
||||||
@@ -995,10 +885,9 @@ case $basic_machine in
|
|||||||
;;
|
;;
|
||||||
power) basic_machine=power-ibm
|
power) basic_machine=power-ibm
|
||||||
;;
|
;;
|
||||||
ppc | ppcbe) basic_machine=powerpc-unknown
|
ppc) basic_machine=powerpc-unknown
|
||||||
;;
|
;;
|
||||||
ppc-* | ppcbe-*)
|
ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||||
basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
|
|
||||||
;;
|
;;
|
||||||
ppcle | powerpclittle | ppc-le | powerpc-little)
|
ppcle | powerpclittle | ppc-le | powerpc-little)
|
||||||
basic_machine=powerpcle-unknown
|
basic_machine=powerpcle-unknown
|
||||||
@@ -1023,11 +912,7 @@ case $basic_machine in
|
|||||||
basic_machine=i586-unknown
|
basic_machine=i586-unknown
|
||||||
os=-pw32
|
os=-pw32
|
||||||
;;
|
;;
|
||||||
rdos | rdos64)
|
rdos)
|
||||||
basic_machine=x86_64-pc
|
|
||||||
os=-rdos
|
|
||||||
;;
|
|
||||||
rdos32)
|
|
||||||
basic_machine=i386-pc
|
basic_machine=i386-pc
|
||||||
os=-rdos
|
os=-rdos
|
||||||
;;
|
;;
|
||||||
@@ -1096,9 +981,6 @@ case $basic_machine in
|
|||||||
basic_machine=i860-stratus
|
basic_machine=i860-stratus
|
||||||
os=-sysv4
|
os=-sysv4
|
||||||
;;
|
;;
|
||||||
strongarm-* | thumb-*)
|
|
||||||
basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
|
|
||||||
;;
|
|
||||||
sun2)
|
sun2)
|
||||||
basic_machine=m68000-sun
|
basic_machine=m68000-sun
|
||||||
;;
|
;;
|
||||||
@@ -1155,8 +1037,20 @@ case $basic_machine in
|
|||||||
basic_machine=t90-cray
|
basic_machine=t90-cray
|
||||||
os=-unicos
|
os=-unicos
|
||||||
;;
|
;;
|
||||||
|
tic54x | c54x*)
|
||||||
|
basic_machine=tic54x-unknown
|
||||||
|
os=-coff
|
||||||
|
;;
|
||||||
|
tic55x | c55x*)
|
||||||
|
basic_machine=tic55x-unknown
|
||||||
|
os=-coff
|
||||||
|
;;
|
||||||
|
tic6x | c6x*)
|
||||||
|
basic_machine=tic6x-unknown
|
||||||
|
os=-coff
|
||||||
|
;;
|
||||||
tile*)
|
tile*)
|
||||||
basic_machine=$basic_machine-unknown
|
basic_machine=tile-unknown
|
||||||
os=-linux-gnu
|
os=-linux-gnu
|
||||||
;;
|
;;
|
||||||
tx39)
|
tx39)
|
||||||
@@ -1226,9 +1120,6 @@ case $basic_machine in
|
|||||||
xps | xps100)
|
xps | xps100)
|
||||||
basic_machine=xps100-honeywell
|
basic_machine=xps100-honeywell
|
||||||
;;
|
;;
|
||||||
xscale-* | xscalee[bl]-*)
|
|
||||||
basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
|
|
||||||
;;
|
|
||||||
ymp)
|
ymp)
|
||||||
basic_machine=ymp-cray
|
basic_machine=ymp-cray
|
||||||
os=-unicos
|
os=-unicos
|
||||||
@@ -1237,10 +1128,6 @@ case $basic_machine in
|
|||||||
basic_machine=z8k-unknown
|
basic_machine=z8k-unknown
|
||||||
os=-sim
|
os=-sim
|
||||||
;;
|
;;
|
||||||
z80-*-coff)
|
|
||||||
basic_machine=z80-unknown
|
|
||||||
os=-sim
|
|
||||||
;;
|
|
||||||
none)
|
none)
|
||||||
basic_machine=none-none
|
basic_machine=none-none
|
||||||
os=-none
|
os=-none
|
||||||
@@ -1279,7 +1166,7 @@ case $basic_machine in
|
|||||||
we32k)
|
we32k)
|
||||||
basic_machine=we32k-att
|
basic_machine=we32k-att
|
||||||
;;
|
;;
|
||||||
sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
|
sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
|
||||||
basic_machine=sh-unknown
|
basic_machine=sh-unknown
|
||||||
;;
|
;;
|
||||||
sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
|
sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
|
||||||
@@ -1326,12 +1213,9 @@ esac
|
|||||||
if [ x"$os" != x"" ]
|
if [ x"$os" != x"" ]
|
||||||
then
|
then
|
||||||
case $os in
|
case $os in
|
||||||
# First match some system type aliases
|
# First match some system type aliases
|
||||||
# that might get confused with valid system types.
|
# that might get confused with valid system types.
|
||||||
# -solaris* is a basic system type, with this one exception.
|
# -solaris* is a basic system type, with this one exception.
|
||||||
-auroraux)
|
|
||||||
os=-auroraux
|
|
||||||
;;
|
|
||||||
-solaris1 | -solaris1.*)
|
-solaris1 | -solaris1.*)
|
||||||
os=`echo $os | sed -e 's|solaris1|sunos4|'`
|
os=`echo $os | sed -e 's|solaris1|sunos4|'`
|
||||||
;;
|
;;
|
||||||
@@ -1352,23 +1236,21 @@ case $os in
|
|||||||
# Each alternative MUST END IN A *, to match a version number.
|
# Each alternative MUST END IN A *, to match a version number.
|
||||||
# -sysv* is not here because it comes later, after sysvr4.
|
# -sysv* is not here because it comes later, after sysvr4.
|
||||||
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
|
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
|
||||||
| -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
|
| -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
|
||||||
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
|
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
|
||||||
| -sym* | -kopensolaris* | -plan9* \
|
|
||||||
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
|
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
|
||||||
| -aos* | -aros* \
|
| -aos* \
|
||||||
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
|
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
|
||||||
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
|
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
|
||||||
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
|
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
|
||||||
| -bitrig* | -openbsd* | -solidbsd* \
|
| -openbsd* | -solidbsd* \
|
||||||
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
|
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
|
||||||
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
|
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
|
||||||
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
|
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
|
||||||
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
|
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
|
||||||
| -chorusos* | -chorusrdb* | -cegcc* \
|
| -chorusos* | -chorusrdb* \
|
||||||
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
|
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
|
||||||
| -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
|
| -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
|
||||||
| -linux-newlib* | -linux-musl* | -linux-uclibc* \
|
|
||||||
| -uxpv* | -beos* | -mpeix* | -udk* \
|
| -uxpv* | -beos* | -mpeix* | -udk* \
|
||||||
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
|
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
|
||||||
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
|
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
|
||||||
@@ -1376,7 +1258,7 @@ case $os in
|
|||||||
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
|
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
|
||||||
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
|
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
|
||||||
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
|
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
|
||||||
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
|
| -skyos* | -haiku* | -rdos* | -toppers* | -drops*)
|
||||||
# Remember, each alternative MUST END IN *, to match a version number.
|
# Remember, each alternative MUST END IN *, to match a version number.
|
||||||
;;
|
;;
|
||||||
-qnx*)
|
-qnx*)
|
||||||
@@ -1415,7 +1297,7 @@ case $os in
|
|||||||
-opened*)
|
-opened*)
|
||||||
os=-openedition
|
os=-openedition
|
||||||
;;
|
;;
|
||||||
-os400*)
|
-os400*)
|
||||||
os=-os400
|
os=-os400
|
||||||
;;
|
;;
|
||||||
-wince*)
|
-wince*)
|
||||||
@@ -1464,7 +1346,7 @@ case $os in
|
|||||||
-sinix*)
|
-sinix*)
|
||||||
os=-sysv4
|
os=-sysv4
|
||||||
;;
|
;;
|
||||||
-tpf*)
|
-tpf*)
|
||||||
os=-tpf
|
os=-tpf
|
||||||
;;
|
;;
|
||||||
-triton*)
|
-triton*)
|
||||||
@@ -1500,14 +1382,12 @@ case $os in
|
|||||||
-aros*)
|
-aros*)
|
||||||
os=-aros
|
os=-aros
|
||||||
;;
|
;;
|
||||||
|
-kaos*)
|
||||||
|
os=-kaos
|
||||||
|
;;
|
||||||
-zvmoe)
|
-zvmoe)
|
||||||
os=-zvmoe
|
os=-zvmoe
|
||||||
;;
|
;;
|
||||||
-dicos*)
|
|
||||||
os=-dicos
|
|
||||||
;;
|
|
||||||
-nacl*)
|
|
||||||
;;
|
|
||||||
-none)
|
-none)
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
@@ -1530,10 +1410,10 @@ else
|
|||||||
# system, and we'll never get to this point.
|
# system, and we'll never get to this point.
|
||||||
|
|
||||||
case $basic_machine in
|
case $basic_machine in
|
||||||
score-*)
|
score-*)
|
||||||
os=-elf
|
os=-elf
|
||||||
;;
|
;;
|
||||||
spu-*)
|
spu-*)
|
||||||
os=-elf
|
os=-elf
|
||||||
;;
|
;;
|
||||||
*-acorn)
|
*-acorn)
|
||||||
@@ -1545,23 +1425,8 @@ case $basic_machine in
|
|||||||
arm*-semi)
|
arm*-semi)
|
||||||
os=-aout
|
os=-aout
|
||||||
;;
|
;;
|
||||||
c4x-* | tic4x-*)
|
c4x-* | tic4x-*)
|
||||||
os=-coff
|
os=-coff
|
||||||
;;
|
|
||||||
c8051-*)
|
|
||||||
os=-elf
|
|
||||||
;;
|
|
||||||
hexagon-*)
|
|
||||||
os=-elf
|
|
||||||
;;
|
|
||||||
tic54x-*)
|
|
||||||
os=-coff
|
|
||||||
;;
|
|
||||||
tic55x-*)
|
|
||||||
os=-coff
|
|
||||||
;;
|
|
||||||
tic6x-*)
|
|
||||||
os=-coff
|
|
||||||
;;
|
;;
|
||||||
# This must come before the *-dec entry.
|
# This must come before the *-dec entry.
|
||||||
pdp10-*)
|
pdp10-*)
|
||||||
@@ -1581,11 +1446,14 @@ case $basic_machine in
|
|||||||
;;
|
;;
|
||||||
m68000-sun)
|
m68000-sun)
|
||||||
os=-sunos3
|
os=-sunos3
|
||||||
|
# This also exists in the configure program, but was not the
|
||||||
|
# default.
|
||||||
|
# os=-sunos4
|
||||||
;;
|
;;
|
||||||
m68*-cisco)
|
m68*-cisco)
|
||||||
os=-aout
|
os=-aout
|
||||||
;;
|
;;
|
||||||
mep-*)
|
mep-*)
|
||||||
os=-elf
|
os=-elf
|
||||||
;;
|
;;
|
||||||
mips*-cisco)
|
mips*-cisco)
|
||||||
@@ -1594,9 +1462,6 @@ case $basic_machine in
|
|||||||
mips*-*)
|
mips*-*)
|
||||||
os=-elf
|
os=-elf
|
||||||
;;
|
;;
|
||||||
or1k-*)
|
|
||||||
os=-elf
|
|
||||||
;;
|
|
||||||
or32-*)
|
or32-*)
|
||||||
os=-coff
|
os=-coff
|
||||||
;;
|
;;
|
||||||
@@ -1615,7 +1480,7 @@ case $basic_machine in
|
|||||||
*-ibm)
|
*-ibm)
|
||||||
os=-aix
|
os=-aix
|
||||||
;;
|
;;
|
||||||
*-knuth)
|
*-knuth)
|
||||||
os=-mmixware
|
os=-mmixware
|
||||||
;;
|
;;
|
||||||
*-wec)
|
*-wec)
|
||||||
@@ -1720,7 +1585,7 @@ case $basic_machine in
|
|||||||
-sunos*)
|
-sunos*)
|
||||||
vendor=sun
|
vendor=sun
|
||||||
;;
|
;;
|
||||||
-cnk*|-aix*)
|
-aix*)
|
||||||
vendor=ibm
|
vendor=ibm
|
||||||
;;
|
;;
|
||||||
-beos*)
|
-beos*)
|
||||||
|
|||||||
6
conf/.gitignore
vendored
6
conf/.gitignore
vendored
@@ -1,6 +0,0 @@
|
|||||||
command_profile_template.profile
|
|
||||||
example.conf
|
|
||||||
lvmlocal.conf
|
|
||||||
metadata_profile_template.profile
|
|
||||||
configure.h
|
|
||||||
lvm-version.h
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
#
|
|
||||||
# Copyright (C) 2004-2015 Red Hat, Inc. All rights reserved.
|
|
||||||
#
|
|
||||||
# This file is part of LVM2.
|
|
||||||
#
|
|
||||||
# This copyrighted material is made available to anyone wishing to use,
|
|
||||||
# modify, copy, or redistribute it subject to the terms and conditions
|
|
||||||
# of the GNU General Public License v.2.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation,
|
|
||||||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
srcdir = @srcdir@
|
|
||||||
top_srcdir = @top_srcdir@
|
|
||||||
top_builddir = @top_builddir@
|
|
||||||
|
|
||||||
CONFSRC=example.conf
|
|
||||||
CONFDEST=lvm.conf
|
|
||||||
CONFLOCAL=lvmlocal.conf
|
|
||||||
|
|
||||||
PROFILE_TEMPLATES=command_profile_template.profile metadata_profile_template.profile
|
|
||||||
PROFILES=$(PROFILE_TEMPLATES) \
|
|
||||||
$(srcdir)/cache-mq.profile \
|
|
||||||
$(srcdir)/cache-smq.profile \
|
|
||||||
$(srcdir)/thin-generic.profile \
|
|
||||||
$(srcdir)/thin-performance.profile
|
|
||||||
|
|
||||||
include $(top_builddir)/make.tmpl
|
|
||||||
|
|
||||||
.PHONY: install_conf install_localconf install_profiles
|
|
||||||
|
|
||||||
generate:
|
|
||||||
(cat $(top_srcdir)/conf/example.conf.base && LD_LIBRARY_PATH=$(top_builddir)/libdm:$(LD_LIBRARY_PATH) $(top_builddir)/tools/lvm dumpconfig --type default --unconfigured --withcomments --ignorelocal --withspaces) > example.conf.in
|
|
||||||
(cat $(top_srcdir)/conf/lvmlocal.conf.base && LD_LIBRARY_PATH=$(top_builddir)/libdm:$(LD_LIBRARY_PATH) $(top_builddir)/tools/lvm dumpconfig --type default --unconfigured --withcomments --withspaces local) > lvmlocal.conf.in
|
|
||||||
|
|
||||||
install_conf: $(CONFSRC)
|
|
||||||
@if [ ! -e $(confdir)/$(CONFDEST) ]; then \
|
|
||||||
echo "$(INSTALL_WDATA) -D $< $(confdir)/$(CONFDEST)"; \
|
|
||||||
$(INSTALL_WDATA) -D $< $(confdir)/$(CONFDEST); \
|
|
||||||
fi
|
|
||||||
|
|
||||||
install_localconf: $(CONFLOCAL)
|
|
||||||
@if [ ! -e $(confdir)/$(CONFLOCAL) ]; then \
|
|
||||||
echo "$(INSTALL_WDATA) -D $< $(confdir)/$(CONFLOCAL)"; \
|
|
||||||
$(INSTALL_WDATA) -D $< $(confdir)/$(CONFLOCAL); \
|
|
||||||
fi
|
|
||||||
|
|
||||||
install_profiles: $(PROFILES)
|
|
||||||
$(INSTALL_DIR) $(DESTDIR)$(DEFAULT_PROFILE_DIR)
|
|
||||||
$(INSTALL_DATA) $(PROFILES) $(DESTDIR)$(DEFAULT_PROFILE_DIR)/
|
|
||||||
|
|
||||||
install_lvm2: install_conf install_localconf install_profiles
|
|
||||||
|
|
||||||
install: install_lvm2
|
|
||||||
|
|
||||||
DISTCLEAN_TARGETS += $(CONFSRC) $(CONFLOCAL) $(PROFILE_TEMPLATES)
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
# Demo configuration 'mq' cache policy
|
|
||||||
#
|
|
||||||
# Note: This policy has been deprecated in favor of the smq policy
|
|
||||||
# keyword "default" means, setting is left with kernel defaults.
|
|
||||||
#
|
|
||||||
|
|
||||||
allocation {
|
|
||||||
cache_pool_chunk_size = 64
|
|
||||||
cache_mode = "writethrough"
|
|
||||||
cache_policy = "mq"
|
|
||||||
cache_settings {
|
|
||||||
mq {
|
|
||||||
sequential_threshold = "default" # #nr_sequential_ios
|
|
||||||
random_threshold = "default" # #nr_random_ios
|
|
||||||
read_promote_adjustment = "default"
|
|
||||||
write_promote_adjustment = "default"
|
|
||||||
discard_promote_adjustment = "default"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
# Demo configuration 'smq' cache policy
|
|
||||||
#
|
|
||||||
# The stochastic multi-queue (smq) policy addresses some of the problems
|
|
||||||
# with the multiqueue (mq) policy and uses less memory.
|
|
||||||
#
|
|
||||||
|
|
||||||
allocation {
|
|
||||||
cache_pool_chunk_size = 64
|
|
||||||
cache_mode = "writethrough"
|
|
||||||
cache_policy = "smq"
|
|
||||||
cache_settings {
|
|
||||||
# currently no settins for "smq" policy
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
# This is a command profile template for the LVM2 system.
|
|
||||||
#
|
|
||||||
# It contains all configuration settings that are customizable by command
|
|
||||||
# profiles. To create a new command profile, select the settings you want
|
|
||||||
# to customize and add them in a new file named <profile_name>.profile.
|
|
||||||
# Then install the new profile in a directory as defined by config/profile_dir
|
|
||||||
# setting found in @DEFAULT_SYS_DIR@/lvm.conf file.
|
|
||||||
#
|
|
||||||
# Command profiles can be referenced by using the --commandprofile option then.
|
|
||||||
#
|
|
||||||
# Refer to 'man lvm.conf' for further information about profiles and
|
|
||||||
# general configuration file layout.
|
|
||||||
#
|
|
||||||
global {
|
|
||||||
units="h"
|
|
||||||
si_unit_consistency=1
|
|
||||||
suffix=1
|
|
||||||
lvdisplay_shows_full_device_path=0
|
|
||||||
}
|
|
||||||
report {
|
|
||||||
compact_output=0
|
|
||||||
aligned=1
|
|
||||||
buffered=1
|
|
||||||
headings=1
|
|
||||||
separator=" "
|
|
||||||
list_item_separator=","
|
|
||||||
prefixes=0
|
|
||||||
quoted=1
|
|
||||||
colums_as_rows=0
|
|
||||||
binary_values_as_numeric=0
|
|
||||||
devtypes_sort="devtype_name"
|
|
||||||
devtypes_cols="devtype_name,devtype_max_partitions,devtype_description"
|
|
||||||
devtypes_cols_verbose="devtype_name,devtype_max_partitions,devtype_description"
|
|
||||||
lvs_sort="vg_name,lv_name"
|
|
||||||
lvs_cols="lv_name,vg_name,lv_attr,lv_size,pool_lv,origin,data_percent,metadata_percent,move_pv,mirror_log,copy_percent,convert_lv"
|
|
||||||
lvs_cols_verbose="lv_name,vg_name,seg_count,lv_attr,lv_size,lv_major,lv_minor,lv_kernel_major,lv_kernel_minor,pool_lv,origin,data_percent,metadata_percent,move_pv,copy_percent,mirror_log,convert_lv,lv_uuid,lv_profile"
|
|
||||||
vgs_sort="vg_name"
|
|
||||||
vgs_cols="vg_name,pv_count,lv_count,snap_count,vg_attr,vg_size,vg_free"
|
|
||||||
vgs_cols_verbose="vg_name,vg_attr,vg_extent_size,pv_count,lv_count,snap_count,vg_size,vg_free,vg_uuid,vg_profile"
|
|
||||||
pvs_sort="pv_name"
|
|
||||||
pvs_cols="pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free"
|
|
||||||
pvs_cols_verbose="pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,dev_size,pv_uuid"
|
|
||||||
segs_sort="vg_name,lv_name,seg_start"
|
|
||||||
segs_cols="lv_name,vg_name,lv_attr,stripes,segtype,seg_size"
|
|
||||||
segs_cols_verbose="lv_name,vg_name,lv_attr,seg_start,seg_size,stripes,segtype,stripesize,chunksize"
|
|
||||||
pvsegs_sort="pv_name,pvseg_start"
|
|
||||||
pvsegs_cols="pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,pvseg_start,pvseg_size"
|
|
||||||
pvsegs_cols_verbose="pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,pvseg_start,pvseg_size,lv_name,seg_start_pe,segtype,seg_pe_ranges"
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
# This is an example configuration file for the LVM2 system.
|
|
||||||
# It contains the default settings that would be used if there was no
|
|
||||||
# @DEFAULT_SYS_DIR@/lvm.conf file.
|
|
||||||
#
|
|
||||||
# Refer to 'man lvm.conf' for further information including the file layout.
|
|
||||||
#
|
|
||||||
# Refer to 'man lvm.conf' for information about how settings configured in
|
|
||||||
# this file are combined with built-in values and command line options to
|
|
||||||
# arrive at the final values used by LVM.
|
|
||||||
#
|
|
||||||
# Refer to 'man lvmconfig' for information about displaying the built-in
|
|
||||||
# and configured values used by LVM.
|
|
||||||
#
|
|
||||||
# If a default value is set in this file (not commented out), then a
|
|
||||||
# new version of LVM using this file will continue using that value,
|
|
||||||
# even if the new version of LVM changes the built-in default value.
|
|
||||||
#
|
|
||||||
# To put this file in a different directory and override @DEFAULT_SYS_DIR@ set
|
|
||||||
# the environment variable LVM_SYSTEM_DIR before running the tools.
|
|
||||||
#
|
|
||||||
# N.B. Take care that each setting only appears once if uncommenting
|
|
||||||
# example settings in this file.
|
|
||||||
|
|
||||||
1887
conf/example.conf.in
1887
conf/example.conf.in
File diff suppressed because it is too large
Load Diff
@@ -1,19 +0,0 @@
|
|||||||
# This is a local configuration file template for the LVM2 system
|
|
||||||
# which should be installed as @DEFAULT_SYS_DIR@/lvmlocal.conf .
|
|
||||||
#
|
|
||||||
# Refer to 'man lvm.conf' for information about the file layout.
|
|
||||||
#
|
|
||||||
# To put this file in a different directory and override
|
|
||||||
# @DEFAULT_SYS_DIR@ set the environment variable LVM_SYSTEM_DIR before
|
|
||||||
# running the tools.
|
|
||||||
#
|
|
||||||
# The lvmlocal.conf file is normally expected to contain only the
|
|
||||||
# "local" section which contains settings that should not be shared or
|
|
||||||
# repeated among different hosts. (But if other sections are present,
|
|
||||||
# they *will* get processed. Settings in this file override equivalent
|
|
||||||
# ones in lvm.conf and are in turn overridden by ones in any enabled
|
|
||||||
# lvm_<tag>.conf files.)
|
|
||||||
#
|
|
||||||
# Please take care that each setting only appears once if uncommenting
|
|
||||||
# example settings in this file and never copy this file between hosts.
|
|
||||||
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
# This is a local configuration file template for the LVM2 system
|
|
||||||
# which should be installed as @DEFAULT_SYS_DIR@/lvmlocal.conf .
|
|
||||||
#
|
|
||||||
# Refer to 'man lvm.conf' for information about the file layout.
|
|
||||||
#
|
|
||||||
# To put this file in a different directory and override
|
|
||||||
# @DEFAULT_SYS_DIR@ set the environment variable LVM_SYSTEM_DIR before
|
|
||||||
# running the tools.
|
|
||||||
#
|
|
||||||
# The lvmlocal.conf file is normally expected to contain only the
|
|
||||||
# "local" section which contains settings that should not be shared or
|
|
||||||
# repeated among different hosts. (But if other sections are present,
|
|
||||||
# they *will* get processed. Settings in this file override equivalent
|
|
||||||
# ones in lvm.conf and are in turn overridden by ones in any enabled
|
|
||||||
# lvm_<tag>.conf files.)
|
|
||||||
#
|
|
||||||
# Please take care that each setting only appears once if uncommenting
|
|
||||||
# example settings in this file and never copy this file between hosts.
|
|
||||||
|
|
||||||
|
|
||||||
# Configuration section local.
|
|
||||||
# LVM settings that are specific to the local host.
|
|
||||||
local {
|
|
||||||
|
|
||||||
# Configuration option local/system_id.
|
|
||||||
# Defines the local system ID for lvmlocal mode.
|
|
||||||
# This is used when global/system_id_source is set to 'lvmlocal' in the
|
|
||||||
# main configuration file, e.g. lvm.conf. When used, it must be set to
|
|
||||||
# a unique value among all hosts sharing access to the storage,
|
|
||||||
# e.g. a host name.
|
|
||||||
#
|
|
||||||
# Example
|
|
||||||
# Set no system ID:
|
|
||||||
# system_id = ""
|
|
||||||
# Set the system_id to a specific name:
|
|
||||||
# system_id = "host1"
|
|
||||||
#
|
|
||||||
# This configuration option has an automatic default value.
|
|
||||||
# system_id = ""
|
|
||||||
|
|
||||||
# Configuration option local/extra_system_ids.
|
|
||||||
# A list of extra VG system IDs the local host can access.
|
|
||||||
# VGs with the system IDs listed here (in addition to the host's own
|
|
||||||
# system ID) can be fully accessed by the local host. (These are
|
|
||||||
# system IDs that the host sees in VGs, not system IDs that identify
|
|
||||||
# the local host, which is determined by system_id_source.)
|
|
||||||
# Use this only after consulting 'man lvmsystemid' to be certain of
|
|
||||||
# correct usage and possible dangers.
|
|
||||||
# This configuration option does not have a default value defined.
|
|
||||||
|
|
||||||
# Configuration option local/host_id.
|
|
||||||
# The lvmlockd sanlock host_id.
|
|
||||||
# This must be unique among all hosts, and must be between 1 and 2000.
|
|
||||||
# This configuration option has an automatic default value.
|
|
||||||
# host_id = 0
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
# This is a metadata profile template for the LVM2 system.
|
|
||||||
#
|
|
||||||
# It contains all configuration settings that are customizable by metadata
|
|
||||||
# profiles. To create a new metadata profile, select the settings you want
|
|
||||||
# to customize and add them in a new file named <profile_name>.profile.
|
|
||||||
# Then install the new profile in a directory as defined by config/profile_dir
|
|
||||||
# setting found in @DEFAULT_SYS_DIR@/lvm.conf file.
|
|
||||||
#
|
|
||||||
# Metadata profiles can be referenced by using the --metadataprofile LVM2
|
|
||||||
# command line option.
|
|
||||||
#
|
|
||||||
# Refer to 'man lvm.conf' for further information about profiles and
|
|
||||||
# general configuration file layout.
|
|
||||||
#
|
|
||||||
allocation {
|
|
||||||
thin_pool_zero=1
|
|
||||||
thin_pool_discards="passdown"
|
|
||||||
thin_pool_chunk_size_policy="generic"
|
|
||||||
# thin_pool_chunk_size=128
|
|
||||||
}
|
|
||||||
activation {
|
|
||||||
thin_pool_autoextend_threshold=100
|
|
||||||
thin_pool_autoextend_percent=20
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
allocation {
|
|
||||||
thin_pool_chunk_size_policy = "generic"
|
|
||||||
thin_pool_zero = 1
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
allocation {
|
|
||||||
thin_pool_chunk_size_policy = "performance"
|
|
||||||
thin_pool_zero = 0
|
|
||||||
}
|
|
||||||
2080
configure.in
2080
configure.in
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# Copyright (C) 2004-2015 Red Hat, Inc. All rights reserved.
|
# Copyright (C) 2004 Red Hat, Inc. All rights reserved.
|
||||||
#
|
#
|
||||||
# This file is part of LVM2.
|
# This file is part of LVM2.
|
||||||
#
|
#
|
||||||
@@ -13,43 +13,11 @@
|
|||||||
|
|
||||||
srcdir = @srcdir@
|
srcdir = @srcdir@
|
||||||
top_srcdir = @top_srcdir@
|
top_srcdir = @top_srcdir@
|
||||||
top_builddir = @top_builddir@
|
VPATH = @srcdir@
|
||||||
|
|
||||||
.PHONY: dmeventd clvmd cmirrord lvmetad lvmpolld lvmlockd
|
|
||||||
|
|
||||||
ifneq ("@CLVMD@", "none")
|
ifneq ("@CLVMD@", "none")
|
||||||
SUBDIRS += clvmd
|
SUBDIRS = clvmd
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ("@BUILD_CMIRRORD@", "yes")
|
include $(top_srcdir)/make.tmpl
|
||||||
SUBDIRS += cmirrord
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ("@BUILD_DMEVENTD@", "yes")
|
|
||||||
SUBDIRS += dmeventd
|
|
||||||
ifneq ("$(CFLOW_CMD)", "")
|
|
||||||
daemons.cflow: dmeventd.cflow
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ("@BUILD_LVMETAD@", "yes")
|
|
||||||
SUBDIRS += lvmetad
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ("@BUILD_LVMPOLLD@", "yes")
|
|
||||||
SUBDIRS += lvmpolld
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ("@BUILD_LVMLOCKD@", "yes")
|
|
||||||
SUBDIRS += lvmlockd
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(MAKECMDGOALS),distclean)
|
|
||||||
SUBDIRS = clvmd cmirrord dmeventd lvmetad lvmpolld lvmlockd
|
|
||||||
endif
|
|
||||||
|
|
||||||
include $(top_builddir)/make.tmpl
|
|
||||||
|
|
||||||
ifeq ("@BUILD_DMEVENTD@", "yes")
|
|
||||||
device-mapper: dmeventd.device-mapper
|
|
||||||
endif
|
|
||||||
|
|||||||
1
daemons/clvmd/.gitignore
vendored
1
daemons/clvmd/.gitignore
vendored
@@ -1 +0,0 @@
|
|||||||
clvmd
|
|
||||||
@@ -13,22 +13,7 @@
|
|||||||
|
|
||||||
srcdir = @srcdir@
|
srcdir = @srcdir@
|
||||||
top_srcdir = @top_srcdir@
|
top_srcdir = @top_srcdir@
|
||||||
top_builddir = @top_builddir@
|
VPATH = @srcdir@
|
||||||
|
|
||||||
CMAN_LIBS = @CMAN_LIBS@
|
|
||||||
CMAN_CFLAGS = @CMAN_CFLAGS@
|
|
||||||
CMAP_LIBS = @CMAP_LIBS@
|
|
||||||
CMAP_CFLAGS = @CMAP_CFLAGS@
|
|
||||||
CONFDB_LIBS = @CONFDB_LIBS@
|
|
||||||
CONFDB_CFLAGS = @CONFDB_CFLAGS@
|
|
||||||
CPG_LIBS = @CPG_LIBS@
|
|
||||||
CPG_CFLAGS = @CPG_CFLAGS@
|
|
||||||
DLM_LIBS = @DLM_LIBS@
|
|
||||||
DLM_CFLAGS = @DLM_CFLAGS@
|
|
||||||
QUORUM_LIBS = @QUORUM_LIBS@
|
|
||||||
QUORUM_CFLAGS = @QUORUM_CFLAGS@
|
|
||||||
SALCK_LIBS = @SALCK_LIBS@
|
|
||||||
SALCK_CFLAGS = @SALCK_CFLAGS@
|
|
||||||
|
|
||||||
SOURCES = \
|
SOURCES = \
|
||||||
clvmd-command.c \
|
clvmd-command.c \
|
||||||
@@ -36,68 +21,78 @@ SOURCES = \
|
|||||||
lvm-functions.c \
|
lvm-functions.c \
|
||||||
refresh_clvmd.c
|
refresh_clvmd.c
|
||||||
|
|
||||||
ifneq (,$(findstring cman,, "@CLVMD@,"))
|
ifeq ("@CLVMD@", "gulm")
|
||||||
|
GULM = yes
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ("@CLVMD@", "cman")
|
||||||
|
CMAN = yes
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ("@CLVMD@", "openais")
|
||||||
|
OPENAIS = yes
|
||||||
|
GULM = no
|
||||||
|
CMAN = no
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ("@CLVMD@", "all")
|
||||||
|
GULM = yes
|
||||||
|
CMAN = yes
|
||||||
|
OPENAIS = no
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ("@DEBUG@", "yes")
|
||||||
|
DEFS += -DDEBUG
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ("$(GULM)", "yes")
|
||||||
|
SOURCES += clvmd-gulm.c tcp-comms.c
|
||||||
|
LMLIBS += -lccs -lgulm
|
||||||
|
DEFS += -DUSE_GULM
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ("$(CMAN)", "yes")
|
||||||
SOURCES += clvmd-cman.c
|
SOURCES += clvmd-cman.c
|
||||||
LMLIBS += $(CMAN_LIBS) $(CONFDB_LIBS) $(DLM_LIBS)
|
LMLIBS += -ldlm -lcman
|
||||||
CFLAGS += $(CMAN_CFLAGS) $(CONFDB_CFLAGS) $(DLM_CFLAGS)
|
|
||||||
DEFS += -DUSE_CMAN
|
DEFS += -DUSE_CMAN
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq (,$(findstring openais,, "@CLVMD@,"))
|
ifeq ("$(OPENAIS)", "yes")
|
||||||
SOURCES += clvmd-openais.c
|
SOURCES += clvmd-openais.c
|
||||||
LMLIBS += $(CONFDB_LIBS) $(CPG_LIBS) $(SALCK_LIBS)
|
LMLIBS += -lSaLck -lcpg
|
||||||
CFLAGS += $(CONFDB_CFLAGS) $(CPG_CFLAGS) $(SALCK_CFLAGS)
|
|
||||||
DEFS += -DUSE_OPENAIS
|
DEFS += -DUSE_OPENAIS
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq (,$(findstring corosync,, "@CLVMD@,"))
|
|
||||||
SOURCES += clvmd-corosync.c
|
|
||||||
LMLIBS += $(CMAP_LIBS) $(CONFDB_LIBS) $(CPG_LIBS) $(DLM_LIBS) $(QUORUM_LIBS)
|
|
||||||
CFLAGS += $(CMAP_CFLAGS) $(CONFDB_CFLAGS) $(CPG_CFLAGS) $(DLM_CFLAGS) $(QUORUM_CFLAGS)
|
|
||||||
DEFS += -DUSE_COROSYNC
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifneq (,$(findstring singlenode,, "@CLVMD@,"))
|
|
||||||
SOURCES += clvmd-singlenode.c
|
|
||||||
DEFS += -DUSE_SINGLENODE
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(MAKECMDGOALS),distclean)
|
|
||||||
SOURCES += clvmd-cman.c
|
|
||||||
SOURCES += clvmd-openais.c
|
|
||||||
SOURCES += clvmd-corosync.c
|
|
||||||
SOURCES += clvmd-singlenode.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
TARGETS = \
|
TARGETS = \
|
||||||
clvmd
|
clvmd
|
||||||
|
|
||||||
LVMLIBS = $(LVMINTERNAL_LIBS)
|
LVMLIBS = -llvm -lpthread
|
||||||
|
|
||||||
ifeq ("@DMEVENTD@", "yes")
|
ifeq ("@DMEVENTD@", "yes")
|
||||||
LVMLIBS += -ldevmapper-event
|
LVMLIBS += -ldevmapper-event
|
||||||
endif
|
endif
|
||||||
|
|
||||||
include $(top_builddir)/make.tmpl
|
|
||||||
|
|
||||||
LVMLIBS += -ldevmapper
|
LVMLIBS += -ldevmapper
|
||||||
LIBS += $(PTHREAD_LIBS)
|
|
||||||
|
|
||||||
CFLAGS += -fno-strict-aliasing $(EXTRA_EXEC_CFLAGS)
|
DEFS += -D_REENTRANT
|
||||||
LDFLAGS += $(EXTRA_EXEC_LDFLAGS)
|
CFLAGS += -fno-strict-aliasing
|
||||||
|
|
||||||
|
include $(top_srcdir)/make.tmpl
|
||||||
|
|
||||||
INSTALL_TARGETS = \
|
INSTALL_TARGETS = \
|
||||||
install_clvmd
|
install_clvmd
|
||||||
|
|
||||||
clvmd: $(OBJECTS) $(top_builddir)/lib/liblvm-internal.a
|
clvmd: $(OBJECTS) $(top_srcdir)/lib/liblvm.a
|
||||||
$(CC) $(CFLAGS) $(LDFLAGS) -o clvmd $(OBJECTS) \
|
$(CC) -o clvmd $(OBJECTS) $(CFLAGS) $(LDFLAGS) \
|
||||||
$(LVMLIBS) $(LMLIBS) $(LIBS)
|
$(LVMLIBS) $(LMLIBS) $(LIBS)
|
||||||
|
|
||||||
.PHONY: install_clvmd
|
.PHONY: install_clvmd
|
||||||
|
|
||||||
install_clvmd: $(TARGETS)
|
install_clvmd: $(TARGETS)
|
||||||
$(INSTALL_PROGRAM) -D clvmd $(usrsbindir)/clvmd
|
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) clvmd \
|
||||||
|
$(usrsbindir)/clvmd
|
||||||
|
|
||||||
install: $(INSTALL_TARGETS)
|
install: $(INSTALL_TARGETS)
|
||||||
|
|
||||||
install_cluster: $(INSTALL_TARGETS)
|
install_cluster: $(INSTALL_TARGETS)
|
||||||
|
|
||||||
|
|||||||
@@ -22,40 +22,37 @@
|
|||||||
#ifndef _CLVM_H
|
#ifndef _CLVM_H
|
||||||
#define _CLVM_H
|
#define _CLVM_H
|
||||||
|
|
||||||
#include "configure.h"
|
|
||||||
#include <inttypes.h>
|
|
||||||
|
|
||||||
struct clvm_header {
|
struct clvm_header {
|
||||||
uint8_t cmd; /* See below */
|
uint8_t cmd; /* See below */
|
||||||
uint8_t flags; /* See below */
|
uint8_t flags; /* See below */
|
||||||
uint16_t xid; /* Transaction ID */
|
uint16_t xid; /* Transaction ID */
|
||||||
uint32_t clientid; /* Only used in Daemon->Daemon comms */
|
uint32_t clientid; /* Only used in Daemon->Daemon comms */
|
||||||
int32_t status; /* For replies, whether request succeeded */
|
int32_t status; /* For replies, whether request succeeded */
|
||||||
uint32_t arglen; /* Length of argument below.
|
uint32_t arglen; /* Length of argument below.
|
||||||
If >1500 then it will be passed
|
If >1500 then it will be passed
|
||||||
around the cluster in the system LV */
|
around the cluster in the system LV */
|
||||||
char node[1]; /* Actually a NUL-terminated string, node name.
|
char node[1]; /* Actually a NUL-terminated string, node name.
|
||||||
If this is empty then the command is
|
If this is empty then the command is
|
||||||
forwarded to all cluster nodes unless
|
forwarded to all cluster nodes unless
|
||||||
FLAG_LOCAL or FLAG_REMOTE is also set. */
|
FLAG_LOCAL is also set. */
|
||||||
char args[1]; /* Arguments for the command follow the
|
char args[1]; /* Arguments for the command follow the
|
||||||
node name, This member is only
|
node name, This member is only
|
||||||
valid if the node name is empty */
|
valid if the node name is empty */
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
/* Flags */
|
/* Flags */
|
||||||
#define CLVMD_FLAG_LOCAL 1 /* Only do this on the local node */
|
#define CLVMD_FLAG_LOCAL 1 /* Only do this on the local node */
|
||||||
#define CLVMD_FLAG_SYSTEMLV 2 /* Data in system LV under my node name */
|
#define CLVMD_FLAG_SYSTEMLV 2 /* Data in system LV under my node name */
|
||||||
#define CLVMD_FLAG_NODEERRS 4 /* Reply has errors in node-specific portion */
|
#define CLVMD_FLAG_NODEERRS 4 /* Reply has errors in node-specific portion */
|
||||||
#define CLVMD_FLAG_REMOTE 8 /* Do this on all nodes except for the local node */
|
|
||||||
|
|
||||||
/* Name of the local socket to communicate between lvm and clvmd */
|
/* Name of the local socket to communicate between libclvm and clvmd */
|
||||||
static const char CLVMD_SOCKNAME[]= DEFAULT_RUN_DIR "/clvmd.sock";
|
//static const char CLVMD_SOCKNAME[]="/var/run/clvmd";
|
||||||
|
static const char CLVMD_SOCKNAME[] = "\0clvmd";
|
||||||
|
|
||||||
/* Internal commands & replies */
|
/* Internal commands & replies */
|
||||||
#define CLVMD_CMD_REPLY 1
|
#define CLVMD_CMD_REPLY 1
|
||||||
#define CLVMD_CMD_VERSION 2 /* Send version around cluster when we start */
|
#define CLVMD_CMD_VERSION 2 /* Send version around cluster when we start */
|
||||||
#define CLVMD_CMD_GOAWAY 3 /* Die if received this - we are running
|
#define CLVMD_CMD_GOAWAY 3 /* Die if received this - we are running
|
||||||
an incompatible version */
|
an incompatible version */
|
||||||
#define CLVMD_CMD_TEST 4 /* Just for mucking about */
|
#define CLVMD_CMD_TEST 4 /* Just for mucking about */
|
||||||
|
|
||||||
@@ -65,19 +62,10 @@ static const char CLVMD_SOCKNAME[]= DEFAULT_RUN_DIR "/clvmd.sock";
|
|||||||
/* Lock/Unlock commands */
|
/* Lock/Unlock commands */
|
||||||
#define CLVMD_CMD_LOCK_LV 50
|
#define CLVMD_CMD_LOCK_LV 50
|
||||||
#define CLVMD_CMD_LOCK_VG 51
|
#define CLVMD_CMD_LOCK_VG 51
|
||||||
#define CLVMD_CMD_LOCK_QUERY 52
|
|
||||||
|
|
||||||
/* Misc functions */
|
/* Misc functions */
|
||||||
#define CLVMD_CMD_REFRESH 40
|
#define CLVMD_CMD_REFRESH 40
|
||||||
#define CLVMD_CMD_GET_CLUSTERNAME 41
|
#define CLVMD_CMD_GET_CLUSTERNAME 41
|
||||||
#define CLVMD_CMD_SET_DEBUG 42
|
#define CLVMD_CMD_SET_DEBUG 42
|
||||||
#define CLVMD_CMD_VG_BACKUP 43
|
#define CLVMD_CMD_VG_BACKUP 43
|
||||||
#define CLVMD_CMD_RESTART 44
|
|
||||||
#define CLVMD_CMD_SYNC_NAMES 45
|
|
||||||
|
|
||||||
/* Used internally by some callers, but not part of the protocol.*/
|
|
||||||
#define NODE_ALL "*"
|
|
||||||
#define NODE_LOCAL "."
|
|
||||||
#define NODE_REMOTE "^"
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -17,19 +17,34 @@
|
|||||||
* CMAN communication layer for clvmd.
|
* CMAN communication layer for clvmd.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "clvmd-common.h"
|
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/uio.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/utsname.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <libdevmapper.h>
|
||||||
|
#include <libdlm.h>
|
||||||
|
|
||||||
#include "clvmd-comms.h"
|
#include "clvmd-comms.h"
|
||||||
#include "clvm.h"
|
#include "clvm.h"
|
||||||
|
#include "log.h"
|
||||||
#include "clvmd.h"
|
#include "clvmd.h"
|
||||||
#include "lvm-functions.h"
|
#include "lvm-functions.h"
|
||||||
|
|
||||||
#include <libdlm.h>
|
|
||||||
|
|
||||||
#include <syslog.h>
|
|
||||||
|
|
||||||
#define LOCKSPACE_NAME "clvmd"
|
#define LOCKSPACE_NAME "clvmd"
|
||||||
|
|
||||||
struct clvmd_node
|
struct clvmd_node
|
||||||
@@ -89,17 +104,11 @@ static int _init_cluster(void)
|
|||||||
DEBUGLOG("CMAN initialisation complete\n");
|
DEBUGLOG("CMAN initialisation complete\n");
|
||||||
|
|
||||||
/* Create a lockspace for LV & VG locks to live in */
|
/* Create a lockspace for LV & VG locks to live in */
|
||||||
lockspace = dlm_open_lockspace(LOCKSPACE_NAME);
|
lockspace = dlm_create_lockspace(LOCKSPACE_NAME, 0600);
|
||||||
if (!lockspace) {
|
if (!lockspace) {
|
||||||
lockspace = dlm_create_lockspace(LOCKSPACE_NAME, 0600);
|
syslog(LOG_ERR, "Unable to create lockspace for CLVM: %m");
|
||||||
if (!lockspace) {
|
return -1;
|
||||||
syslog(LOG_ERR, "Unable to create DLM lockspace for CLVM: %m");
|
}
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
DEBUGLOG("Created DLM lockspace for CLVMD.\n");
|
|
||||||
} else
|
|
||||||
DEBUGLOG("Opened existing DLM lockspace for CLVMD.\n");
|
|
||||||
|
|
||||||
dlm_ls_pthread_init(lockspace);
|
dlm_ls_pthread_init(lockspace);
|
||||||
DEBUGLOG("DLM initialisation complete\n");
|
DEBUGLOG("DLM initialisation complete\n");
|
||||||
return 0;
|
return 0;
|
||||||
@@ -110,12 +119,12 @@ static void _cluster_init_completed(void)
|
|||||||
clvmd_cluster_init_completed();
|
clvmd_cluster_init_completed();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _get_main_cluster_fd(void)
|
static int _get_main_cluster_fd()
|
||||||
{
|
{
|
||||||
return cman_get_fd(c_handle);
|
return cman_get_fd(c_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _get_num_nodes(void)
|
static int _get_num_nodes()
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int nnodes = 0;
|
int nnodes = 0;
|
||||||
@@ -243,8 +252,9 @@ static void _add_up_node(const char *csid)
|
|||||||
DEBUGLOG("Added new node %d to updown list\n", nodeid);
|
DEBUGLOG("Added new node %d to updown list\n", nodeid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _cluster_closedown(void)
|
static void _cluster_closedown()
|
||||||
{
|
{
|
||||||
|
unlock_all();
|
||||||
dlm_release_lockspace(LOCKSPACE_NAME, lockspace, 1);
|
dlm_release_lockspace(LOCKSPACE_NAME, lockspace, 1);
|
||||||
cman_finish(c_handle);
|
cman_finish(c_handle);
|
||||||
}
|
}
|
||||||
@@ -282,7 +292,7 @@ static void count_clvmds_running(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Get a list of active cluster members */
|
/* Get a list of active cluster members */
|
||||||
static void get_members(void)
|
static void get_members()
|
||||||
{
|
{
|
||||||
int retnodes;
|
int retnodes;
|
||||||
int status;
|
int status;
|
||||||
@@ -380,7 +390,7 @@ static int nodeid_from_csid(const char *csid)
|
|||||||
return nodeid;
|
return nodeid;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _is_quorate(void)
|
static int _is_quorate()
|
||||||
{
|
{
|
||||||
return cman_is_quorate(c_handle);
|
return cman_is_quorate(c_handle);
|
||||||
}
|
}
|
||||||
@@ -478,7 +488,6 @@ static int _get_cluster_name(char *buf, int buflen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct cluster_ops _cluster_cman_ops = {
|
static struct cluster_ops _cluster_cman_ops = {
|
||||||
.name = "cman",
|
|
||||||
.cluster_init_completed = _cluster_init_completed,
|
.cluster_init_completed = _cluster_init_completed,
|
||||||
.cluster_send_message = _cluster_send_message,
|
.cluster_send_message = _cluster_send_message,
|
||||||
.name_from_csid = _name_from_csid,
|
.name_from_csid = _name_from_csid,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
|
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
|
||||||
* Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
|
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* This file is part of LVM2.
|
* This file is part of LVM2.
|
||||||
*
|
*
|
||||||
@@ -50,19 +50,33 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "clvmd-common.h"
|
#include <pthread.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/utsname.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <libdevmapper.h>
|
||||||
|
#include <libdlm.h>
|
||||||
|
|
||||||
|
#include "list.h"
|
||||||
|
#include "locking.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "lvm-functions.h"
|
||||||
#include "clvmd-comms.h"
|
#include "clvmd-comms.h"
|
||||||
#include "clvm.h"
|
#include "clvm.h"
|
||||||
#include "clvmd.h"
|
#include "clvmd.h"
|
||||||
#include "lvm-globals.h"
|
|
||||||
#include "lvm-functions.h"
|
|
||||||
|
|
||||||
#include "locking.h"
|
|
||||||
|
|
||||||
#include <sys/utsname.h>
|
|
||||||
|
|
||||||
|
extern debug_t debug;
|
||||||
extern struct cluster_ops *clops;
|
extern struct cluster_ops *clops;
|
||||||
static int restart_clvmd(void);
|
|
||||||
|
|
||||||
/* This is where all the real work happens:
|
/* This is where all the real work happens:
|
||||||
NOTE: client will be NULL when this is executed on a remote node */
|
NOTE: client will be NULL when this is executed on a remote node */
|
||||||
@@ -73,7 +87,6 @@ int do_command(struct local_client *client, struct clvm_header *msg, int msglen,
|
|||||||
int arglen = msglen - sizeof(struct clvm_header) - strlen(msg->node);
|
int arglen = msglen - sizeof(struct clvm_header) - strlen(msg->node);
|
||||||
int status = 0;
|
int status = 0;
|
||||||
char *lockname;
|
char *lockname;
|
||||||
const char *locktype;
|
|
||||||
struct utsname nodeinfo;
|
struct utsname nodeinfo;
|
||||||
unsigned char lock_cmd;
|
unsigned char lock_cmd;
|
||||||
unsigned char lock_flags;
|
unsigned char lock_flags;
|
||||||
@@ -93,61 +106,47 @@ int do_command(struct local_client *client, struct clvm_header *msg, int msglen,
|
|||||||
*buf = new_buf;
|
*buf = new_buf;
|
||||||
}
|
}
|
||||||
if (*buf) {
|
if (*buf) {
|
||||||
if (uname(&nodeinfo))
|
uname(&nodeinfo);
|
||||||
memset(&nodeinfo, 0, sizeof(nodeinfo));
|
*retlen = 1 + snprintf(*buf, buflen,
|
||||||
|
"TEST from %s: %s v%s",
|
||||||
*retlen = 1 + dm_snprintf(*buf, buflen,
|
nodeinfo.nodename, args,
|
||||||
"TEST from %s: %s v%s",
|
nodeinfo.release);
|
||||||
nodeinfo.nodename, args,
|
|
||||||
nodeinfo.release);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CLVMD_CMD_LOCK_VG:
|
case CLVMD_CMD_LOCK_VG:
|
||||||
lock_cmd = args[0];
|
|
||||||
lock_flags = args[1];
|
|
||||||
lockname = &args[2];
|
lockname = &args[2];
|
||||||
/* Check to see if the VG is in use by LVM1 */
|
/* Check to see if the VG is in use by LVM1 */
|
||||||
status = do_check_lvm1(lockname);
|
status = do_check_lvm1(lockname);
|
||||||
do_lock_vg(lock_cmd, lock_flags, lockname);
|
/* P_#global causes a full cache refresh */
|
||||||
|
if (!strcmp(lockname, "P_" VG_GLOBAL))
|
||||||
|
do_refresh_cache();
|
||||||
|
else
|
||||||
|
drop_metadata(lockname + 2);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CLVMD_CMD_LOCK_LV:
|
case CLVMD_CMD_LOCK_LV:
|
||||||
/* This is the biggie */
|
/* This is the biggie */
|
||||||
lock_cmd = args[0];
|
lock_cmd = args[0] & 0x3F;
|
||||||
lock_flags = args[1];
|
lock_flags = args[1];
|
||||||
lockname = &args[2];
|
lockname = &args[2];
|
||||||
status = do_lock_lv(lock_cmd, lock_flags, lockname);
|
status = do_lock_lv(lock_cmd, lock_flags, lockname);
|
||||||
/* Replace EIO with something less scary */
|
/* Replace EIO with something less scary */
|
||||||
if (status == EIO) {
|
if (status == EIO) {
|
||||||
*retlen = 1 + dm_snprintf(*buf, buflen, "%s",
|
*retlen =
|
||||||
get_last_lvm_error());
|
1 + snprintf(*buf, buflen, "%s",
|
||||||
|
get_last_lvm_error());
|
||||||
return EIO;
|
return EIO;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CLVMD_CMD_LOCK_QUERY:
|
|
||||||
lockname = &args[2];
|
|
||||||
if (buflen < 3)
|
|
||||||
return EIO;
|
|
||||||
if ((locktype = do_lock_query(lockname)))
|
|
||||||
*retlen = 1 + dm_snprintf(*buf, buflen, "%s", locktype);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CLVMD_CMD_REFRESH:
|
case CLVMD_CMD_REFRESH:
|
||||||
do_refresh_cache();
|
do_refresh_cache();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CLVMD_CMD_SYNC_NAMES:
|
|
||||||
lvm_do_fs_unlock();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CLVMD_CMD_SET_DEBUG:
|
case CLVMD_CMD_SET_DEBUG:
|
||||||
clvmd_set_debug((debug_t) args[0]);
|
debug = args[0];
|
||||||
break;
|
|
||||||
|
|
||||||
case CLVMD_CMD_RESTART:
|
|
||||||
status = restart_clvmd();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CLVMD_CMD_GET_CLUSTERNAME:
|
case CLVMD_CMD_GET_CLUSTERNAME:
|
||||||
@@ -157,11 +156,7 @@ int do_command(struct local_client *client, struct clvm_header *msg, int msglen,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CLVMD_CMD_VG_BACKUP:
|
case CLVMD_CMD_VG_BACKUP:
|
||||||
/*
|
lvm_do_backup(&args[2]);
|
||||||
* Do not run backup on local node, caller should do that.
|
|
||||||
*/
|
|
||||||
if (!client)
|
|
||||||
lvm_do_backup(&args[2]);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -171,63 +166,69 @@ int do_command(struct local_client *client, struct clvm_header *msg, int msglen,
|
|||||||
|
|
||||||
/* Check the status of the command and return the error text */
|
/* Check the status of the command and return the error text */
|
||||||
if (status) {
|
if (status) {
|
||||||
*retlen = 1 + ((*buf) ? dm_snprintf(*buf, buflen, "%s",
|
*retlen = 1 + snprintf(*buf, buflen, "%s", strerror(status));
|
||||||
strerror(status)) : -1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lock_vg(struct local_client *client)
|
static int lock_vg(struct local_client *client)
|
||||||
{
|
{
|
||||||
struct dm_hash_table *lock_hash;
|
struct dm_hash_table *lock_hash;
|
||||||
struct clvm_header *header =
|
struct clvm_header *header =
|
||||||
(struct clvm_header *) client->bits.localsock.cmd;
|
(struct clvm_header *) client->bits.localsock.cmd;
|
||||||
unsigned char lock_cmd;
|
unsigned char lock_cmd;
|
||||||
int lock_mode;
|
unsigned char lock_flags;
|
||||||
char *args = header->node + strlen(header->node) + 1;
|
char *args = header->node + strlen(header->node) + 1;
|
||||||
int lkid;
|
int lkid;
|
||||||
int status;
|
int status = 0;
|
||||||
char *lockname;
|
char *lockname;
|
||||||
|
|
||||||
/*
|
/* Keep a track of VG locks in our own hash table. In current
|
||||||
* Keep a track of VG locks in our own hash table. In current
|
practice there should only ever be more than two VGs locked
|
||||||
* practice there should only ever be more than two VGs locked
|
if a user tries to merge lots of them at once */
|
||||||
* if a user tries to merge lots of them at once
|
if (client->bits.localsock.private) {
|
||||||
*/
|
lock_hash = (struct dm_hash_table *)client->bits.localsock.private;
|
||||||
if (!client->bits.localsock.private) {
|
}
|
||||||
if (!(lock_hash = dm_hash_create(3)))
|
else {
|
||||||
return ENOMEM;
|
lock_hash = dm_hash_create(3);
|
||||||
client->bits.localsock.private = (void *) lock_hash;
|
if (!lock_hash)
|
||||||
} else
|
return ENOMEM;
|
||||||
lock_hash = (struct dm_hash_table *) client->bits.localsock.private;
|
client->bits.localsock.private = (void *)lock_hash;
|
||||||
|
}
|
||||||
|
|
||||||
lock_cmd = args[0] & (LCK_NONBLOCK | LCK_HOLD | LCK_SCOPE_MASK | LCK_TYPE_MASK);
|
lock_cmd = args[0] & 0x3F;
|
||||||
lock_mode = ((int) lock_cmd & LCK_TYPE_MASK);
|
lock_flags = args[1];
|
||||||
/* lock_flags = args[1]; */
|
lockname = &args[2];
|
||||||
lockname = &args[2];
|
DEBUGLOG("doing PRE command LOCK_VG '%s' at %x (client=%p)\n", lockname, lock_cmd, client);
|
||||||
DEBUGLOG("doing PRE command LOCK_VG '%s' at %x (client=%p)\n", lockname, lock_cmd, client);
|
|
||||||
|
|
||||||
if (lock_mode == LCK_UNLOCK) {
|
if (lock_cmd == LCK_UNLOCK) {
|
||||||
if (!(lkid = (int) (long) dm_hash_lookup(lock_hash, lockname)))
|
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
if ((status = sync_unlock(lockname, lkid)))
|
lkid = (int)(long)dm_hash_lookup(lock_hash, lockname);
|
||||||
status = errno;
|
if (lkid == 0)
|
||||||
else
|
return EINVAL;
|
||||||
dm_hash_remove(lock_hash, lockname);
|
|
||||||
} else {
|
|
||||||
/* Read locks need to be PR; other modes get passed through */
|
|
||||||
if (lock_mode == LCK_READ)
|
|
||||||
lock_mode = LCK_PREAD;
|
|
||||||
|
|
||||||
if ((status = sync_lock(lockname, lock_mode, (lock_cmd & LCK_NONBLOCK) ? LCKF_NOQUEUE : 0, &lkid)))
|
status = sync_unlock(lockname, lkid);
|
||||||
status = errno;
|
if (status)
|
||||||
else if (!dm_hash_insert(lock_hash, lockname, (void *) (long) lkid))
|
status = errno;
|
||||||
return ENOMEM;
|
else
|
||||||
|
dm_hash_remove(lock_hash, lockname);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Read locks need to be PR; other modes get passed through */
|
||||||
|
if ((lock_cmd & LCK_TYPE_MASK) == LCK_READ) {
|
||||||
|
lock_cmd &= ~LCK_TYPE_MASK;
|
||||||
|
lock_cmd |= LCK_PREAD;
|
||||||
}
|
}
|
||||||
|
status = sync_lock(lockname, (int)lock_cmd, (lock_flags & LCK_NONBLOCK) ? LKF_NOQUEUE : 0, &lkid);
|
||||||
|
if (status)
|
||||||
|
status = errno;
|
||||||
|
else
|
||||||
|
dm_hash_insert(lock_hash, lockname, (void *)(long)lkid);
|
||||||
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -241,13 +242,13 @@ int do_pre_command(struct local_client *client)
|
|||||||
unsigned char lock_cmd;
|
unsigned char lock_cmd;
|
||||||
unsigned char lock_flags;
|
unsigned char lock_flags;
|
||||||
char *args = header->node + strlen(header->node) + 1;
|
char *args = header->node + strlen(header->node) + 1;
|
||||||
int lockid = 0;
|
int lockid;
|
||||||
int status = 0;
|
int status = 0;
|
||||||
char *lockname;
|
char *lockname;
|
||||||
|
|
||||||
switch (header->cmd) {
|
switch (header->cmd) {
|
||||||
case CLVMD_CMD_TEST:
|
case CLVMD_CMD_TEST:
|
||||||
status = sync_lock("CLVMD_TEST", LCK_EXCL, 0, &lockid);
|
status = sync_lock("CLVMD_TEST", LKM_EXMODE, 0, &lockid);
|
||||||
client->bits.localsock.private = (void *)(long)lockid;
|
client->bits.localsock.private = (void *)(long)lockid;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -270,9 +271,6 @@ int do_pre_command(struct local_client *client)
|
|||||||
case CLVMD_CMD_GET_CLUSTERNAME:
|
case CLVMD_CMD_GET_CLUSTERNAME:
|
||||||
case CLVMD_CMD_SET_DEBUG:
|
case CLVMD_CMD_SET_DEBUG:
|
||||||
case CLVMD_CMD_VG_BACKUP:
|
case CLVMD_CMD_VG_BACKUP:
|
||||||
case CLVMD_CMD_SYNC_NAMES:
|
|
||||||
case CLVMD_CMD_LOCK_QUERY:
|
|
||||||
case CLVMD_CMD_RESTART:
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -296,8 +294,14 @@ int do_post_command(struct local_client *client)
|
|||||||
|
|
||||||
switch (header->cmd) {
|
switch (header->cmd) {
|
||||||
case CLVMD_CMD_TEST:
|
case CLVMD_CMD_TEST:
|
||||||
status = sync_unlock("CLVMD_TEST", (int) (long) client->bits.localsock.private);
|
status =
|
||||||
client->bits.localsock.private = NULL;
|
sync_unlock("CLVMD_TEST", (int) (long) client->bits.localsock.private);
|
||||||
|
client->bits.localsock.private = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLVMD_CMD_LOCK_VG:
|
||||||
|
case CLVMD_CMD_VG_BACKUP:
|
||||||
|
/* Nothing to do here */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CLVMD_CMD_LOCK_LV:
|
case CLVMD_CMD_LOCK_LV:
|
||||||
@@ -306,10 +310,6 @@ int do_post_command(struct local_client *client)
|
|||||||
lockname = &args[2];
|
lockname = &args[2];
|
||||||
status = post_lock_lv(lock_cmd, lock_flags, lockname);
|
status = post_lock_lv(lock_cmd, lock_flags, lockname);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
|
||||||
/* Nothing to do here */
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@@ -318,97 +318,21 @@ int do_post_command(struct local_client *client)
|
|||||||
/* Called when the client is about to be deleted */
|
/* Called when the client is about to be deleted */
|
||||||
void cmd_client_cleanup(struct local_client *client)
|
void cmd_client_cleanup(struct local_client *client)
|
||||||
{
|
{
|
||||||
|
if (client->bits.localsock.private) {
|
||||||
|
|
||||||
struct dm_hash_node *v;
|
struct dm_hash_node *v;
|
||||||
struct dm_hash_table *lock_hash;
|
struct dm_hash_table *lock_hash =
|
||||||
int lkid;
|
(struct dm_hash_table *)client->bits.localsock.private;
|
||||||
char *lockname;
|
|
||||||
|
|
||||||
DEBUGLOG("Client thread cleanup (%p)\n", client);
|
|
||||||
if (!client->bits.localsock.private)
|
|
||||||
return;
|
|
||||||
|
|
||||||
lock_hash = (struct dm_hash_table *)client->bits.localsock.private;
|
|
||||||
|
|
||||||
dm_hash_iterate(v, lock_hash) {
|
dm_hash_iterate(v, lock_hash) {
|
||||||
lkid = (int)(long)dm_hash_get_data(lock_hash, v);
|
int lkid = (int)(long)dm_hash_get_data(lock_hash, v);
|
||||||
lockname = dm_hash_get_key(lock_hash, v);
|
char *lockname = dm_hash_get_key(lock_hash, v);
|
||||||
DEBUGLOG("Cleanup (%p): Unlocking lock %s %x\n", client, lockname, lkid);
|
|
||||||
(void) sync_unlock(lockname, lkid);
|
DEBUGLOG("cleanup: Unlocking lock %s %x\n", lockname, lkid);
|
||||||
|
sync_unlock(lockname, lkid);
|
||||||
}
|
}
|
||||||
|
|
||||||
dm_hash_destroy(lock_hash);
|
dm_hash_destroy(lock_hash);
|
||||||
client->bits.localsock.private = NULL;
|
client->bits.localsock.private = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int restart_clvmd(void)
|
|
||||||
{
|
|
||||||
const char **argv;
|
|
||||||
char *lv_name;
|
|
||||||
int argc = 0, max_locks = 0;
|
|
||||||
struct dm_hash_node *hn = NULL;
|
|
||||||
char debug_arg[16];
|
|
||||||
const char *clvmd = getenv("LVM_CLVMD_BINARY") ? : CLVMD_PATH;
|
|
||||||
|
|
||||||
DEBUGLOG("clvmd restart requested\n");
|
|
||||||
|
|
||||||
/* Count exclusively-open LVs */
|
|
||||||
do {
|
|
||||||
hn = get_next_excl_lock(hn, &lv_name);
|
|
||||||
if (lv_name) {
|
|
||||||
max_locks++;
|
|
||||||
if (!*lv_name)
|
|
||||||
break; /* FIXME: Is this error ? */
|
|
||||||
}
|
|
||||||
} while (hn);
|
|
||||||
|
|
||||||
/* clvmd + locks (-E uuid) + debug (-d X) + NULL */
|
|
||||||
if (!(argv = malloc((max_locks * 2 + 6) * sizeof(*argv))))
|
|
||||||
goto_out;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Build the command-line
|
|
||||||
*/
|
|
||||||
argv[argc++] = "clvmd";
|
|
||||||
|
|
||||||
/* Propagate debug options */
|
|
||||||
if (clvmd_get_debug()) {
|
|
||||||
if (dm_snprintf(debug_arg, sizeof(debug_arg), "-d%u", clvmd_get_debug()) < 0)
|
|
||||||
goto_out;
|
|
||||||
argv[argc++] = debug_arg;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Propagate foreground options */
|
|
||||||
if (clvmd_get_foreground())
|
|
||||||
argv[argc++] = "-f";
|
|
||||||
|
|
||||||
argv[argc++] = "-I";
|
|
||||||
argv[argc++] = clops->name;
|
|
||||||
|
|
||||||
/* Now add the exclusively-open LVs */
|
|
||||||
hn = NULL;
|
|
||||||
do {
|
|
||||||
hn = get_next_excl_lock(hn, &lv_name);
|
|
||||||
if (lv_name) {
|
|
||||||
if (!*lv_name)
|
|
||||||
break; /* FIXME: Is this error ? */
|
|
||||||
argv[argc++] = "-E";
|
|
||||||
argv[argc++] = lv_name;
|
|
||||||
DEBUGLOG("excl lock: %s\n", lv_name);
|
|
||||||
}
|
|
||||||
} while (hn);
|
|
||||||
argv[argc] = NULL;
|
|
||||||
|
|
||||||
/* Exec new clvmd */
|
|
||||||
DEBUGLOG("--- Restarting %s ---\n", clvmd);
|
|
||||||
for (argc = 1; argv[argc]; argc++) DEBUGLOG("--- %d: %s\n", argc, argv[argc]);
|
|
||||||
|
|
||||||
/* NOTE: This will fail when downgrading! */
|
|
||||||
execvp(clvmd, (char **)argv);
|
|
||||||
out:
|
|
||||||
/* We failed */
|
|
||||||
DEBUGLOG("Restart of clvmd failed.\n");
|
|
||||||
|
|
||||||
free(argv);
|
|
||||||
|
|
||||||
return EIO;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
|
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
|
||||||
* Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
|
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* This file is part of LVM2.
|
* This file is part of LVM2.
|
||||||
*
|
*
|
||||||
@@ -23,7 +23,6 @@
|
|||||||
struct local_client;
|
struct local_client;
|
||||||
|
|
||||||
struct cluster_ops {
|
struct cluster_ops {
|
||||||
const char *name;
|
|
||||||
void (*cluster_init_completed) (void);
|
void (*cluster_init_completed) (void);
|
||||||
|
|
||||||
int (*cluster_send_message) (const void *buf, int msglen,
|
int (*cluster_send_message) (const void *buf, int msglen,
|
||||||
@@ -55,6 +54,13 @@ struct cluster_ops {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef USE_GULM
|
||||||
|
# include "tcp-comms.h"
|
||||||
|
struct cluster_ops *init_gulm_cluster(void);
|
||||||
|
#define MAX_CSID_LEN GULM_MAX_CSID_LEN
|
||||||
|
#define MAX_CLUSTER_MEMBER_NAME_LEN GULM_MAX_CLUSTER_MEMBER_NAME_LEN
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef USE_CMAN
|
#ifdef USE_CMAN
|
||||||
# include <netinet/in.h>
|
# include <netinet/in.h>
|
||||||
# include "libcman.h"
|
# include "libcman.h"
|
||||||
@@ -71,7 +77,7 @@ struct cluster_ops *init_cman_cluster(void);
|
|||||||
|
|
||||||
#ifdef USE_OPENAIS
|
#ifdef USE_OPENAIS
|
||||||
# include <openais/saAis.h>
|
# include <openais/saAis.h>
|
||||||
# include <corosync/totem/totem.h>
|
# include <openais/totem/totem.h>
|
||||||
# define OPENAIS_CSID_LEN (sizeof(int))
|
# define OPENAIS_CSID_LEN (sizeof(int))
|
||||||
# define OPENAIS_MAX_CLUSTER_MESSAGE MESSAGE_SIZE_MAX
|
# define OPENAIS_MAX_CLUSTER_MESSAGE MESSAGE_SIZE_MAX
|
||||||
# define OPENAIS_MAX_CLUSTER_MEMBER_NAME_LEN SA_MAX_NAME_LENGTH
|
# define OPENAIS_MAX_CLUSTER_MEMBER_NAME_LEN SA_MAX_NAME_LENGTH
|
||||||
@@ -87,33 +93,5 @@ struct cluster_ops *init_cman_cluster(void);
|
|||||||
struct cluster_ops *init_openais_cluster(void);
|
struct cluster_ops *init_openais_cluster(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_COROSYNC
|
|
||||||
# include <corosync/corotypes.h>
|
|
||||||
# define COROSYNC_CSID_LEN (sizeof(int))
|
|
||||||
# define COROSYNC_MAX_CLUSTER_MESSAGE 65535
|
|
||||||
# define COROSYNC_MAX_CLUSTER_MEMBER_NAME_LEN CS_MAX_NAME_LENGTH
|
|
||||||
# ifndef MAX_CLUSTER_MEMBER_NAME_LEN
|
|
||||||
# define MAX_CLUSTER_MEMBER_NAME_LEN CS_MAX_NAME_LENGTH
|
|
||||||
# endif
|
|
||||||
# ifndef CMAN_MAX_CLUSTER_MESSAGE
|
|
||||||
# define CMAN_MAX_CLUSTER_MESSAGE 65535
|
|
||||||
# endif
|
|
||||||
# ifndef MAX_CSID_LEN
|
|
||||||
# define MAX_CSID_LEN sizeof(int)
|
|
||||||
# endif
|
|
||||||
struct cluster_ops *init_corosync_cluster(void);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_SINGLENODE
|
|
||||||
# define SINGLENODE_CSID_LEN (sizeof(int))
|
|
||||||
# ifndef MAX_CLUSTER_MEMBER_NAME_LEN
|
|
||||||
# define MAX_CLUSTER_MEMBER_NAME_LEN 64
|
|
||||||
# endif
|
|
||||||
# define SINGLENODE_MAX_CLUSTER_MESSAGE 65535
|
|
||||||
# ifndef MAX_CSID_LEN
|
|
||||||
# define MAX_CSID_LEN sizeof(int)
|
|
||||||
# endif
|
|
||||||
struct cluster_ops *init_singlenode_cluster(void);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,658 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2009-2012 Red Hat, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* This file is part of LVM2.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use,
|
|
||||||
* modify, copy, or redistribute it subject to the terms and conditions
|
|
||||||
* of the GNU Lesser General Public License v.2.1.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this program; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This provides the interface between clvmd and corosync/DLM as the cluster
|
|
||||||
* and lock manager.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "clvmd-common.h"
|
|
||||||
|
|
||||||
#include <pthread.h>
|
|
||||||
|
|
||||||
#include "clvm.h"
|
|
||||||
#include "clvmd-comms.h"
|
|
||||||
#include "clvmd.h"
|
|
||||||
#include "lvm-functions.h"
|
|
||||||
|
|
||||||
#include "locking.h"
|
|
||||||
|
|
||||||
#include <corosync/cpg.h>
|
|
||||||
#include <corosync/quorum.h>
|
|
||||||
|
|
||||||
#ifdef HAVE_COROSYNC_CONFDB_H
|
|
||||||
# include <corosync/confdb.h>
|
|
||||||
#elif defined HAVE_COROSYNC_CMAP_H
|
|
||||||
# include <corosync/cmap.h>
|
|
||||||
#else
|
|
||||||
# error "Either HAVE_COROSYNC_CONFDB_H or HAVE_COROSYNC_CMAP_H must be defined."
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <libdlm.h>
|
|
||||||
|
|
||||||
#include <syslog.h>
|
|
||||||
|
|
||||||
/* Timeout value for several corosync calls */
|
|
||||||
#define LOCKSPACE_NAME "clvmd"
|
|
||||||
|
|
||||||
static void corosync_cpg_deliver_callback (cpg_handle_t handle,
|
|
||||||
const struct cpg_name *groupName,
|
|
||||||
uint32_t nodeid,
|
|
||||||
uint32_t pid,
|
|
||||||
void *msg,
|
|
||||||
size_t msg_len);
|
|
||||||
static void corosync_cpg_confchg_callback(cpg_handle_t handle,
|
|
||||||
const struct cpg_name *groupName,
|
|
||||||
const struct cpg_address *member_list, size_t member_list_entries,
|
|
||||||
const struct cpg_address *left_list, size_t left_list_entries,
|
|
||||||
const struct cpg_address *joined_list, size_t joined_list_entries);
|
|
||||||
static void _cluster_closedown(void);
|
|
||||||
|
|
||||||
/* Hash list of nodes in the cluster */
|
|
||||||
static struct dm_hash_table *node_hash;
|
|
||||||
|
|
||||||
/* Number of active nodes */
|
|
||||||
static int num_nodes;
|
|
||||||
static unsigned int our_nodeid;
|
|
||||||
|
|
||||||
static struct local_client *cluster_client;
|
|
||||||
|
|
||||||
/* Corosync handles */
|
|
||||||
static cpg_handle_t cpg_handle;
|
|
||||||
static quorum_handle_t quorum_handle;
|
|
||||||
|
|
||||||
/* DLM Handle */
|
|
||||||
static dlm_lshandle_t *lockspace;
|
|
||||||
|
|
||||||
static struct cpg_name cpg_group_name;
|
|
||||||
|
|
||||||
/* Corosync callback structs */
|
|
||||||
cpg_callbacks_t corosync_cpg_callbacks = {
|
|
||||||
.cpg_deliver_fn = corosync_cpg_deliver_callback,
|
|
||||||
.cpg_confchg_fn = corosync_cpg_confchg_callback,
|
|
||||||
};
|
|
||||||
|
|
||||||
quorum_callbacks_t quorum_callbacks = {
|
|
||||||
.quorum_notify_fn = NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct node_info
|
|
||||||
{
|
|
||||||
enum {NODE_DOWN, NODE_CLVMD} state;
|
|
||||||
int nodeid;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* Set errno to something approximating the right value and return 0 or -1 */
|
|
||||||
static int cs_to_errno(cs_error_t err)
|
|
||||||
{
|
|
||||||
switch(err)
|
|
||||||
{
|
|
||||||
case CS_OK:
|
|
||||||
return 0;
|
|
||||||
case CS_ERR_LIBRARY:
|
|
||||||
errno = EINVAL;
|
|
||||||
break;
|
|
||||||
case CS_ERR_VERSION:
|
|
||||||
errno = EINVAL;
|
|
||||||
break;
|
|
||||||
case CS_ERR_INIT:
|
|
||||||
errno = EINVAL;
|
|
||||||
break;
|
|
||||||
case CS_ERR_TIMEOUT:
|
|
||||||
errno = ETIME;
|
|
||||||
break;
|
|
||||||
case CS_ERR_TRY_AGAIN:
|
|
||||||
errno = EAGAIN;
|
|
||||||
break;
|
|
||||||
case CS_ERR_INVALID_PARAM:
|
|
||||||
errno = EINVAL;
|
|
||||||
break;
|
|
||||||
case CS_ERR_NO_MEMORY:
|
|
||||||
errno = ENOMEM;
|
|
||||||
break;
|
|
||||||
case CS_ERR_BAD_HANDLE:
|
|
||||||
errno = EINVAL;
|
|
||||||
break;
|
|
||||||
case CS_ERR_BUSY:
|
|
||||||
errno = EBUSY;
|
|
||||||
break;
|
|
||||||
case CS_ERR_ACCESS:
|
|
||||||
errno = EPERM;
|
|
||||||
break;
|
|
||||||
case CS_ERR_NOT_EXIST:
|
|
||||||
errno = ENOENT;
|
|
||||||
break;
|
|
||||||
case CS_ERR_NAME_TOO_LONG:
|
|
||||||
errno = ENAMETOOLONG;
|
|
||||||
break;
|
|
||||||
case CS_ERR_EXIST:
|
|
||||||
errno = EEXIST;
|
|
||||||
break;
|
|
||||||
case CS_ERR_NO_SPACE:
|
|
||||||
errno = ENOSPC;
|
|
||||||
break;
|
|
||||||
case CS_ERR_INTERRUPT:
|
|
||||||
errno = EINTR;
|
|
||||||
break;
|
|
||||||
case CS_ERR_NAME_NOT_FOUND:
|
|
||||||
errno = ENOENT;
|
|
||||||
break;
|
|
||||||
case CS_ERR_NO_RESOURCES:
|
|
||||||
errno = ENOMEM;
|
|
||||||
break;
|
|
||||||
case CS_ERR_NOT_SUPPORTED:
|
|
||||||
errno = EOPNOTSUPP;
|
|
||||||
break;
|
|
||||||
case CS_ERR_BAD_OPERATION:
|
|
||||||
errno = EINVAL;
|
|
||||||
break;
|
|
||||||
case CS_ERR_FAILED_OPERATION:
|
|
||||||
errno = EIO;
|
|
||||||
break;
|
|
||||||
case CS_ERR_MESSAGE_ERROR:
|
|
||||||
errno = EIO;
|
|
||||||
break;
|
|
||||||
case CS_ERR_QUEUE_FULL:
|
|
||||||
errno = EXFULL;
|
|
||||||
break;
|
|
||||||
case CS_ERR_QUEUE_NOT_AVAILABLE:
|
|
||||||
errno = EINVAL;
|
|
||||||
break;
|
|
||||||
case CS_ERR_BAD_FLAGS:
|
|
||||||
errno = EINVAL;
|
|
||||||
break;
|
|
||||||
case CS_ERR_TOO_BIG:
|
|
||||||
errno = E2BIG;
|
|
||||||
break;
|
|
||||||
case CS_ERR_NO_SECTIONS:
|
|
||||||
errno = ENOMEM;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
errno = EINVAL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *print_corosync_csid(const char *csid)
|
|
||||||
{
|
|
||||||
static char buf[128];
|
|
||||||
int id;
|
|
||||||
|
|
||||||
memcpy(&id, csid, sizeof(int));
|
|
||||||
sprintf(buf, "%d", id);
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void corosync_cpg_deliver_callback (cpg_handle_t handle,
|
|
||||||
const struct cpg_name *groupName,
|
|
||||||
uint32_t nodeid,
|
|
||||||
uint32_t pid,
|
|
||||||
void *msg,
|
|
||||||
size_t msg_len)
|
|
||||||
{
|
|
||||||
int target_nodeid;
|
|
||||||
|
|
||||||
memcpy(&target_nodeid, msg, COROSYNC_CSID_LEN);
|
|
||||||
|
|
||||||
DEBUGLOG("%u got message from nodeid %d for %d. len %zd\n",
|
|
||||||
our_nodeid, nodeid, target_nodeid, msg_len-4);
|
|
||||||
|
|
||||||
if (nodeid != our_nodeid)
|
|
||||||
if (target_nodeid == our_nodeid || target_nodeid == 0)
|
|
||||||
process_message(cluster_client, (char *)msg+COROSYNC_CSID_LEN,
|
|
||||||
msg_len-COROSYNC_CSID_LEN, (char*)&nodeid);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void corosync_cpg_confchg_callback(cpg_handle_t handle,
|
|
||||||
const struct cpg_name *groupName,
|
|
||||||
const struct cpg_address *member_list, size_t member_list_entries,
|
|
||||||
const struct cpg_address *left_list, size_t left_list_entries,
|
|
||||||
const struct cpg_address *joined_list, size_t joined_list_entries)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
struct node_info *ninfo;
|
|
||||||
|
|
||||||
DEBUGLOG("confchg callback. %zd joined, %zd left, %zd members\n",
|
|
||||||
joined_list_entries, left_list_entries, member_list_entries);
|
|
||||||
|
|
||||||
for (i=0; i<joined_list_entries; i++) {
|
|
||||||
ninfo = dm_hash_lookup_binary(node_hash,
|
|
||||||
(char *)&joined_list[i].nodeid,
|
|
||||||
COROSYNC_CSID_LEN);
|
|
||||||
if (!ninfo) {
|
|
||||||
ninfo = malloc(sizeof(struct node_info));
|
|
||||||
if (!ninfo) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ninfo->nodeid = joined_list[i].nodeid;
|
|
||||||
dm_hash_insert_binary(node_hash,
|
|
||||||
(char *)&ninfo->nodeid,
|
|
||||||
COROSYNC_CSID_LEN, ninfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ninfo->state = NODE_CLVMD;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i=0; i<left_list_entries; i++) {
|
|
||||||
ninfo = dm_hash_lookup_binary(node_hash,
|
|
||||||
(char *)&left_list[i].nodeid,
|
|
||||||
COROSYNC_CSID_LEN);
|
|
||||||
if (ninfo)
|
|
||||||
ninfo->state = NODE_DOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
num_nodes = member_list_entries;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _init_cluster(void)
|
|
||||||
{
|
|
||||||
cs_error_t err;
|
|
||||||
|
|
||||||
#ifdef QUORUM_SET /* corosync/quorum.h */
|
|
||||||
uint32_t quorum_type;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
node_hash = dm_hash_create(100);
|
|
||||||
|
|
||||||
err = cpg_initialize(&cpg_handle,
|
|
||||||
&corosync_cpg_callbacks);
|
|
||||||
if (err != CS_OK) {
|
|
||||||
syslog(LOG_ERR, "Cannot initialise Corosync CPG service: %d",
|
|
||||||
err);
|
|
||||||
DEBUGLOG("Cannot initialise Corosync CPG service: %d", err);
|
|
||||||
return cs_to_errno(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef QUORUM_SET
|
|
||||||
err = quorum_initialize(&quorum_handle,
|
|
||||||
&quorum_callbacks,
|
|
||||||
&quorum_type);
|
|
||||||
|
|
||||||
if (quorum_type != QUORUM_SET) {
|
|
||||||
syslog(LOG_ERR, "Corosync quorum service is not configured");
|
|
||||||
DEBUGLOG("Corosync quorum service is not configured");
|
|
||||||
return EINVAL;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
err = quorum_initialize(&quorum_handle,
|
|
||||||
&quorum_callbacks);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (err != CS_OK) {
|
|
||||||
syslog(LOG_ERR, "Cannot initialise Corosync quorum service: %d",
|
|
||||||
err);
|
|
||||||
DEBUGLOG("Cannot initialise Corosync quorum service: %d", err);
|
|
||||||
return cs_to_errno(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create a lockspace for LV & VG locks to live in */
|
|
||||||
lockspace = dlm_open_lockspace(LOCKSPACE_NAME);
|
|
||||||
if (!lockspace) {
|
|
||||||
lockspace = dlm_create_lockspace(LOCKSPACE_NAME, 0600);
|
|
||||||
if (!lockspace) {
|
|
||||||
syslog(LOG_ERR, "Unable to create DLM lockspace for CLVM: %m");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
DEBUGLOG("Created DLM lockspace for CLVMD.\n");
|
|
||||||
} else
|
|
||||||
DEBUGLOG("Opened existing DLM lockspace for CLVMD.\n");
|
|
||||||
|
|
||||||
dlm_ls_pthread_init(lockspace);
|
|
||||||
DEBUGLOG("DLM initialisation complete\n");
|
|
||||||
|
|
||||||
/* Connect to the clvmd group */
|
|
||||||
strcpy((char *)cpg_group_name.value, "clvmd");
|
|
||||||
cpg_group_name.length = strlen((char *)cpg_group_name.value);
|
|
||||||
err = cpg_join(cpg_handle, &cpg_group_name);
|
|
||||||
if (err != CS_OK) {
|
|
||||||
cpg_finalize(cpg_handle);
|
|
||||||
quorum_finalize(quorum_handle);
|
|
||||||
dlm_release_lockspace(LOCKSPACE_NAME, lockspace, 1);
|
|
||||||
syslog(LOG_ERR, "Cannot join clvmd process group");
|
|
||||||
DEBUGLOG("Cannot join clvmd process group: %d\n", err);
|
|
||||||
return cs_to_errno(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
err = cpg_local_get(cpg_handle,
|
|
||||||
&our_nodeid);
|
|
||||||
if (err != CS_OK) {
|
|
||||||
cpg_finalize(cpg_handle);
|
|
||||||
quorum_finalize(quorum_handle);
|
|
||||||
dlm_release_lockspace(LOCKSPACE_NAME, lockspace, 1);
|
|
||||||
syslog(LOG_ERR, "Cannot get local node id\n");
|
|
||||||
return cs_to_errno(err);
|
|
||||||
}
|
|
||||||
DEBUGLOG("Our local node id is %d\n", our_nodeid);
|
|
||||||
|
|
||||||
DEBUGLOG("Connected to Corosync\n");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _cluster_closedown(void)
|
|
||||||
{
|
|
||||||
dlm_release_lockspace(LOCKSPACE_NAME, lockspace, 1);
|
|
||||||
cpg_finalize(cpg_handle);
|
|
||||||
quorum_finalize(quorum_handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _get_our_csid(char *csid)
|
|
||||||
{
|
|
||||||
memcpy(csid, &our_nodeid, sizeof(int));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Corosync doesn't really have nmode names so we
|
|
||||||
just use the node ID in hex instead */
|
|
||||||
static int _csid_from_name(char *csid, const char *name)
|
|
||||||
{
|
|
||||||
int nodeid;
|
|
||||||
struct node_info *ninfo;
|
|
||||||
|
|
||||||
if (sscanf(name, "%x", &nodeid) == 1) {
|
|
||||||
ninfo = dm_hash_lookup_binary(node_hash, csid, COROSYNC_CSID_LEN);
|
|
||||||
if (ninfo)
|
|
||||||
return nodeid;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _name_from_csid(const char *csid, char *name)
|
|
||||||
{
|
|
||||||
struct node_info *ninfo;
|
|
||||||
|
|
||||||
ninfo = dm_hash_lookup_binary(node_hash, csid, COROSYNC_CSID_LEN);
|
|
||||||
if (!ninfo)
|
|
||||||
{
|
|
||||||
sprintf(name, "UNKNOWN %s", print_corosync_csid(csid));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sprintf(name, "%x", ninfo->nodeid);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _get_num_nodes(void)
|
|
||||||
{
|
|
||||||
DEBUGLOG("num_nodes = %d\n", num_nodes);
|
|
||||||
return num_nodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Node is now known to be running a clvmd */
|
|
||||||
static void _add_up_node(const char *csid)
|
|
||||||
{
|
|
||||||
struct node_info *ninfo;
|
|
||||||
|
|
||||||
ninfo = dm_hash_lookup_binary(node_hash, csid, COROSYNC_CSID_LEN);
|
|
||||||
if (!ninfo) {
|
|
||||||
DEBUGLOG("corosync_add_up_node no node_hash entry for csid %s\n",
|
|
||||||
print_corosync_csid(csid));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUGLOG("corosync_add_up_node %d\n", ninfo->nodeid);
|
|
||||||
|
|
||||||
ninfo->state = NODE_CLVMD;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Call a callback for each node, so the caller knows whether it's up or down */
|
|
||||||
static int _cluster_do_node_callback(struct local_client *master_client,
|
|
||||||
void (*callback)(struct local_client *,
|
|
||||||
const char *csid, int node_up))
|
|
||||||
{
|
|
||||||
struct dm_hash_node *hn;
|
|
||||||
struct node_info *ninfo;
|
|
||||||
|
|
||||||
dm_hash_iterate(hn, node_hash)
|
|
||||||
{
|
|
||||||
char csid[COROSYNC_CSID_LEN];
|
|
||||||
|
|
||||||
ninfo = dm_hash_get_data(node_hash, hn);
|
|
||||||
memcpy(csid, dm_hash_get_key(node_hash, hn), COROSYNC_CSID_LEN);
|
|
||||||
|
|
||||||
DEBUGLOG("down_callback. node %d, state = %d\n", ninfo->nodeid,
|
|
||||||
ninfo->state);
|
|
||||||
|
|
||||||
if (ninfo->state == NODE_CLVMD)
|
|
||||||
callback(master_client, csid, 1);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Real locking */
|
|
||||||
static int _lock_resource(const char *resource, int mode, int flags, int *lockid)
|
|
||||||
{
|
|
||||||
struct dlm_lksb lksb;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
DEBUGLOG("lock_resource '%s', flags=%d, mode=%d\n", resource, flags, mode);
|
|
||||||
|
|
||||||
if (flags & LKF_CONVERT)
|
|
||||||
lksb.sb_lkid = *lockid;
|
|
||||||
|
|
||||||
err = dlm_ls_lock_wait(lockspace,
|
|
||||||
mode,
|
|
||||||
&lksb,
|
|
||||||
flags,
|
|
||||||
resource,
|
|
||||||
strlen(resource),
|
|
||||||
0,
|
|
||||||
NULL, NULL, NULL);
|
|
||||||
|
|
||||||
if (err != 0)
|
|
||||||
{
|
|
||||||
DEBUGLOG("dlm_ls_lock returned %d\n", errno);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
if (lksb.sb_status != 0)
|
|
||||||
{
|
|
||||||
DEBUGLOG("dlm_ls_lock returns lksb.sb_status %d\n", lksb.sb_status);
|
|
||||||
errno = lksb.sb_status;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUGLOG("lock_resource returning %d, lock_id=%x\n", err, lksb.sb_lkid);
|
|
||||||
|
|
||||||
*lockid = lksb.sb_lkid;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int _unlock_resource(const char *resource, int lockid)
|
|
||||||
{
|
|
||||||
struct dlm_lksb lksb;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
DEBUGLOG("unlock_resource: %s lockid: %x\n", resource, lockid);
|
|
||||||
lksb.sb_lkid = lockid;
|
|
||||||
|
|
||||||
err = dlm_ls_unlock_wait(lockspace,
|
|
||||||
lockid,
|
|
||||||
0,
|
|
||||||
&lksb);
|
|
||||||
if (err != 0)
|
|
||||||
{
|
|
||||||
DEBUGLOG("Unlock returned %d\n", err);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
if (lksb.sb_status != EUNLOCK)
|
|
||||||
{
|
|
||||||
DEBUGLOG("dlm_ls_unlock_wait returns lksb.sb_status: %d\n", lksb.sb_status);
|
|
||||||
errno = lksb.sb_status;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _is_quorate(void)
|
|
||||||
{
|
|
||||||
int quorate;
|
|
||||||
if (quorum_getquorate(quorum_handle, &quorate) == CS_OK)
|
|
||||||
return quorate;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _get_main_cluster_fd(void)
|
|
||||||
{
|
|
||||||
int select_fd;
|
|
||||||
|
|
||||||
cpg_fd_get(cpg_handle, &select_fd);
|
|
||||||
return select_fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _cluster_fd_callback(struct local_client *fd, char *buf, int len,
|
|
||||||
const char *csid,
|
|
||||||
struct local_client **new_client)
|
|
||||||
{
|
|
||||||
cluster_client = fd;
|
|
||||||
*new_client = NULL;
|
|
||||||
cpg_dispatch(cpg_handle, CS_DISPATCH_ONE);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _cluster_send_message(const void *buf, int msglen, const char *csid,
|
|
||||||
const char *errtext)
|
|
||||||
{
|
|
||||||
struct iovec iov[2];
|
|
||||||
cs_error_t err;
|
|
||||||
int target_node;
|
|
||||||
|
|
||||||
if (csid)
|
|
||||||
memcpy(&target_node, csid, COROSYNC_CSID_LEN);
|
|
||||||
else
|
|
||||||
target_node = 0;
|
|
||||||
|
|
||||||
iov[0].iov_base = &target_node;
|
|
||||||
iov[0].iov_len = sizeof(int);
|
|
||||||
iov[1].iov_base = (char *)buf;
|
|
||||||
iov[1].iov_len = msglen;
|
|
||||||
|
|
||||||
err = cpg_mcast_joined(cpg_handle, CPG_TYPE_AGREED, iov, 2);
|
|
||||||
return cs_to_errno(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HAVE_COROSYNC_CONFDB_H
|
|
||||||
/*
|
|
||||||
* We are not necessarily connected to a Red Hat Cluster system,
|
|
||||||
* but if we are, this returns the cluster name from cluster.conf.
|
|
||||||
* I've used confdb rather than ccs to reduce the inter-package
|
|
||||||
* dependancies as well as to allow people to set a cluster name
|
|
||||||
* for themselves even if they are not running on RH cluster.
|
|
||||||
*/
|
|
||||||
static int _get_cluster_name(char *buf, int buflen)
|
|
||||||
{
|
|
||||||
confdb_handle_t handle;
|
|
||||||
int result;
|
|
||||||
size_t namelen = buflen;
|
|
||||||
hdb_handle_t cluster_handle;
|
|
||||||
confdb_callbacks_t callbacks = {
|
|
||||||
.confdb_key_change_notify_fn = NULL,
|
|
||||||
.confdb_object_create_change_notify_fn = NULL,
|
|
||||||
.confdb_object_delete_change_notify_fn = NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
/* This is a default in case everything else fails */
|
|
||||||
strncpy(buf, "Corosync", buflen);
|
|
||||||
|
|
||||||
/* Look for a cluster name in confdb */
|
|
||||||
result = confdb_initialize (&handle, &callbacks);
|
|
||||||
if (result != CS_OK)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
result = confdb_object_find_start(handle, OBJECT_PARENT_HANDLE);
|
|
||||||
if (result != CS_OK)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
result = confdb_object_find(handle, OBJECT_PARENT_HANDLE, (void *)"cluster", strlen("cluster"), &cluster_handle);
|
|
||||||
if (result != CS_OK)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
result = confdb_key_get(handle, cluster_handle, (void *)"name", strlen("name"), buf, &namelen);
|
|
||||||
if (result != CS_OK)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
buf[namelen] = '\0';
|
|
||||||
|
|
||||||
out:
|
|
||||||
confdb_finalize(handle);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#elif defined HAVE_COROSYNC_CMAP_H
|
|
||||||
|
|
||||||
static int _get_cluster_name(char *buf, int buflen)
|
|
||||||
{
|
|
||||||
cmap_handle_t cmap_handle = 0;
|
|
||||||
int result;
|
|
||||||
char *name = NULL;
|
|
||||||
|
|
||||||
/* This is a default in case everything else fails */
|
|
||||||
strncpy(buf, "Corosync", buflen);
|
|
||||||
|
|
||||||
/* Look for a cluster name in cmap */
|
|
||||||
result = cmap_initialize(&cmap_handle);
|
|
||||||
if (result != CS_OK)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
result = cmap_get_string(cmap_handle, "totem.cluster_name", &name);
|
|
||||||
if (result != CS_OK)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
memset(buf, 0, buflen);
|
|
||||||
strncpy(buf, name, buflen - 1);
|
|
||||||
|
|
||||||
out:
|
|
||||||
if (name)
|
|
||||||
free(name);
|
|
||||||
cmap_finalize(cmap_handle);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static struct cluster_ops _cluster_corosync_ops = {
|
|
||||||
.name = "corosync",
|
|
||||||
.cluster_init_completed = NULL,
|
|
||||||
.cluster_send_message = _cluster_send_message,
|
|
||||||
.name_from_csid = _name_from_csid,
|
|
||||||
.csid_from_name = _csid_from_name,
|
|
||||||
.get_num_nodes = _get_num_nodes,
|
|
||||||
.cluster_fd_callback = _cluster_fd_callback,
|
|
||||||
.get_main_cluster_fd = _get_main_cluster_fd,
|
|
||||||
.cluster_do_node_callback = _cluster_do_node_callback,
|
|
||||||
.is_quorate = _is_quorate,
|
|
||||||
.get_our_csid = _get_our_csid,
|
|
||||||
.add_up_node = _add_up_node,
|
|
||||||
.reread_config = NULL,
|
|
||||||
.cluster_closedown = _cluster_closedown,
|
|
||||||
.get_cluster_name = _get_cluster_name,
|
|
||||||
.sync_lock = _lock_resource,
|
|
||||||
.sync_unlock = _unlock_resource,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct cluster_ops *init_corosync_cluster(void)
|
|
||||||
{
|
|
||||||
if (!_init_cluster())
|
|
||||||
return &_cluster_corosync_ops;
|
|
||||||
else
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
1012
daemons/clvmd/clvmd-gulm.c
Normal file
1012
daemons/clvmd/clvmd-gulm.c
Normal file
File diff suppressed because it is too large
Load Diff
13
daemons/clvmd/clvmd-gulm.h
Normal file
13
daemons/clvmd/clvmd-gulm.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
|
||||||
|
/* DLM constant that clvmd uses as a generic NONBLOCK lock flag */
|
||||||
|
#define LKF_NOQUEUE 1
|
||||||
|
|
||||||
|
extern int get_next_node_csid(void **context, char *csid);
|
||||||
|
extern void add_down_node(char *csid);
|
||||||
|
extern int gulm_fd(void);
|
||||||
|
extern int get_ip_address(const char *node, char *addr);
|
||||||
|
extern void tcp_remove_client(const char *csid);
|
||||||
|
extern int alloc_client(int fd, const char *csid, struct local_client **new_client);
|
||||||
|
|
||||||
|
void gulm_add_up_node(const char *csid);
|
||||||
|
int gulm_name_from_csid(const char *csid, char *name);
|
||||||
@@ -1,35 +1,47 @@
|
|||||||
/*
|
/******************************************************************************
|
||||||
* Copyright (C) 2007-2009 Red Hat, Inc. All rights reserved.
|
*******************************************************************************
|
||||||
*
|
**
|
||||||
* This file is part of LVM2.
|
** Copyright (C) 2007 Red Hat, Inc. All rights reserved.
|
||||||
*
|
**
|
||||||
* This copyrighted material is made available to anyone wishing to use,
|
*******************************************************************************
|
||||||
* modify, copy, or redistribute it subject to the terms and conditions
|
******************************************************************************/
|
||||||
* of the GNU Lesser General Public License v.2.1.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this program; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/* This provides the interface between clvmd and OpenAIS as the cluster
|
||||||
* This provides the interface between clvmd and OpenAIS as the cluster
|
|
||||||
* and lock manager.
|
* and lock manager.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "clvmd-common.h"
|
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/utsname.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/file.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <signal.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <utmpx.h>
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <libdevmapper.h>
|
||||||
|
|
||||||
#include <openais/saAis.h>
|
#include <openais/saAis.h>
|
||||||
#include <openais/saLck.h>
|
#include <openais/saLck.h>
|
||||||
|
#include <openais/cpg.h>
|
||||||
|
|
||||||
#include <corosync/corotypes.h>
|
#include "list.h"
|
||||||
#include <corosync/cpg.h>
|
|
||||||
|
|
||||||
#include "locking.h"
|
#include "locking.h"
|
||||||
|
#include "log.h"
|
||||||
#include "clvm.h"
|
#include "clvm.h"
|
||||||
#include "clvmd-comms.h"
|
#include "clvmd-comms.h"
|
||||||
#include "lvm-functions.h"
|
#include "lvm-functions.h"
|
||||||
@@ -38,18 +50,17 @@
|
|||||||
/* Timeout value for several openais calls */
|
/* Timeout value for several openais calls */
|
||||||
#define TIMEOUT 10
|
#define TIMEOUT 10
|
||||||
|
|
||||||
static void openais_cpg_deliver_callback (cpg_handle_t handle,
|
static void cpg_deliver_callback (cpg_handle_t handle,
|
||||||
const struct cpg_name *groupName,
|
struct cpg_name *groupName,
|
||||||
uint32_t nodeid,
|
uint32_t nodeid,
|
||||||
uint32_t pid,
|
uint32_t pid,
|
||||||
void *msg,
|
void *msg,
|
||||||
size_t msg_len);
|
int msg_len);
|
||||||
static void openais_cpg_confchg_callback(cpg_handle_t handle,
|
static void cpg_confchg_callback(cpg_handle_t handle,
|
||||||
const struct cpg_name *groupName,
|
struct cpg_name *groupName,
|
||||||
const struct cpg_address *member_list, size_t member_list_entries,
|
struct cpg_address *member_list, int member_list_entries,
|
||||||
const struct cpg_address *left_list, size_t left_list_entries,
|
struct cpg_address *left_list, int left_list_entries,
|
||||||
const struct cpg_address *joined_list, size_t joined_list_entries);
|
struct cpg_address *joined_list, int joined_list_entries);
|
||||||
|
|
||||||
static void _cluster_closedown(void);
|
static void _cluster_closedown(void);
|
||||||
|
|
||||||
/* Hash list of nodes in the cluster */
|
/* Hash list of nodes in the cluster */
|
||||||
@@ -71,9 +82,9 @@ static SaLckHandleT lck_handle;
|
|||||||
static struct cpg_name cpg_group_name;
|
static struct cpg_name cpg_group_name;
|
||||||
|
|
||||||
/* Openais callback structs */
|
/* Openais callback structs */
|
||||||
cpg_callbacks_t openais_cpg_callbacks = {
|
cpg_callbacks_t cpg_callbacks = {
|
||||||
.cpg_deliver_fn = openais_cpg_deliver_callback,
|
.cpg_deliver_fn = cpg_deliver_callback,
|
||||||
.cpg_confchg_fn = openais_cpg_confchg_callback,
|
.cpg_confchg_fn = cpg_confchg_callback,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct node_info
|
struct node_info
|
||||||
@@ -181,7 +192,7 @@ static int ais_to_errno(SaAisErrorT err)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *print_openais_csid(const char *csid)
|
static char *print_csid(const char *csid)
|
||||||
{
|
{
|
||||||
static char buf[128];
|
static char buf[128];
|
||||||
int id;
|
int id;
|
||||||
@@ -197,11 +208,14 @@ static int add_internal_client(int fd, fd_callback_t callback)
|
|||||||
|
|
||||||
DEBUGLOG("Add_internal_client, fd = %d\n", fd);
|
DEBUGLOG("Add_internal_client, fd = %d\n", fd);
|
||||||
|
|
||||||
if (!(client = dm_zalloc(sizeof(*client)))) {
|
client = malloc(sizeof(struct local_client));
|
||||||
|
if (!client)
|
||||||
|
{
|
||||||
DEBUGLOG("malloc failed\n");
|
DEBUGLOG("malloc failed\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memset(client, 0, sizeof(struct local_client));
|
||||||
client->fd = fd;
|
client->fd = fd;
|
||||||
client->type = CLUSTER_INTERNAL;
|
client->type = CLUSTER_INTERNAL;
|
||||||
client->callback = callback;
|
client->callback = callback;
|
||||||
@@ -213,18 +227,18 @@ static int add_internal_client(int fd, fd_callback_t callback)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void openais_cpg_deliver_callback (cpg_handle_t handle,
|
static void cpg_deliver_callback (cpg_handle_t handle,
|
||||||
const struct cpg_name *groupName,
|
struct cpg_name *groupName,
|
||||||
uint32_t nodeid,
|
uint32_t nodeid,
|
||||||
uint32_t pid,
|
uint32_t pid,
|
||||||
void *msg,
|
void *msg,
|
||||||
size_t msg_len)
|
int msg_len)
|
||||||
{
|
{
|
||||||
int target_nodeid;
|
int target_nodeid;
|
||||||
|
|
||||||
memcpy(&target_nodeid, msg, OPENAIS_CSID_LEN);
|
memcpy(&target_nodeid, msg, OPENAIS_CSID_LEN);
|
||||||
|
|
||||||
DEBUGLOG("%u got message from nodeid %d for %d. len %" PRIsize_t "\n",
|
DEBUGLOG("%u got message from nodeid %d for %d. len %d\n",
|
||||||
our_nodeid, nodeid, target_nodeid, msg_len-4);
|
our_nodeid, nodeid, target_nodeid, msg_len-4);
|
||||||
|
|
||||||
if (nodeid != our_nodeid)
|
if (nodeid != our_nodeid)
|
||||||
@@ -233,17 +247,16 @@ static void openais_cpg_deliver_callback (cpg_handle_t handle,
|
|||||||
msg_len-OPENAIS_CSID_LEN, (char*)&nodeid);
|
msg_len-OPENAIS_CSID_LEN, (char*)&nodeid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void openais_cpg_confchg_callback(cpg_handle_t handle,
|
static void cpg_confchg_callback(cpg_handle_t handle,
|
||||||
const struct cpg_name *groupName,
|
struct cpg_name *groupName,
|
||||||
const struct cpg_address *member_list, size_t member_list_entries,
|
struct cpg_address *member_list, int member_list_entries,
|
||||||
const struct cpg_address *left_list, size_t left_list_entries,
|
struct cpg_address *left_list, int left_list_entries,
|
||||||
const struct cpg_address *joined_list, size_t joined_list_entries)
|
struct cpg_address *joined_list, int joined_list_entries)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct node_info *ninfo;
|
struct node_info *ninfo;
|
||||||
|
|
||||||
DEBUGLOG("confchg callback. %" PRIsize_t " joined, "
|
DEBUGLOG("confchg callback. %d joined, %d left, %d members\n",
|
||||||
FMTsize_t " left, %" PRIsize_t " members\n",
|
|
||||||
joined_list_entries, left_list_entries, member_list_entries);
|
joined_list_entries, left_list_entries, member_list_entries);
|
||||||
|
|
||||||
for (i=0; i<joined_list_entries; i++) {
|
for (i=0; i<joined_list_entries; i++) {
|
||||||
@@ -314,7 +327,7 @@ static int _init_cluster(void)
|
|||||||
lock_hash = dm_hash_create(10);
|
lock_hash = dm_hash_create(10);
|
||||||
|
|
||||||
err = cpg_initialize(&cpg_handle,
|
err = cpg_initialize(&cpg_handle,
|
||||||
&openais_cpg_callbacks);
|
&cpg_callbacks);
|
||||||
if (err != SA_AIS_OK) {
|
if (err != SA_AIS_OK) {
|
||||||
syslog(LOG_ERR, "Cannot initialise OpenAIS CPG service: %d",
|
syslog(LOG_ERR, "Cannot initialise OpenAIS CPG service: %d",
|
||||||
err);
|
err);
|
||||||
@@ -326,7 +339,7 @@ static int _init_cluster(void)
|
|||||||
NULL,
|
NULL,
|
||||||
&ver);
|
&ver);
|
||||||
if (err != SA_AIS_OK) {
|
if (err != SA_AIS_OK) {
|
||||||
cpg_initialize(&cpg_handle, &openais_cpg_callbacks);
|
cpg_initialize(&cpg_handle, &cpg_callbacks);
|
||||||
syslog(LOG_ERR, "Cannot initialise OpenAIS lock service: %d",
|
syslog(LOG_ERR, "Cannot initialise OpenAIS lock service: %d",
|
||||||
err);
|
err);
|
||||||
DEBUGLOG("Cannot initialise OpenAIS lock service: %d\n\n", err);
|
DEBUGLOG("Cannot initialise OpenAIS lock service: %d\n\n", err);
|
||||||
@@ -365,6 +378,9 @@ static int _init_cluster(void)
|
|||||||
|
|
||||||
static void _cluster_closedown(void)
|
static void _cluster_closedown(void)
|
||||||
{
|
{
|
||||||
|
DEBUGLOG("cluster_closedown\n");
|
||||||
|
unlock_all();
|
||||||
|
|
||||||
saLckFinalize(lck_handle);
|
saLckFinalize(lck_handle);
|
||||||
cpg_finalize(cpg_handle);
|
cpg_finalize(cpg_handle);
|
||||||
}
|
}
|
||||||
@@ -396,7 +412,7 @@ static int _name_from_csid(const char *csid, char *name)
|
|||||||
ninfo = dm_hash_lookup_binary(node_hash, csid, OPENAIS_CSID_LEN);
|
ninfo = dm_hash_lookup_binary(node_hash, csid, OPENAIS_CSID_LEN);
|
||||||
if (!ninfo)
|
if (!ninfo)
|
||||||
{
|
{
|
||||||
sprintf(name, "UNKNOWN %s", print_openais_csid(csid));
|
sprintf(name, "UNKNOWN %s", print_csid(csid));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -418,7 +434,7 @@ static void _add_up_node(const char *csid)
|
|||||||
ninfo = dm_hash_lookup_binary(node_hash, csid, OPENAIS_CSID_LEN);
|
ninfo = dm_hash_lookup_binary(node_hash, csid, OPENAIS_CSID_LEN);
|
||||||
if (!ninfo) {
|
if (!ninfo) {
|
||||||
DEBUGLOG("openais_add_up_node no node_hash entry for csid %s\n",
|
DEBUGLOG("openais_add_up_node no node_hash entry for csid %s\n",
|
||||||
print_openais_csid(csid));
|
print_csid(csid));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -500,11 +516,11 @@ static int _lock_resource(char *resource, int mode, int flags, int *lockid)
|
|||||||
saLckResourceClose(res_handle);
|
saLckResourceClose(res_handle);
|
||||||
return ais_to_errno(err);
|
return ais_to_errno(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wait for it to complete */
|
/* Wait for it to complete */
|
||||||
|
|
||||||
DEBUGLOG("lock_resource returning %d, lock_id=%" PRIx64 "\n",
|
DEBUGLOG("lock_resource returning %d, lock_id=%llx\n", err,
|
||||||
err, lock_id);
|
lock_id);
|
||||||
|
|
||||||
linfo->lock_id = lock_id;
|
linfo->lock_id = lock_id;
|
||||||
linfo->res_handle = res_handle;
|
linfo->res_handle = res_handle;
|
||||||
@@ -525,7 +541,7 @@ static int _unlock_resource(char *resource, int lockid)
|
|||||||
if (!linfo)
|
if (!linfo)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
DEBUGLOG("unlock_resource: lockid: %" PRIx64 "\n", linfo->lock_id);
|
DEBUGLOG("unlock_resource: lockid: %llx\n", linfo->lock_id);
|
||||||
err = saLckResourceUnlock(linfo->lock_id, SA_TIME_END);
|
err = saLckResourceUnlock(linfo->lock_id, SA_TIME_END);
|
||||||
if (err != SA_AIS_OK)
|
if (err != SA_AIS_OK)
|
||||||
{
|
{
|
||||||
@@ -661,7 +677,6 @@ static int _get_cluster_name(char *buf, int buflen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct cluster_ops _cluster_openais_ops = {
|
static struct cluster_ops _cluster_openais_ops = {
|
||||||
.name = "openais",
|
|
||||||
.cluster_init_completed = NULL,
|
.cluster_init_completed = NULL,
|
||||||
.cluster_send_message = _cluster_send_message,
|
.cluster_send_message = _cluster_send_message,
|
||||||
.name_from_csid = _name_from_csid,
|
.name_from_csid = _name_from_csid,
|
||||||
@@ -684,6 +699,6 @@ struct cluster_ops *init_openais_cluster(void)
|
|||||||
{
|
{
|
||||||
if (!_init_cluster())
|
if (!_init_cluster())
|
||||||
return &_cluster_openais_ops;
|
return &_cluster_openais_ops;
|
||||||
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,382 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2009-2013 Red Hat, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* This file is part of LVM2.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use,
|
|
||||||
* modify, copy, or redistribute it subject to the terms and conditions
|
|
||||||
* of the GNU Lesser General Public License v.2.1.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this program; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "clvmd-common.h"
|
|
||||||
|
|
||||||
#include <pthread.h>
|
|
||||||
|
|
||||||
#include "locking.h"
|
|
||||||
#include "clvm.h"
|
|
||||||
#include "clvmd-comms.h"
|
|
||||||
#include "clvmd.h"
|
|
||||||
|
|
||||||
#include <sys/un.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
static const char SINGLENODE_CLVMD_SOCKNAME[] = DEFAULT_RUN_DIR "/clvmd_singlenode.sock";
|
|
||||||
static int listen_fd = -1;
|
|
||||||
|
|
||||||
static struct dm_hash_table *_locks;
|
|
||||||
static int _lockid;
|
|
||||||
|
|
||||||
static pthread_mutex_t _lock_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
||||||
/* Using one common condition for all locks for simplicity */
|
|
||||||
static pthread_cond_t _lock_cond = PTHREAD_COND_INITIALIZER;
|
|
||||||
|
|
||||||
struct lock {
|
|
||||||
struct dm_list list;
|
|
||||||
int lockid;
|
|
||||||
int mode;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void close_comms(void)
|
|
||||||
{
|
|
||||||
if (listen_fd != -1 && close(listen_fd))
|
|
||||||
stack;
|
|
||||||
(void)unlink(SINGLENODE_CLVMD_SOCKNAME);
|
|
||||||
listen_fd = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int init_comms(void)
|
|
||||||
{
|
|
||||||
mode_t old_mask;
|
|
||||||
struct sockaddr_un addr = { .sun_family = AF_UNIX };
|
|
||||||
|
|
||||||
if (!dm_strncpy(addr.sun_path, SINGLENODE_CLVMD_SOCKNAME,
|
|
||||||
sizeof(addr.sun_path))) {
|
|
||||||
DEBUGLOG("%s: singlenode socket name too long.",
|
|
||||||
SINGLENODE_CLVMD_SOCKNAME);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
close_comms();
|
|
||||||
|
|
||||||
(void) dm_prepare_selinux_context(SINGLENODE_CLVMD_SOCKNAME, S_IFSOCK);
|
|
||||||
old_mask = umask(0077);
|
|
||||||
|
|
||||||
listen_fd = socket(PF_UNIX, SOCK_STREAM, 0);
|
|
||||||
if (listen_fd < 0) {
|
|
||||||
DEBUGLOG("Can't create local socket: %s\n", strerror(errno));
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
/* Set Close-on-exec */
|
|
||||||
if (fcntl(listen_fd, F_SETFD, 1)) {
|
|
||||||
DEBUGLOG("Setting CLOEXEC on client fd failed: %s\n", strerror(errno));
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bind(listen_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
|
||||||
DEBUGLOG("Can't bind local socket: %s\n", strerror(errno));
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
if (listen(listen_fd, 10) < 0) {
|
|
||||||
DEBUGLOG("Can't listen local socket: %s\n", strerror(errno));
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
umask(old_mask);
|
|
||||||
(void) dm_prepare_selinux_context(NULL, 0);
|
|
||||||
return 0;
|
|
||||||
error:
|
|
||||||
umask(old_mask);
|
|
||||||
(void) dm_prepare_selinux_context(NULL, 0);
|
|
||||||
close_comms();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _init_cluster(void)
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
|
|
||||||
if (!(_locks = dm_hash_create(128))) {
|
|
||||||
DEBUGLOG("Failed to allocate single-node hash table.\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = init_comms();
|
|
||||||
if (r) {
|
|
||||||
dm_hash_destroy(_locks);
|
|
||||||
_locks = NULL;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUGLOG("Single-node cluster initialised.\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _cluster_closedown(void)
|
|
||||||
{
|
|
||||||
close_comms();
|
|
||||||
|
|
||||||
/* If there is any awaited resource, kill it softly */
|
|
||||||
pthread_mutex_lock(&_lock_mutex);
|
|
||||||
dm_hash_destroy(_locks);
|
|
||||||
_locks = NULL;
|
|
||||||
_lockid = 0;
|
|
||||||
pthread_cond_broadcast(&_lock_cond); /* wakeup waiters */
|
|
||||||
pthread_mutex_unlock(&_lock_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _get_our_csid(char *csid)
|
|
||||||
{
|
|
||||||
int nodeid = 1;
|
|
||||||
memcpy(csid, &nodeid, sizeof(int));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _csid_from_name(char *csid, const char *name)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _name_from_csid(const char *csid, char *name)
|
|
||||||
{
|
|
||||||
strcpy(name, "SINGLENODE");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _get_num_nodes(void)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Node is now known to be running a clvmd */
|
|
||||||
static void _add_up_node(const char *csid)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Call a callback for each node, so the caller knows whether it's up or down */
|
|
||||||
static int _cluster_do_node_callback(struct local_client *master_client,
|
|
||||||
void (*callback)(struct local_client *,
|
|
||||||
const char *csid, int node_up))
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _lock_file(const char *file, uint32_t flags);
|
|
||||||
|
|
||||||
static const char *_get_mode(int mode)
|
|
||||||
{
|
|
||||||
switch (mode) {
|
|
||||||
case LCK_NULL: return "NULL";
|
|
||||||
case LCK_READ: return "READ";
|
|
||||||
case LCK_PREAD: return "PREAD";
|
|
||||||
case LCK_WRITE: return "WRITE";
|
|
||||||
case LCK_EXCL: return "EXCLUSIVE";
|
|
||||||
case LCK_UNLOCK: return "UNLOCK";
|
|
||||||
default: return "????";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Real locking */
|
|
||||||
static int _lock_resource(const char *resource, int mode, int flags, int *lockid)
|
|
||||||
{
|
|
||||||
/* DLM table of allowed transition states */
|
|
||||||
static const int _dlm_table[6][6] = {
|
|
||||||
/* Mode NL CR CW PR PW EX */
|
|
||||||
/* NL */ { 1, 1, 1, 1, 1, 1},
|
|
||||||
/* CR */ { 1, 1, 1, 1, 1, 0},
|
|
||||||
/* CW */ { 1, 1, 1, 0, 0, 0},
|
|
||||||
/* PR */ { 1, 1, 0, 1, 0, 0},
|
|
||||||
/* PW */ { 1, 1, 0, 0, 0, 0},
|
|
||||||
/* EX */ { 1, 0, 0, 0, 0, 0}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct lock *lck = NULL, *lckt;
|
|
||||||
struct dm_list *head;
|
|
||||||
|
|
||||||
DEBUGLOG("Locking resource %s, flags=0x%02x (%s%s%s), mode=%s (%d)\n",
|
|
||||||
resource, flags,
|
|
||||||
(flags & LCKF_NOQUEUE) ? "NOQUEUE" : "",
|
|
||||||
((flags & (LCKF_NOQUEUE | LCKF_CONVERT)) ==
|
|
||||||
(LCKF_NOQUEUE | LCKF_CONVERT)) ? "|" : "",
|
|
||||||
(flags & LCKF_CONVERT) ? "CONVERT" : "",
|
|
||||||
_get_mode(mode), mode);
|
|
||||||
|
|
||||||
mode &= LCK_TYPE_MASK;
|
|
||||||
pthread_mutex_lock(&_lock_mutex);
|
|
||||||
|
|
||||||
retry:
|
|
||||||
if (!(head = dm_hash_lookup(_locks, resource))) {
|
|
||||||
if (flags & LCKF_CONVERT) {
|
|
||||||
/* In real DLM, lock is identified only by lockid, resource is not used */
|
|
||||||
DEBUGLOG("Unlocked resource %s cannot be converted\n", resource);
|
|
||||||
goto_bad;
|
|
||||||
}
|
|
||||||
/* Add new locked resource */
|
|
||||||
if (!(head = dm_malloc(sizeof(struct dm_list))) ||
|
|
||||||
!dm_hash_insert(_locks, resource, head)) {
|
|
||||||
dm_free(head);
|
|
||||||
goto_bad;
|
|
||||||
}
|
|
||||||
|
|
||||||
dm_list_init(head);
|
|
||||||
} else /* Update/convert locked resource */
|
|
||||||
dm_list_iterate_items(lck, head) {
|
|
||||||
/* Check is all locks are compatible with requested lock */
|
|
||||||
if (flags & LCKF_CONVERT) {
|
|
||||||
if (lck->lockid != *lockid)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
DEBUGLOG("Converting resource %s lockid=%d mode:%s -> %s...\n",
|
|
||||||
resource, lck->lockid, _get_mode(lck->mode), _get_mode(mode));
|
|
||||||
dm_list_iterate_items(lckt, head) {
|
|
||||||
if ((lckt->lockid != *lockid) &&
|
|
||||||
!_dlm_table[mode][lckt->mode]) {
|
|
||||||
if (!(flags & LCKF_NOQUEUE) &&
|
|
||||||
/* TODO: Real dlm uses here conversion queues */
|
|
||||||
!pthread_cond_wait(&_lock_cond, &_lock_mutex) &&
|
|
||||||
_locks) /* End of the game? */
|
|
||||||
goto retry;
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lck->mode = mode; /* Lock is now converted */
|
|
||||||
goto out;
|
|
||||||
} else if (!_dlm_table[mode][lck->mode]) {
|
|
||||||
DEBUGLOG("Resource %s already locked lockid=%d, mode:%s\n",
|
|
||||||
resource, lck->lockid, _get_mode(lck->mode));
|
|
||||||
if (!(flags & LCKF_NOQUEUE) &&
|
|
||||||
!pthread_cond_wait(&_lock_cond, &_lock_mutex) &&
|
|
||||||
_locks) { /* End of the game? */
|
|
||||||
DEBUGLOG("Resource %s retrying lock in mode:%s...\n",
|
|
||||||
resource, _get_mode(mode));
|
|
||||||
goto retry;
|
|
||||||
}
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(flags & LCKF_CONVERT)) {
|
|
||||||
if (!(lck = dm_malloc(sizeof(struct lock))))
|
|
||||||
goto_bad;
|
|
||||||
|
|
||||||
*lockid = lck->lockid = ++_lockid;
|
|
||||||
lck->mode = mode;
|
|
||||||
dm_list_add(head, &lck->list);
|
|
||||||
}
|
|
||||||
out:
|
|
||||||
pthread_cond_broadcast(&_lock_cond); /* to wakeup waiters */
|
|
||||||
pthread_mutex_unlock(&_lock_mutex);
|
|
||||||
DEBUGLOG("Locked resource %s, lockid=%d, mode=%s\n",
|
|
||||||
resource, lck->lockid, _get_mode(lck->mode));
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
bad:
|
|
||||||
pthread_cond_broadcast(&_lock_cond); /* to wakeup waiters */
|
|
||||||
pthread_mutex_unlock(&_lock_mutex);
|
|
||||||
DEBUGLOG("Failed to lock resource %s\n", resource);
|
|
||||||
|
|
||||||
return 1; /* fail */
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _unlock_resource(const char *resource, int lockid)
|
|
||||||
{
|
|
||||||
struct lock *lck;
|
|
||||||
struct dm_list *head;
|
|
||||||
int r = 1;
|
|
||||||
|
|
||||||
if (lockid < 0) {
|
|
||||||
DEBUGLOG("Not tracking unlock of lockid -1: %s, lockid=%d\n",
|
|
||||||
resource, lockid);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUGLOG("Unlocking resource %s, lockid=%d\n", resource, lockid);
|
|
||||||
pthread_mutex_lock(&_lock_mutex);
|
|
||||||
pthread_cond_broadcast(&_lock_cond); /* wakeup waiters */
|
|
||||||
|
|
||||||
if (!(head = dm_hash_lookup(_locks, resource))) {
|
|
||||||
pthread_mutex_unlock(&_lock_mutex);
|
|
||||||
DEBUGLOG("Resource %s is not locked.\n", resource);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
dm_list_iterate_items(lck, head)
|
|
||||||
if (lck->lockid == lockid) {
|
|
||||||
dm_list_del(&lck->list);
|
|
||||||
dm_free(lck);
|
|
||||||
r = 0;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUGLOG("Resource %s has wrong lockid %d.\n", resource, lockid);
|
|
||||||
out:
|
|
||||||
if (dm_list_empty(head)) {
|
|
||||||
//DEBUGLOG("Resource %s is no longer hashed (lockid=%d).\n", resource, lockid);
|
|
||||||
dm_hash_remove(_locks, resource);
|
|
||||||
dm_free(head);
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&_lock_mutex);
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _is_quorate(void)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _get_main_cluster_fd(void)
|
|
||||||
{
|
|
||||||
return listen_fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _cluster_fd_callback(struct local_client *fd, char *buf, int len,
|
|
||||||
const char *csid,
|
|
||||||
struct local_client **new_client)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _cluster_send_message(const void *buf, int msglen,
|
|
||||||
const char *csid,
|
|
||||||
const char *errtext)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _get_cluster_name(char *buf, int buflen)
|
|
||||||
{
|
|
||||||
return dm_strncpy(buf, "localcluster", buflen) ? 0 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct cluster_ops _cluster_singlenode_ops = {
|
|
||||||
.name = "singlenode",
|
|
||||||
.cluster_init_completed = NULL,
|
|
||||||
.cluster_send_message = _cluster_send_message,
|
|
||||||
.name_from_csid = _name_from_csid,
|
|
||||||
.csid_from_name = _csid_from_name,
|
|
||||||
.get_num_nodes = _get_num_nodes,
|
|
||||||
.cluster_fd_callback = _cluster_fd_callback,
|
|
||||||
.get_main_cluster_fd = _get_main_cluster_fd,
|
|
||||||
.cluster_do_node_callback = _cluster_do_node_callback,
|
|
||||||
.is_quorate = _is_quorate,
|
|
||||||
.get_our_csid = _get_our_csid,
|
|
||||||
.add_up_node = _add_up_node,
|
|
||||||
.reread_config = NULL,
|
|
||||||
.cluster_closedown = _cluster_closedown,
|
|
||||||
.get_cluster_name = _get_cluster_name,
|
|
||||||
.sync_lock = _lock_resource,
|
|
||||||
.sync_unlock = _unlock_resource,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct cluster_ops *init_singlenode_cluster(void)
|
|
||||||
{
|
|
||||||
if (!_init_cluster())
|
|
||||||
return &_cluster_singlenode_ops;
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -20,6 +20,9 @@
|
|||||||
#define CLVMD_MINOR_VERSION 2
|
#define CLVMD_MINOR_VERSION 2
|
||||||
#define CLVMD_PATCH_VERSION 1
|
#define CLVMD_PATCH_VERSION 1
|
||||||
|
|
||||||
|
/* Name of the cluster LVM admin lock */
|
||||||
|
#define ADMIN_LOCK_NAME "CLVMD_ADMIN"
|
||||||
|
|
||||||
/* Default time (in seconds) we will wait for all remote commands to execute
|
/* Default time (in seconds) we will wait for all remote commands to execute
|
||||||
before declaring them dead */
|
before declaring them dead */
|
||||||
#define DEFAULT_CMD_TIMEOUT 60
|
#define DEFAULT_CMD_TIMEOUT 60
|
||||||
@@ -53,12 +56,13 @@ struct localsock_bits {
|
|||||||
int finished; /* Flag to tell subthread to exit */
|
int finished; /* Flag to tell subthread to exit */
|
||||||
int all_success; /* Set to 0 if any node (or the pre_command)
|
int all_success; /* Set to 0 if any node (or the pre_command)
|
||||||
failed */
|
failed */
|
||||||
int cleanup_needed; /* helper for cleanup_zombie */
|
|
||||||
struct local_client *pipe_client;
|
struct local_client *pipe_client;
|
||||||
pthread_t threadid;
|
pthread_t threadid;
|
||||||
enum { PRE_COMMAND, POST_COMMAND } state;
|
enum { PRE_COMMAND, POST_COMMAND, QUIT } state;
|
||||||
pthread_mutex_t mutex; /* Main thread and worker synchronisation */
|
pthread_mutex_t mutex; /* Main thread and worker synchronisation */
|
||||||
pthread_cond_t cond;
|
pthread_cond_t cond;
|
||||||
|
|
||||||
|
pthread_mutex_t reply_mutex; /* Protect reply structure */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Entries for PIPE clients */
|
/* Entries for PIPE clients */
|
||||||
@@ -94,7 +98,7 @@ struct local_client {
|
|||||||
} bits;
|
} bits;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DEBUGLOG(fmt, args...) debuglog(fmt, ## args)
|
#define DEBUGLOG(fmt, args...) debuglog(fmt, ## args);
|
||||||
|
|
||||||
#ifndef max
|
#ifndef max
|
||||||
#define max(a,b) ((a)>(b)?(a):(b))
|
#define max(a,b) ((a)>(b)?(a):(b))
|
||||||
@@ -111,15 +115,11 @@ extern void cmd_client_cleanup(struct local_client *client);
|
|||||||
extern int add_client(struct local_client *new_client);
|
extern int add_client(struct local_client *new_client);
|
||||||
|
|
||||||
extern void clvmd_cluster_init_completed(void);
|
extern void clvmd_cluster_init_completed(void);
|
||||||
extern void process_message(struct local_client *client, char *buf,
|
extern void process_message(struct local_client *client, const char *buf,
|
||||||
int len, const char *csid);
|
int len, const char *csid);
|
||||||
extern void debuglog(const char *fmt, ... )
|
extern void debuglog(const char *fmt, ... )
|
||||||
__attribute__ ((format(printf, 1, 2)));
|
__attribute__ ((format(printf, 1, 2)));
|
||||||
|
|
||||||
void clvmd_set_debug(debug_t new_de);
|
|
||||||
debug_t clvmd_get_debug(void);
|
|
||||||
int clvmd_get_foreground(void);
|
|
||||||
|
|
||||||
int sync_lock(const char *resource, int mode, int flags, int *lockid);
|
int sync_lock(const char *resource, int mode, int flags, int *lockid);
|
||||||
int sync_unlock(const char *resource, int lockid);
|
int sync_unlock(const char *resource, int lockid);
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
|
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
|
||||||
* Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved.
|
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* This file is part of LVM2.
|
* This file is part of LVM2.
|
||||||
*
|
*
|
||||||
@@ -22,20 +22,17 @@ extern int pre_lock_lv(unsigned char lock_cmd, unsigned char lock_flags,
|
|||||||
char *resource);
|
char *resource);
|
||||||
extern int do_lock_lv(unsigned char lock_cmd, unsigned char lock_flags,
|
extern int do_lock_lv(unsigned char lock_cmd, unsigned char lock_flags,
|
||||||
char *resource);
|
char *resource);
|
||||||
extern const char *do_lock_query(char *resource);
|
|
||||||
extern int post_lock_lv(unsigned char lock_cmd, unsigned char lock_flags,
|
extern int post_lock_lv(unsigned char lock_cmd, unsigned char lock_flags,
|
||||||
char *resource);
|
char *resource);
|
||||||
extern int do_check_lvm1(const char *vgname);
|
extern int do_check_lvm1(const char *vgname);
|
||||||
extern int do_refresh_cache(void);
|
extern int do_refresh_cache(void);
|
||||||
extern int init_clvm(struct dm_hash_table *excl_uuid);
|
extern int init_lvm(int using_gulm);
|
||||||
extern void destroy_lvm(void);
|
|
||||||
extern void init_lvhash(void);
|
extern void init_lvhash(void);
|
||||||
extern void destroy_lvhash(void);
|
|
||||||
extern void lvm_do_backup(const char *vgname);
|
extern void lvm_do_backup(const char *vgname);
|
||||||
|
extern int hold_unlock(char *resource);
|
||||||
|
extern int hold_lock(char *resource, int mode, int flags);
|
||||||
|
extern void unlock_all(void);
|
||||||
extern char *get_last_lvm_error(void);
|
extern char *get_last_lvm_error(void);
|
||||||
extern void do_lock_vg(unsigned char command, unsigned char lock_flags,
|
extern void drop_metadata(const char *vgname);
|
||||||
char *resource);
|
|
||||||
extern struct dm_hash_node *get_next_excl_lock(struct dm_hash_node *v, char **name);
|
|
||||||
void lvm_do_fs_unlock(void);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
|
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
|
||||||
* Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved.
|
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* This file is part of LVM2.
|
* This file is part of LVM2.
|
||||||
*
|
*
|
||||||
@@ -13,20 +13,23 @@
|
|||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* FIXME Remove duplicated functions from this file. */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Send a command to a running clvmd from the command-line
|
* Tell all clvmds in a cluster to refresh their toolcontext
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "clvmd-common.h"
|
|
||||||
|
|
||||||
#include "clvm.h"
|
|
||||||
#include "refresh_clvmd.h"
|
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <libdevmapper.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
#include "clvm.h"
|
||||||
|
#include "refresh_clvmd.h"
|
||||||
|
|
||||||
typedef struct lvm_response {
|
typedef struct lvm_response {
|
||||||
char node[255];
|
char node[255];
|
||||||
@@ -47,12 +50,7 @@ static int _clvmd_sock = -1;
|
|||||||
static int _open_local_sock(void)
|
static int _open_local_sock(void)
|
||||||
{
|
{
|
||||||
int local_socket;
|
int local_socket;
|
||||||
struct sockaddr_un sockaddr = { .sun_family = AF_UNIX };
|
struct sockaddr_un sockaddr;
|
||||||
|
|
||||||
if (!dm_strncpy(sockaddr.sun_path, CLVMD_SOCKNAME, sizeof(sockaddr.sun_path))) {
|
|
||||||
fprintf(stderr, "%s: clvmd socket name too long.", CLVMD_SOCKNAME);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Open local socket */
|
/* Open local socket */
|
||||||
if ((local_socket = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
|
if ((local_socket = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
|
||||||
@@ -60,6 +58,11 @@ static int _open_local_sock(void)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memset(&sockaddr, 0, sizeof(sockaddr));
|
||||||
|
memcpy(sockaddr.sun_path, CLVMD_SOCKNAME, sizeof(CLVMD_SOCKNAME));
|
||||||
|
|
||||||
|
sockaddr.sun_family = AF_UNIX;
|
||||||
|
|
||||||
if (connect(local_socket,(struct sockaddr *) &sockaddr,
|
if (connect(local_socket,(struct sockaddr *) &sockaddr,
|
||||||
sizeof(sockaddr))) {
|
sizeof(sockaddr))) {
|
||||||
int saved_errno = errno;
|
int saved_errno = errno;
|
||||||
@@ -77,12 +80,12 @@ static int _open_local_sock(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Send a request and return the status */
|
/* Send a request and return the status */
|
||||||
static int _send_request(const char *inbuf, int inlen, char **retbuf, int no_response)
|
static int _send_request(const char *inbuf, int inlen, char **retbuf)
|
||||||
{
|
{
|
||||||
char outbuf[PIPE_BUF];
|
char outbuf[PIPE_BUF];
|
||||||
struct clvm_header *outheader = (struct clvm_header *) outbuf;
|
struct clvm_header *outheader = (struct clvm_header *) outbuf;
|
||||||
int len;
|
int len;
|
||||||
unsigned off;
|
int off;
|
||||||
int buflen;
|
int buflen;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
@@ -94,8 +97,6 @@ static int _send_request(const char *inbuf, int inlen, char **retbuf, int no_res
|
|||||||
fprintf(stderr, "Error writing data to clvmd: %s", strerror(errno));
|
fprintf(stderr, "Error writing data to clvmd: %s", strerror(errno));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (no_response)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
/* Get the response */
|
/* Get the response */
|
||||||
reread:
|
reread:
|
||||||
@@ -151,38 +152,36 @@ static int _send_request(const char *inbuf, int inlen, char **retbuf, int no_res
|
|||||||
|
|
||||||
/* Build the structure header and parse-out wildcard node names */
|
/* Build the structure header and parse-out wildcard node names */
|
||||||
static void _build_header(struct clvm_header *head, int cmd, const char *node,
|
static void _build_header(struct clvm_header *head, int cmd, const char *node,
|
||||||
unsigned int len)
|
int len)
|
||||||
{
|
{
|
||||||
head->cmd = cmd;
|
head->cmd = cmd;
|
||||||
head->status = 0;
|
head->status = 0;
|
||||||
head->flags = 0;
|
head->flags = 0;
|
||||||
head->xid = 0;
|
|
||||||
head->clientid = 0;
|
head->clientid = 0;
|
||||||
if (len)
|
head->arglen = len;
|
||||||
/* 1 byte is used from struct clvm_header.args[1], so -> len - 1 */
|
|
||||||
head->arglen = len - 1;
|
|
||||||
else {
|
|
||||||
head->arglen = 0;
|
|
||||||
*head->args = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
if (node) {
|
||||||
* Translate special node names.
|
/*
|
||||||
*/
|
* Allow a couple of special node names:
|
||||||
if (!node || !strcmp(node, NODE_ALL))
|
* "*" for all nodes,
|
||||||
head->node[0] = '\0';
|
* "." for the local node only
|
||||||
else if (!strcmp(node, NODE_LOCAL)) {
|
*/
|
||||||
head->node[0] = '\0';
|
if (strcmp(node, "*") == 0) {
|
||||||
head->flags = CLVMD_FLAG_LOCAL;
|
head->node[0] = '\0';
|
||||||
|
} else if (strcmp(node, ".") == 0) {
|
||||||
|
head->node[0] = '\0';
|
||||||
|
head->flags = CLVMD_FLAG_LOCAL;
|
||||||
|
} else
|
||||||
|
strcpy(head->node, node);
|
||||||
} else
|
} else
|
||||||
strcpy(head->node, node);
|
head->node[0] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Send a message to a(or all) node(s) in the cluster and wait for replies
|
* Send a message to a(or all) node(s) in the cluster and wait for replies
|
||||||
*/
|
*/
|
||||||
static int _cluster_request(char cmd, const char *node, void *data, int len,
|
static int _cluster_request(char cmd, const char *node, void *data, int len,
|
||||||
lvm_response_t ** response, int *num, int no_response)
|
lvm_response_t ** response, int *num)
|
||||||
{
|
{
|
||||||
char outbuf[sizeof(struct clvm_header) + len + strlen(node) + 1];
|
char outbuf[sizeof(struct clvm_header) + len + strlen(node) + 1];
|
||||||
char *inptr;
|
char *inptr;
|
||||||
@@ -202,12 +201,11 @@ static int _cluster_request(char cmd, const char *node, void *data, int len,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
_build_header(head, cmd, node, len);
|
_build_header(head, cmd, node, len);
|
||||||
if (len)
|
memcpy(head->node + strlen(head->node) + 1, data, len);
|
||||||
memcpy(head->node + strlen(head->node) + 1, data, len);
|
|
||||||
|
|
||||||
status = _send_request(outbuf, sizeof(struct clvm_header) +
|
status = _send_request(outbuf, sizeof(struct clvm_header) +
|
||||||
strlen(head->node) + len, &retbuf, no_response);
|
strlen(head->node) + len, &retbuf);
|
||||||
if (!status || no_response)
|
if (!status)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* Count the number of responses we got */
|
/* Count the number of responses we got */
|
||||||
@@ -225,14 +223,16 @@ static int _cluster_request(char cmd, const char *node, void *data, int len,
|
|||||||
* With an extra pair of INTs on the front to sanity
|
* With an extra pair of INTs on the front to sanity
|
||||||
* check the pointer when we are given it back to free
|
* check the pointer when we are given it back to free
|
||||||
*/
|
*/
|
||||||
*response = NULL;
|
*response = dm_malloc(sizeof(lvm_response_t) * num_responses +
|
||||||
if (!(rarray = dm_malloc(sizeof(lvm_response_t) * num_responses +
|
sizeof(int) * 2);
|
||||||
sizeof(int) * 2))) {
|
if (!*response) {
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
status = 0;
|
status = 0;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rarray = *response;
|
||||||
|
|
||||||
/* Unpack the response into an lvm_response_t array */
|
/* Unpack the response into an lvm_response_t array */
|
||||||
inptr = head->args;
|
inptr = head->args;
|
||||||
i = 0;
|
i = 0;
|
||||||
@@ -249,9 +249,9 @@ static int _cluster_request(char cmd, const char *node, void *data, int len,
|
|||||||
int j;
|
int j;
|
||||||
for (j = 0; j < i; j++)
|
for (j = 0; j < i; j++)
|
||||||
dm_free(rarray[i].response);
|
dm_free(rarray[i].response);
|
||||||
dm_free(rarray);
|
free(*response);
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
status = 0;
|
status = -1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,7 +264,8 @@ static int _cluster_request(char cmd, const char *node, void *data, int len,
|
|||||||
*response = rarray;
|
*response = rarray;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
dm_free(retbuf);
|
if (retbuf)
|
||||||
|
dm_free(retbuf);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@@ -283,16 +284,16 @@ static int _cluster_free_request(lvm_response_t * response, int num)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int refresh_clvmd(int all_nodes)
|
int refresh_clvmd()
|
||||||
{
|
{
|
||||||
int num_responses;
|
int num_responses;
|
||||||
char args[1]; // No args really.
|
char args[1]; // No args really.
|
||||||
lvm_response_t *response = NULL;
|
lvm_response_t *response;
|
||||||
int saved_errno;
|
int saved_errno;
|
||||||
int status;
|
int status;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
status = _cluster_request(CLVMD_CMD_REFRESH, all_nodes ? NODE_ALL : NODE_LOCAL, args, 0, &response, &num_responses, 0);
|
status = _cluster_request(CLVMD_CMD_REFRESH, "*", args, 0, &response, &num_responses);
|
||||||
|
|
||||||
/* If any nodes were down then display them and return an error */
|
/* If any nodes were down then display them and return an error */
|
||||||
for (i = 0; i < num_responses; i++) {
|
for (i = 0; i < num_responses; i++) {
|
||||||
@@ -319,42 +320,23 @@ int refresh_clvmd(int all_nodes)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
int restart_clvmd(int all_nodes)
|
|
||||||
{
|
|
||||||
int dummy, status;
|
|
||||||
|
|
||||||
status = _cluster_request(CLVMD_CMD_RESTART, all_nodes ? NODE_ALL : NODE_LOCAL, NULL, 0, NULL, &dummy, 1);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* FIXME: we cannot receive response, clvmd re-exec before it.
|
|
||||||
* but also should not close socket too early (the whole rq is dropped then).
|
|
||||||
* FIXME: This should be handled this way:
|
|
||||||
* - client waits for RESTART ack (and socket close)
|
|
||||||
* - server restarts
|
|
||||||
* - client checks that server is ready again (VERSION command?)
|
|
||||||
*/
|
|
||||||
usleep(500000);
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
int debug_clvmd(int level, int clusterwide)
|
int debug_clvmd(int level, int clusterwide)
|
||||||
{
|
{
|
||||||
int num_responses;
|
int num_responses;
|
||||||
char args[1];
|
char args[1];
|
||||||
const char *nodes;
|
const char *nodes;
|
||||||
lvm_response_t *response = NULL;
|
lvm_response_t *response;
|
||||||
int saved_errno;
|
int saved_errno;
|
||||||
int status;
|
int status;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
args[0] = level;
|
args[0] = level;
|
||||||
if (clusterwide)
|
if (clusterwide)
|
||||||
nodes = NODE_ALL;
|
nodes = "*";
|
||||||
else
|
else
|
||||||
nodes = NODE_LOCAL;
|
nodes = ".";
|
||||||
|
|
||||||
status = _cluster_request(CLVMD_CMD_SET_DEBUG, nodes, args, 1, &response, &num_responses, 0);
|
status = _cluster_request(CLVMD_CMD_SET_DEBUG, nodes, args, 1, &response, &num_responses);
|
||||||
|
|
||||||
/* If any nodes were down then display them and return an error */
|
/* If any nodes were down then display them and return an error */
|
||||||
for (i = 0; i < num_responses; i++) {
|
for (i = 0; i < num_responses; i++) {
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
int refresh_clvmd(int all_nodes);
|
int refresh_clvmd(void);
|
||||||
int restart_clvmd(int all_nodes);
|
|
||||||
int debug_clvmd(int level, int clusterwide);
|
int debug_clvmd(int level, int clusterwide);
|
||||||
|
|
||||||
|
|||||||
501
daemons/clvmd/tcp-comms.c
Normal file
501
daemons/clvmd/tcp-comms.c
Normal file
@@ -0,0 +1,501 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
*******************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) Sistina Software, Inc. 2002-2003 All rights reserved.
|
||||||
|
** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
|
||||||
|
**
|
||||||
|
*******************************************************************************
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/* This provides the inter-clvmd communications for a system without CMAN.
|
||||||
|
There is a listening TCP socket which accepts new connections in the
|
||||||
|
normal way.
|
||||||
|
It can also make outgoing connnections to the other clvmd nodes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/utsname.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <libdevmapper.h>
|
||||||
|
|
||||||
|
#include "clvm.h"
|
||||||
|
#include "clvmd-comms.h"
|
||||||
|
#include "clvmd.h"
|
||||||
|
#include "clvmd-gulm.h"
|
||||||
|
|
||||||
|
#define DEFAULT_TCP_PORT 21064
|
||||||
|
|
||||||
|
static int listen_fd = -1;
|
||||||
|
static int tcp_port;
|
||||||
|
struct dm_hash_table *sock_hash;
|
||||||
|
|
||||||
|
static int get_our_ip_address(char *addr, int *family);
|
||||||
|
static int read_from_tcpsock(struct local_client *fd, char *buf, int len, char *csid,
|
||||||
|
struct local_client **new_client);
|
||||||
|
|
||||||
|
/* Called by init_cluster() to open up the listening socket */
|
||||||
|
int init_comms(unsigned short port)
|
||||||
|
{
|
||||||
|
struct sockaddr_in6 addr;
|
||||||
|
|
||||||
|
sock_hash = dm_hash_create(100);
|
||||||
|
tcp_port = port ? : DEFAULT_TCP_PORT;
|
||||||
|
|
||||||
|
listen_fd = socket(AF_INET6, SOCK_STREAM, 0);
|
||||||
|
|
||||||
|
if (listen_fd < 0)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int one = 1;
|
||||||
|
setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(int));
|
||||||
|
setsockopt(listen_fd, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof(int));
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&addr, 0, sizeof(addr)); // Bind to INADDR_ANY
|
||||||
|
addr.sin6_family = AF_INET6;
|
||||||
|
addr.sin6_port = htons(tcp_port);
|
||||||
|
|
||||||
|
if (bind(listen_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
|
||||||
|
{
|
||||||
|
DEBUGLOG("Can't bind to port: %s\n", strerror(errno));
|
||||||
|
syslog(LOG_ERR, "Can't bind to port %d, is clvmd already running ?", tcp_port);
|
||||||
|
close(listen_fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
listen(listen_fd, 5);
|
||||||
|
|
||||||
|
/* Set Close-on-exec */
|
||||||
|
fcntl(listen_fd, F_SETFD, 1);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tcp_remove_client(const char *c_csid)
|
||||||
|
{
|
||||||
|
struct local_client *client;
|
||||||
|
char csid[GULM_MAX_CSID_LEN];
|
||||||
|
unsigned int i;
|
||||||
|
memcpy(csid, c_csid, sizeof csid);
|
||||||
|
DEBUGLOG("tcp_remove_client\n");
|
||||||
|
|
||||||
|
/* Don't actually close the socket here - that's the
|
||||||
|
job of clvmd.c whch will do the job when it notices the
|
||||||
|
other end has gone. We just need to remove the client(s) from
|
||||||
|
the hash table so we don't try to use it for sending any more */
|
||||||
|
for (i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
client = dm_hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
|
||||||
|
if (client)
|
||||||
|
{
|
||||||
|
dm_hash_remove_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
|
||||||
|
client->removeme = 1;
|
||||||
|
close(client->fd);
|
||||||
|
}
|
||||||
|
/* Look for a mangled one too, on the 2nd iteration. */
|
||||||
|
csid[0] ^= 0x80;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int alloc_client(int fd, const char *c_csid, struct local_client **new_client)
|
||||||
|
{
|
||||||
|
struct local_client *client;
|
||||||
|
char csid[GULM_MAX_CSID_LEN];
|
||||||
|
memcpy(csid, c_csid, sizeof csid);
|
||||||
|
|
||||||
|
DEBUGLOG("alloc_client %d csid = %s\n", fd, print_csid(csid));
|
||||||
|
|
||||||
|
/* Create a local_client and return it */
|
||||||
|
client = malloc(sizeof(struct local_client));
|
||||||
|
if (!client)
|
||||||
|
{
|
||||||
|
DEBUGLOG("malloc failed\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(client, 0, sizeof(struct local_client));
|
||||||
|
client->fd = fd;
|
||||||
|
client->type = CLUSTER_DATA_SOCK;
|
||||||
|
client->callback = read_from_tcpsock;
|
||||||
|
if (new_client)
|
||||||
|
*new_client = client;
|
||||||
|
|
||||||
|
/* Add to our list of node sockets */
|
||||||
|
if (dm_hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN))
|
||||||
|
{
|
||||||
|
DEBUGLOG("alloc_client mangling CSID for second connection\n");
|
||||||
|
/* This is a duplicate connection but we can't close it because
|
||||||
|
the other end may already have started sending.
|
||||||
|
So, we mangle the IP address and keep it, all sending will
|
||||||
|
go out of the main FD
|
||||||
|
*/
|
||||||
|
csid[0] ^= 0x80;
|
||||||
|
client->bits.net.flags = 1; /* indicate mangled CSID */
|
||||||
|
|
||||||
|
/* If it still exists then kill the connection as we should only
|
||||||
|
ever have one incoming connection from each node */
|
||||||
|
if (dm_hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN))
|
||||||
|
{
|
||||||
|
DEBUGLOG("Multiple incoming connections from node\n");
|
||||||
|
syslog(LOG_ERR, " Bogus incoming connection from %d.%d.%d.%d\n", csid[0],csid[1],csid[2],csid[3]);
|
||||||
|
|
||||||
|
free(client);
|
||||||
|
errno = ECONNREFUSED;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dm_hash_insert_binary(sock_hash, csid, GULM_MAX_CSID_LEN, client);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_main_gulm_cluster_fd()
|
||||||
|
{
|
||||||
|
return listen_fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Read on main comms (listen) socket, accept it */
|
||||||
|
int cluster_fd_gulm_callback(struct local_client *fd, char *buf, int len, const char *csid,
|
||||||
|
struct local_client **new_client)
|
||||||
|
{
|
||||||
|
int newfd;
|
||||||
|
struct sockaddr_in6 addr;
|
||||||
|
socklen_t addrlen = sizeof(addr);
|
||||||
|
int status;
|
||||||
|
char name[GULM_MAX_CLUSTER_MEMBER_NAME_LEN];
|
||||||
|
|
||||||
|
DEBUGLOG("cluster_fd_callback\n");
|
||||||
|
*new_client = NULL;
|
||||||
|
newfd = accept(listen_fd, (struct sockaddr *)&addr, &addrlen);
|
||||||
|
|
||||||
|
DEBUGLOG("cluster_fd_callback, newfd=%d (errno=%d)\n", newfd, errno);
|
||||||
|
if (!newfd)
|
||||||
|
{
|
||||||
|
syslog(LOG_ERR, "error in accept: %m");
|
||||||
|
errno = EAGAIN;
|
||||||
|
return -1; /* Don't return an error or clvmd will close the listening FD */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check that the client is a member of the cluster
|
||||||
|
and reject if not.
|
||||||
|
*/
|
||||||
|
if (gulm_name_from_csid((char *)&addr.sin6_addr, name) < 0)
|
||||||
|
{
|
||||||
|
syslog(LOG_ERR, "Got connect from non-cluster node %s\n",
|
||||||
|
print_csid((char *)&addr.sin6_addr));
|
||||||
|
DEBUGLOG("Got connect from non-cluster node %s\n",
|
||||||
|
print_csid((char *)&addr.sin6_addr));
|
||||||
|
close(newfd);
|
||||||
|
|
||||||
|
errno = EAGAIN;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = alloc_client(newfd, (char *)&addr.sin6_addr, new_client);
|
||||||
|
if (status)
|
||||||
|
{
|
||||||
|
DEBUGLOG("cluster_fd_callback, alloc_client failed, status = %d\n", status);
|
||||||
|
close(newfd);
|
||||||
|
/* See above... */
|
||||||
|
errno = EAGAIN;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
DEBUGLOG("cluster_fd_callback, returning %d, %p\n", newfd, *new_client);
|
||||||
|
return newfd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try to get at least 'len' bytes from the socket */
|
||||||
|
static int really_read(int fd, char *buf, int len)
|
||||||
|
{
|
||||||
|
int got, offset;
|
||||||
|
|
||||||
|
got = offset = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
got = read(fd, buf+offset, len-offset);
|
||||||
|
DEBUGLOG("really_read. got %d bytes\n", got);
|
||||||
|
offset += got;
|
||||||
|
} while (got > 0 && offset < len);
|
||||||
|
|
||||||
|
if (got < 0)
|
||||||
|
return got;
|
||||||
|
else
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int read_from_tcpsock(struct local_client *client, char *buf, int len, char *csid,
|
||||||
|
struct local_client **new_client)
|
||||||
|
{
|
||||||
|
struct sockaddr_in6 addr;
|
||||||
|
socklen_t slen = sizeof(addr);
|
||||||
|
struct clvm_header *header = (struct clvm_header *)buf;
|
||||||
|
int status;
|
||||||
|
uint32_t arglen;
|
||||||
|
|
||||||
|
DEBUGLOG("read_from_tcpsock fd %d\n", client->fd);
|
||||||
|
*new_client = NULL;
|
||||||
|
|
||||||
|
/* Get "csid" */
|
||||||
|
getpeername(client->fd, (struct sockaddr *)&addr, &slen);
|
||||||
|
memcpy(csid, &addr.sin6_addr, GULM_MAX_CSID_LEN);
|
||||||
|
|
||||||
|
/* Read just the header first, then get the rest if there is any.
|
||||||
|
* Stream sockets, sigh.
|
||||||
|
*/
|
||||||
|
status = really_read(client->fd, buf, sizeof(struct clvm_header));
|
||||||
|
if (status > 0)
|
||||||
|
{
|
||||||
|
int status2;
|
||||||
|
|
||||||
|
arglen = ntohl(header->arglen);
|
||||||
|
|
||||||
|
/* Get the rest */
|
||||||
|
if (arglen && arglen < GULM_MAX_CLUSTER_MESSAGE)
|
||||||
|
{
|
||||||
|
status2 = really_read(client->fd, buf+status, arglen);
|
||||||
|
if (status2 > 0)
|
||||||
|
status += status2;
|
||||||
|
else
|
||||||
|
status = status2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUGLOG("read_from_tcpsock, status = %d(errno = %d)\n", status, errno);
|
||||||
|
|
||||||
|
/* Remove it from the hash table if there's an error, clvmd will
|
||||||
|
remove the socket from its lists and free the client struct */
|
||||||
|
if (status == 0 ||
|
||||||
|
(status < 0 && errno != EAGAIN && errno != EINTR))
|
||||||
|
{
|
||||||
|
char remcsid[GULM_MAX_CSID_LEN];
|
||||||
|
|
||||||
|
memcpy(remcsid, csid, GULM_MAX_CSID_LEN);
|
||||||
|
close(client->fd);
|
||||||
|
|
||||||
|
/* If the csid was mangled, then make sure we remove the right entry */
|
||||||
|
if (client->bits.net.flags)
|
||||||
|
remcsid[0] ^= 0x80;
|
||||||
|
dm_hash_remove_binary(sock_hash, remcsid, GULM_MAX_CSID_LEN);
|
||||||
|
|
||||||
|
/* Tell cluster manager layer */
|
||||||
|
add_down_node(remcsid);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
gulm_add_up_node(csid);
|
||||||
|
/* Send it back to clvmd */
|
||||||
|
process_message(client, buf, status, csid);
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int gulm_connect_csid(const char *csid, struct local_client **newclient)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
struct sockaddr_in6 addr;
|
||||||
|
int status;
|
||||||
|
int one = 1;
|
||||||
|
|
||||||
|
DEBUGLOG("Connecting socket\n");
|
||||||
|
fd = socket(PF_INET6, SOCK_STREAM, 0);
|
||||||
|
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
syslog(LOG_ERR, "Unable to create new socket: %m");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
addr.sin6_family = AF_INET6;
|
||||||
|
memcpy(&addr.sin6_addr, csid, GULM_MAX_CSID_LEN);
|
||||||
|
addr.sin6_port = htons(tcp_port);
|
||||||
|
|
||||||
|
DEBUGLOG("Connecting socket %d\n", fd);
|
||||||
|
if (connect(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in6)) < 0)
|
||||||
|
{
|
||||||
|
/* "Connection refused" is "normal" because clvmd may not yet be running
|
||||||
|
* on that node.
|
||||||
|
*/
|
||||||
|
if (errno != ECONNREFUSED)
|
||||||
|
{
|
||||||
|
syslog(LOG_ERR, "Unable to connect to remote node: %m");
|
||||||
|
}
|
||||||
|
DEBUGLOG("Unable to connect to remote node: %s\n", strerror(errno));
|
||||||
|
close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set Close-on-exec */
|
||||||
|
fcntl(fd, F_SETFD, 1);
|
||||||
|
setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof(int));
|
||||||
|
|
||||||
|
status = alloc_client(fd, csid, newclient);
|
||||||
|
if (status)
|
||||||
|
close(fd);
|
||||||
|
else
|
||||||
|
add_client(*newclient);
|
||||||
|
|
||||||
|
/* If we can connect to it, it must be running a clvmd */
|
||||||
|
gulm_add_up_node(csid);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send a message to a known CSID */
|
||||||
|
static int tcp_send_message(void *buf, int msglen, const char *csid, const char *errtext)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
struct local_client *client;
|
||||||
|
char ourcsid[GULM_MAX_CSID_LEN];
|
||||||
|
|
||||||
|
assert(csid);
|
||||||
|
|
||||||
|
DEBUGLOG("tcp_send_message, csid = %s, msglen = %d\n", print_csid(csid), msglen);
|
||||||
|
|
||||||
|
/* Don't connect to ourself */
|
||||||
|
get_our_gulm_csid(ourcsid);
|
||||||
|
if (memcmp(csid, ourcsid, GULM_MAX_CSID_LEN) == 0)
|
||||||
|
return msglen;
|
||||||
|
|
||||||
|
client = dm_hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
|
||||||
|
if (!client)
|
||||||
|
{
|
||||||
|
status = gulm_connect_csid(csid, &client);
|
||||||
|
if (status)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
DEBUGLOG("tcp_send_message, fd = %d\n", client->fd);
|
||||||
|
|
||||||
|
return write(client->fd, buf, msglen);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int gulm_cluster_send_message(void *buf, int msglen, const char *csid, const char *errtext)
|
||||||
|
{
|
||||||
|
int status=0;
|
||||||
|
|
||||||
|
DEBUGLOG("cluster send message, csid = %p, msglen = %d\n", csid, msglen);
|
||||||
|
|
||||||
|
/* If csid is NULL then send to all known (not just connected) nodes */
|
||||||
|
if (!csid)
|
||||||
|
{
|
||||||
|
void *context = NULL;
|
||||||
|
char loop_csid[GULM_MAX_CSID_LEN];
|
||||||
|
|
||||||
|
/* Loop round all gulm-known nodes */
|
||||||
|
while (get_next_node_csid(&context, loop_csid))
|
||||||
|
{
|
||||||
|
status = tcp_send_message(buf, msglen, loop_csid, errtext);
|
||||||
|
if (status == 0 ||
|
||||||
|
(status < 0 && (errno == EAGAIN || errno == EINTR)))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
status = tcp_send_message(buf, msglen, csid, errtext);
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* To get our own IP address we get the locally bound address of the
|
||||||
|
socket that's talking to GULM in the assumption(eek) that it will
|
||||||
|
be on the "right" network in a multi-homed system */
|
||||||
|
static int get_our_ip_address(char *addr, int *family)
|
||||||
|
{
|
||||||
|
struct utsname info;
|
||||||
|
|
||||||
|
uname(&info);
|
||||||
|
get_ip_address(info.nodename, addr);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Public version of above for those that don't care what protocol
|
||||||
|
we're using */
|
||||||
|
void get_our_gulm_csid(char *csid)
|
||||||
|
{
|
||||||
|
static char our_csid[GULM_MAX_CSID_LEN];
|
||||||
|
static int got_csid = 0;
|
||||||
|
|
||||||
|
if (!got_csid)
|
||||||
|
{
|
||||||
|
int family;
|
||||||
|
|
||||||
|
memset(our_csid, 0, sizeof(our_csid));
|
||||||
|
if (get_our_ip_address(our_csid, &family))
|
||||||
|
{
|
||||||
|
got_csid = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
memcpy(csid, our_csid, GULM_MAX_CSID_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void map_v4_to_v6(struct in_addr *ip4, struct in6_addr *ip6)
|
||||||
|
{
|
||||||
|
ip6->s6_addr32[0] = 0;
|
||||||
|
ip6->s6_addr32[1] = 0;
|
||||||
|
ip6->s6_addr32[2] = htonl(0xffff);
|
||||||
|
ip6->s6_addr32[3] = ip4->s_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get someone else's IP address from DNS */
|
||||||
|
int get_ip_address(const char *node, char *addr)
|
||||||
|
{
|
||||||
|
struct hostent *he;
|
||||||
|
|
||||||
|
memset(addr, 0, GULM_MAX_CSID_LEN);
|
||||||
|
|
||||||
|
// TODO: what do we do about multi-homed hosts ???
|
||||||
|
// CCSs ip_interfaces solved this but some bugger removed it.
|
||||||
|
|
||||||
|
/* Try IPv6 first. The man page for gethostbyname implies that
|
||||||
|
it will lookup ip6 & ip4 names, but it seems not to */
|
||||||
|
he = gethostbyname2(node, AF_INET6);
|
||||||
|
if (he)
|
||||||
|
{
|
||||||
|
memcpy(addr, he->h_addr_list[0],
|
||||||
|
he->h_length);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
he = gethostbyname2(node, AF_INET);
|
||||||
|
if (!he)
|
||||||
|
return -1;
|
||||||
|
map_v4_to_v6((struct in_addr *)he->h_addr_list[0], (struct in6_addr *)addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *print_csid(const char *csid)
|
||||||
|
{
|
||||||
|
static char buf[128];
|
||||||
|
int *icsid = (int *)csid;
|
||||||
|
|
||||||
|
sprintf(buf, "[%x.%x.%x.%x]",
|
||||||
|
icsid[0],icsid[1],icsid[2],icsid[3]);
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
13
daemons/clvmd/tcp-comms.h
Normal file
13
daemons/clvmd/tcp-comms.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
#define GULM_MAX_CLUSTER_MESSAGE 1600
|
||||||
|
#define GULM_MAX_CSID_LEN sizeof(struct in6_addr)
|
||||||
|
#define GULM_MAX_CLUSTER_MEMBER_NAME_LEN 128
|
||||||
|
|
||||||
|
extern int init_comms(unsigned short);
|
||||||
|
extern char *print_csid(const char *);
|
||||||
|
int get_main_gulm_cluster_fd(void);
|
||||||
|
int cluster_fd_gulm_callback(struct local_client *fd, char *buf, int len, const char *csid, struct local_client **new_client);
|
||||||
|
int gulm_cluster_send_message(void *buf, int msglen, const char *csid, const char *errtext);
|
||||||
|
void get_our_gulm_csid(char *csid);
|
||||||
|
int gulm_connect_csid(const char *csid, struct local_client **newclient);
|
||||||
1
daemons/cmirrord/.gitignore
vendored
1
daemons/cmirrord/.gitignore
vendored
@@ -1 +0,0 @@
|
|||||||
cmirrord
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
#
|
|
||||||
# Copyright (C) 2009-2010 Red Hat, Inc. All rights reserved.
|
|
||||||
#
|
|
||||||
# This file is part of LVM2.
|
|
||||||
#
|
|
||||||
# This copyrighted material is made available to anyone wishing to use,
|
|
||||||
# modify, copy, or redistribute it subject to the terms and conditions
|
|
||||||
# of the GNU General Public License v.2.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation,
|
|
||||||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
srcdir = @srcdir@
|
|
||||||
top_srcdir = @top_srcdir@
|
|
||||||
top_builddir = @top_builddir@
|
|
||||||
|
|
||||||
CPG_LIBS = @CPG_LIBS@
|
|
||||||
CPG_CFLAGS = @CPG_CFLAGS@
|
|
||||||
SACKPT_LIBS = @SACKPT_LIBS@
|
|
||||||
SACKPT_CFLAGS = @SACKPT_CFLAGS@
|
|
||||||
|
|
||||||
SOURCES = clogd.c cluster.c compat.c functions.c link_mon.c local.c logging.c
|
|
||||||
|
|
||||||
TARGETS = cmirrord
|
|
||||||
|
|
||||||
include $(top_builddir)/make.tmpl
|
|
||||||
|
|
||||||
LIBS += -ldevmapper
|
|
||||||
LMLIBS += $(CPG_LIBS) $(SACKPT_LIBS)
|
|
||||||
CFLAGS += $(CPG_CFLAGS) $(SACKPT_CFLAGS) $(EXTRA_EXEC_CFLAGS)
|
|
||||||
LDFLAGS += $(EXTRA_EXEC_LDFLAGS)
|
|
||||||
|
|
||||||
cmirrord: $(OBJECTS) $(top_builddir)/lib/liblvm-internal.a
|
|
||||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJECTS) \
|
|
||||||
$(LVMLIBS) $(LMLIBS) $(LIBS)
|
|
||||||
|
|
||||||
install: $(TARGETS)
|
|
||||||
$(INSTALL_PROGRAM) -D cmirrord $(usrsbindir)/cmirrord
|
|
||||||
@@ -1,292 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use,
|
|
||||||
* modify, copy, or redistribute it subject to the terms and conditions
|
|
||||||
* of the GNU General Public License v.2.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
#include "logging.h"
|
|
||||||
#include "common.h"
|
|
||||||
#include "functions.h"
|
|
||||||
#include "link_mon.h"
|
|
||||||
#include "local.h"
|
|
||||||
|
|
||||||
#include <getopt.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
static volatile sig_atomic_t exit_now = 0;
|
|
||||||
/* FIXME Review signal handling. Should be volatile sig_atomic_t */
|
|
||||||
static sigset_t signal_mask;
|
|
||||||
static volatile sig_atomic_t signal_received;
|
|
||||||
|
|
||||||
static void process_signals(void);
|
|
||||||
static void daemonize(void);
|
|
||||||
static void init_all(void);
|
|
||||||
static void cleanup_all(void);
|
|
||||||
|
|
||||||
static void usage (FILE *dest)
|
|
||||||
{
|
|
||||||
fprintf (dest, "Usage: cmirrord [options]\n"
|
|
||||||
" -f, --foreground stay in the foreground, log to the terminal\n"
|
|
||||||
" -h, --help print this help\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
int foreground_mode = 0;
|
|
||||||
struct option longopts[] = {
|
|
||||||
{ "foreground", no_argument, NULL, 'f' },
|
|
||||||
{ "help" , no_argument, NULL, 'h' },
|
|
||||||
{ 0, 0, 0, 0 }
|
|
||||||
};
|
|
||||||
int opt;
|
|
||||||
|
|
||||||
while ((opt = getopt_long (argc, argv, "fh", longopts, NULL)) != -1) {
|
|
||||||
switch (opt) {
|
|
||||||
case 'f':
|
|
||||||
foreground_mode = 1;
|
|
||||||
break;
|
|
||||||
case 'h':
|
|
||||||
usage (stdout);
|
|
||||||
exit (0);
|
|
||||||
default:
|
|
||||||
usage (stderr);
|
|
||||||
exit (2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (optind < argc) {
|
|
||||||
usage (stderr);
|
|
||||||
exit (2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!foreground_mode)
|
|
||||||
daemonize();
|
|
||||||
|
|
||||||
init_all();
|
|
||||||
|
|
||||||
/* Parent can now exit, we're ready to handle requests */
|
|
||||||
if (!foreground_mode)
|
|
||||||
kill(getppid(), SIGTERM);
|
|
||||||
|
|
||||||
LOG_PRINT("Starting cmirrord:");
|
|
||||||
LOG_PRINT(" Built: "__DATE__" "__TIME__"\n");
|
|
||||||
LOG_DBG(" Compiled with debugging.");
|
|
||||||
|
|
||||||
while (!exit_now) {
|
|
||||||
links_monitor();
|
|
||||||
|
|
||||||
links_issue_callbacks();
|
|
||||||
|
|
||||||
process_signals();
|
|
||||||
}
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* parent_exit_handler: exit the parent
|
|
||||||
* @sig: the signal
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static void parent_exit_handler(int sig __attribute__((unused)))
|
|
||||||
{
|
|
||||||
exit_now = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void sig_handler(int sig)
|
|
||||||
{
|
|
||||||
/* FIXME Races - don't touch signal_mask here. */
|
|
||||||
sigaddset(&signal_mask, sig);
|
|
||||||
signal_received = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void process_signal(int sig){
|
|
||||||
int r = 0;
|
|
||||||
|
|
||||||
switch(sig) {
|
|
||||||
case SIGINT:
|
|
||||||
case SIGQUIT:
|
|
||||||
case SIGTERM:
|
|
||||||
case SIGHUP:
|
|
||||||
r += log_status();
|
|
||||||
break;
|
|
||||||
case SIGUSR1:
|
|
||||||
case SIGUSR2:
|
|
||||||
log_debug();
|
|
||||||
/*local_debug();*/
|
|
||||||
cluster_debug();
|
|
||||||
return;
|
|
||||||
default:
|
|
||||||
LOG_PRINT("Unknown signal received... ignoring");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!r) {
|
|
||||||
LOG_DBG("No current cluster logs... safe to exit.");
|
|
||||||
cleanup_all();
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_ERROR("Cluster logs exist. Refusing to exit.");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void process_signals(void)
|
|
||||||
{
|
|
||||||
int x;
|
|
||||||
|
|
||||||
if (!signal_received)
|
|
||||||
return;
|
|
||||||
|
|
||||||
signal_received = 0;
|
|
||||||
|
|
||||||
for (x = 1; x < _NSIG; x++) {
|
|
||||||
if (sigismember(&signal_mask, x)) {
|
|
||||||
sigdelset(&signal_mask, x);
|
|
||||||
process_signal(x);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void remove_lockfile(void)
|
|
||||||
{
|
|
||||||
if (unlink(CMIRRORD_PIDFILE))
|
|
||||||
LOG_ERROR("Unable to remove \"" CMIRRORD_PIDFILE "\" %s", strerror(errno));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* daemonize
|
|
||||||
*
|
|
||||||
* Performs the steps necessary to become a daemon.
|
|
||||||
*/
|
|
||||||
static void daemonize(void)
|
|
||||||
{
|
|
||||||
int pid;
|
|
||||||
int status;
|
|
||||||
int devnull;
|
|
||||||
|
|
||||||
if ((devnull = open("/dev/null", O_RDWR)) == -1) {
|
|
||||||
LOG_ERROR("Can't open /dev/null: %s", strerror(errno));
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
signal(SIGTERM, &parent_exit_handler);
|
|
||||||
|
|
||||||
pid = fork();
|
|
||||||
|
|
||||||
if (pid < 0) {
|
|
||||||
LOG_ERROR("Unable to fork()");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pid) {
|
|
||||||
/* Parent waits here for child to get going */
|
|
||||||
while (!waitpid(pid, &status, WNOHANG) && !exit_now);
|
|
||||||
if (exit_now)
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
|
|
||||||
switch (WEXITSTATUS(status)) {
|
|
||||||
case EXIT_LOCKFILE:
|
|
||||||
LOG_ERROR("Failed to create lockfile");
|
|
||||||
LOG_ERROR("Process already running?");
|
|
||||||
break;
|
|
||||||
case EXIT_KERNEL_SOCKET:
|
|
||||||
LOG_ERROR("Unable to create netlink socket");
|
|
||||||
break;
|
|
||||||
case EXIT_KERNEL_BIND:
|
|
||||||
LOG_ERROR("Unable to bind to netlink socket");
|
|
||||||
break;
|
|
||||||
case EXIT_KERNEL_SETSOCKOPT:
|
|
||||||
LOG_ERROR("Unable to setsockopt on netlink socket");
|
|
||||||
break;
|
|
||||||
case EXIT_CLUSTER_CKPT_INIT:
|
|
||||||
LOG_ERROR("Unable to initialize checkpoint service");
|
|
||||||
LOG_ERROR("Has the cluster infrastructure been started?");
|
|
||||||
break;
|
|
||||||
case EXIT_FAILURE:
|
|
||||||
LOG_ERROR("Failed to start: Generic error");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG_ERROR("Failed to start: Unknown error");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
setsid();
|
|
||||||
if (chdir("/")) {
|
|
||||||
LOG_ERROR("Failed to chdir /: %s", strerror(errno));
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
umask(0);
|
|
||||||
|
|
||||||
if (close(0) || close(1) || close(2)) {
|
|
||||||
LOG_ERROR("Failed to close terminal FDs");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((dup2(devnull, 0) < 0) || /* reopen stdin */
|
|
||||||
(dup2(devnull, 1) < 0) || /* reopen stdout */
|
|
||||||
(dup2(devnull, 2) < 0)) /* reopen stderr */
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
|
|
||||||
if ((devnull > STDERR_FILENO) && close(devnull)) {
|
|
||||||
LOG_ERROR("Failed to close descriptor %d: %s",
|
|
||||||
devnull, strerror(errno));
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_OPEN("cmirrord", LOG_PID, LOG_DAEMON);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* init_all
|
|
||||||
*
|
|
||||||
* Initialize modules. Exit on failure.
|
|
||||||
*/
|
|
||||||
static void init_all(void)
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
|
|
||||||
(void) dm_prepare_selinux_context(CMIRRORD_PIDFILE, S_IFREG);
|
|
||||||
if (dm_create_lockfile(CMIRRORD_PIDFILE) == 0)
|
|
||||||
exit(EXIT_LOCKFILE);
|
|
||||||
(void) dm_prepare_selinux_context(NULL, 0);
|
|
||||||
|
|
||||||
atexit(remove_lockfile);
|
|
||||||
|
|
||||||
/* FIXME Replace with sigaction. (deprecated) */
|
|
||||||
signal(SIGINT, &sig_handler);
|
|
||||||
signal(SIGQUIT, &sig_handler);
|
|
||||||
signal(SIGTERM, &sig_handler);
|
|
||||||
signal(SIGHUP, &sig_handler);
|
|
||||||
signal(SIGPIPE, SIG_IGN);
|
|
||||||
signal(SIGUSR1, &sig_handler);
|
|
||||||
signal(SIGUSR2, &sig_handler);
|
|
||||||
sigemptyset(&signal_mask);
|
|
||||||
signal_received = 0;
|
|
||||||
|
|
||||||
if ((r = init_local()) ||
|
|
||||||
(r = init_cluster())) {
|
|
||||||
exit(r);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* cleanup_all
|
|
||||||
*
|
|
||||||
* Clean up before exiting
|
|
||||||
*/
|
|
||||||
static void cleanup_all(void)
|
|
||||||
{
|
|
||||||
cleanup_local();
|
|
||||||
cleanup_cluster();
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,76 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use,
|
|
||||||
* modify, copy, or redistribute it subject to the terms and conditions
|
|
||||||
* of the GNU Lesser General Public License v.2.1.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this program; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
#ifndef _LVM_CLOG_CLUSTER_H
|
|
||||||
#define _LVM_CLOG_CLUSTER_H
|
|
||||||
|
|
||||||
#include "dm-log-userspace.h"
|
|
||||||
#include "libdevmapper.h"
|
|
||||||
|
|
||||||
#define DM_ULOG_RESPONSE 0x1000U /* in last byte of 32-bit value */
|
|
||||||
#define DM_ULOG_CHECKPOINT_READY 21
|
|
||||||
#define DM_ULOG_MEMBER_JOIN 22
|
|
||||||
|
|
||||||
/*
|
|
||||||
* There is other information in addition to what can
|
|
||||||
* be found in the dm_ulog_request structure that we
|
|
||||||
* need for processing. 'clog_request' is the wrapping
|
|
||||||
* structure we use to make the additional fields
|
|
||||||
* available.
|
|
||||||
*/
|
|
||||||
struct clog_request {
|
|
||||||
/*
|
|
||||||
* If we don't use a union, the structure size will
|
|
||||||
* vary between 32-bit and 64-bit machines. So, we
|
|
||||||
* pack two 64-bit version numbers in there to force
|
|
||||||
* the size of the structure to be the same.
|
|
||||||
*
|
|
||||||
* The two version numbers also help us with endian
|
|
||||||
* issues. The first is always little endian, while
|
|
||||||
* the second is in native format of the sending
|
|
||||||
* machine. If the two are equal, there is no need
|
|
||||||
* to do endian conversions.
|
|
||||||
*/
|
|
||||||
union {
|
|
||||||
uint64_t version[2]; /* LE version and native version */
|
|
||||||
struct dm_list list;
|
|
||||||
} u;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 'originator' is the machine from which the requests
|
|
||||||
* was made.
|
|
||||||
*/
|
|
||||||
uint32_t originator;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 'pit_server' is the "point-in-time" server for the
|
|
||||||
* request. (I.e. The machine that was the server at
|
|
||||||
* the time the request was issued - only important during
|
|
||||||
* startup.
|
|
||||||
*/
|
|
||||||
uint32_t pit_server;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The request from the kernel that is being processed
|
|
||||||
*/
|
|
||||||
struct dm_ulog_request u_rq;
|
|
||||||
};
|
|
||||||
|
|
||||||
int init_cluster(void);
|
|
||||||
void cleanup_cluster(void);
|
|
||||||
void cluster_debug(void);
|
|
||||||
|
|
||||||
int create_cluster_cpg(char *uuid, uint64_t luid);
|
|
||||||
int destroy_cluster_cpg(char *uuid);
|
|
||||||
|
|
||||||
int cluster_send(struct clog_request *rq);
|
|
||||||
|
|
||||||
#endif /* _LVM_CLOG_CLUSTER_H */
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use,
|
|
||||||
* modify, copy, or redistribute it subject to the terms and conditions
|
|
||||||
* of the GNU Lesser General Public License v.2.1.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this program; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
#ifndef _LVM_CLOG_COMMON_H
|
|
||||||
#define _LVM_CLOG_COMMON_H
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If there are problems when forking off to become a daemon,
|
|
||||||
* the child will exist with one of these codes. This allows
|
|
||||||
* the parent to know the reason for the failure and print it
|
|
||||||
* to the launching terminal.
|
|
||||||
*
|
|
||||||
* #define EXIT_SUCCESS 0 (from stdlib.h)
|
|
||||||
* #define EXIT_FAILURE 1 (from stdlib.h)
|
|
||||||
*/
|
|
||||||
#define EXIT_LOCKFILE 2
|
|
||||||
#define EXIT_KERNEL_SOCKET 3 /* Failed netlink socket create */
|
|
||||||
#define EXIT_KERNEL_BIND 4
|
|
||||||
#define EXIT_KERNEL_SETSOCKOPT 5
|
|
||||||
#define EXIT_CLUSTER_CKPT_INIT 6 /* Failed to init checkpoint */
|
|
||||||
#define EXIT_QUEUE_NOMEM 7
|
|
||||||
|
|
||||||
#define DM_ULOG_REQUEST_SIZE 1024
|
|
||||||
|
|
||||||
#endif /* _LVM_CLOG_COMMON_H */
|
|
||||||
@@ -1,210 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2010 Red Hat, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use,
|
|
||||||
* modify, copy, or redistribute it subject to the terms and conditions
|
|
||||||
* of the GNU Lesser General Public License v.2.1.
|
|
||||||
*/
|
|
||||||
#include "logging.h"
|
|
||||||
#include "cluster.h"
|
|
||||||
#include "compat.h"
|
|
||||||
#include "xlate.h"
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Older versions of the log daemon communicate with different
|
|
||||||
* versions of the inter-machine communication structure, which
|
|
||||||
* varies in size and fields. The older versions append the
|
|
||||||
* standard upstream version of the structure to every request.
|
|
||||||
* COMPAT_OFFSET is where the upstream structure starts.
|
|
||||||
*/
|
|
||||||
#define COMPAT_OFFSET 256
|
|
||||||
|
|
||||||
static void v5_data_endian_switch(struct clog_request *rq, int to_network __attribute__((unused)))
|
|
||||||
{
|
|
||||||
int i, end;
|
|
||||||
int64_t *pi64;
|
|
||||||
uint64_t *pu64;
|
|
||||||
uint32_t rq_type = rq->u_rq.request_type & ~DM_ULOG_RESPONSE;
|
|
||||||
|
|
||||||
if (rq->u_rq.request_type & DM_ULOG_RESPONSE) {
|
|
||||||
switch (rq_type) {
|
|
||||||
case DM_ULOG_CTR:
|
|
||||||
case DM_ULOG_DTR:
|
|
||||||
LOG_ERROR("Invalid response type in endian switch");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
|
|
||||||
case DM_ULOG_PRESUSPEND:
|
|
||||||
case DM_ULOG_POSTSUSPEND:
|
|
||||||
case DM_ULOG_RESUME:
|
|
||||||
case DM_ULOG_FLUSH:
|
|
||||||
case DM_ULOG_MARK_REGION:
|
|
||||||
case DM_ULOG_CLEAR_REGION:
|
|
||||||
case DM_ULOG_SET_REGION_SYNC:
|
|
||||||
case DM_ULOG_CHECKPOINT_READY:
|
|
||||||
case DM_ULOG_MEMBER_JOIN:
|
|
||||||
case DM_ULOG_STATUS_INFO:
|
|
||||||
case DM_ULOG_STATUS_TABLE:
|
|
||||||
/* No outbound data */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DM_ULOG_GET_REGION_SIZE:
|
|
||||||
case DM_ULOG_GET_SYNC_COUNT:
|
|
||||||
pu64 = (uint64_t *)rq->u_rq.data;
|
|
||||||
*pu64 = xlate64(*pu64);
|
|
||||||
break;
|
|
||||||
case DM_ULOG_IS_CLEAN:
|
|
||||||
case DM_ULOG_IN_SYNC:
|
|
||||||
pi64 = (int64_t *)rq->u_rq.data;
|
|
||||||
*pi64 = xlate64(*pi64);
|
|
||||||
break;
|
|
||||||
case DM_ULOG_GET_RESYNC_WORK:
|
|
||||||
case DM_ULOG_IS_REMOTE_RECOVERING:
|
|
||||||
pi64 = (int64_t *)rq->u_rq.data;
|
|
||||||
pu64 = ((uint64_t *)rq->u_rq.data) + 1;
|
|
||||||
*pi64 = xlate64(*pi64);
|
|
||||||
*pu64 = xlate64(*pu64);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG_ERROR("Unknown request type, %u", rq_type);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
switch (rq_type) {
|
|
||||||
case DM_ULOG_CTR:
|
|
||||||
case DM_ULOG_DTR:
|
|
||||||
LOG_ERROR("Invalid request type in endian switch");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
|
|
||||||
case DM_ULOG_PRESUSPEND:
|
|
||||||
case DM_ULOG_POSTSUSPEND:
|
|
||||||
case DM_ULOG_RESUME:
|
|
||||||
case DM_ULOG_GET_REGION_SIZE:
|
|
||||||
case DM_ULOG_FLUSH:
|
|
||||||
case DM_ULOG_GET_RESYNC_WORK:
|
|
||||||
case DM_ULOG_GET_SYNC_COUNT:
|
|
||||||
case DM_ULOG_STATUS_INFO:
|
|
||||||
case DM_ULOG_STATUS_TABLE:
|
|
||||||
case DM_ULOG_CHECKPOINT_READY:
|
|
||||||
case DM_ULOG_MEMBER_JOIN:
|
|
||||||
/* No incoming data */
|
|
||||||
break;
|
|
||||||
case DM_ULOG_IS_CLEAN:
|
|
||||||
case DM_ULOG_IN_SYNC:
|
|
||||||
case DM_ULOG_IS_REMOTE_RECOVERING:
|
|
||||||
pu64 = (uint64_t *)rq->u_rq.data;
|
|
||||||
*pu64 = xlate64(*pu64);
|
|
||||||
break;
|
|
||||||
case DM_ULOG_MARK_REGION:
|
|
||||||
case DM_ULOG_CLEAR_REGION:
|
|
||||||
end = rq->u_rq.data_size/sizeof(uint64_t);
|
|
||||||
|
|
||||||
pu64 = (uint64_t *)rq->u_rq.data;
|
|
||||||
for (i = 0; i < end; i++)
|
|
||||||
pu64[i] = xlate64(pu64[i]);
|
|
||||||
break;
|
|
||||||
case DM_ULOG_SET_REGION_SYNC:
|
|
||||||
pu64 = (uint64_t *)rq->u_rq.data;
|
|
||||||
pi64 = ((int64_t *)rq->u_rq.data) + 1;
|
|
||||||
*pu64 = xlate64(*pu64);
|
|
||||||
*pi64 = xlate64(*pi64);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG_ERROR("Unknown request type, %u", rq_type);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int v5_endian_to_network(struct clog_request *rq)
|
|
||||||
{
|
|
||||||
int size;
|
|
||||||
struct dm_ulog_request *u_rq = &rq->u_rq;
|
|
||||||
|
|
||||||
size = sizeof(*rq) + u_rq->data_size;
|
|
||||||
|
|
||||||
u_rq->error = xlate32(u_rq->error);
|
|
||||||
u_rq->seq = xlate32(u_rq->seq);
|
|
||||||
|
|
||||||
rq->originator = xlate32(rq->originator);
|
|
||||||
|
|
||||||
v5_data_endian_switch(rq, 1);
|
|
||||||
|
|
||||||
u_rq->request_type = xlate32(u_rq->request_type);
|
|
||||||
u_rq->data_size = xlate32(u_rq->data_size);
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
int clog_request_to_network(struct clog_request *rq)
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
|
|
||||||
/* FIXME: Remove this safety check */
|
|
||||||
if (rq->u.version[0] != xlate64(rq->u.version[1])) {
|
|
||||||
LOG_ERROR("Programmer error: version[0] must be LE");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Are we already running in the endian mode we send
|
|
||||||
* over the wire?
|
|
||||||
*/
|
|
||||||
if (rq->u.version[0] == rq->u.version[1])
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
r = v5_endian_to_network(rq);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int v5_endian_from_network(struct clog_request *rq)
|
|
||||||
{
|
|
||||||
int size;
|
|
||||||
struct dm_ulog_request *u_rq = &rq->u_rq;
|
|
||||||
|
|
||||||
u_rq->error = xlate32(u_rq->error);
|
|
||||||
u_rq->seq = xlate32(u_rq->seq);
|
|
||||||
u_rq->request_type = xlate32(u_rq->request_type);
|
|
||||||
u_rq->data_size = xlate32(u_rq->data_size);
|
|
||||||
|
|
||||||
rq->originator = xlate32(rq->originator);
|
|
||||||
|
|
||||||
size = sizeof(*rq) + u_rq->data_size;
|
|
||||||
|
|
||||||
v5_data_endian_switch(rq, 0);
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
int clog_request_from_network(void *data, size_t data_len)
|
|
||||||
{
|
|
||||||
uint64_t *vp = data;
|
|
||||||
uint64_t version = xlate64(vp[0]);
|
|
||||||
struct clog_request *rq = data;
|
|
||||||
|
|
||||||
switch (version) {
|
|
||||||
case 5: /* Upstream */
|
|
||||||
if (version == vp[0])
|
|
||||||
return 0;
|
|
||||||
break;
|
|
||||||
case 4: /* RHEL 5.[45] */
|
|
||||||
case 3: /* RHEL 5.3 */
|
|
||||||
case 2: /* RHEL 5.2 */
|
|
||||||
/* FIXME: still need to account for payload */
|
|
||||||
if (data_len < (COMPAT_OFFSET + sizeof(*rq)))
|
|
||||||
return -ENOSPC;
|
|
||||||
|
|
||||||
rq = (struct clog_request *)((char *)data + COMPAT_OFFSET);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG_ERROR("Unable to process cluster message: "
|
|
||||||
"Incompatible version");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
v5_endian_from_network(rq);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2010 Red Hat, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use,
|
|
||||||
* modify, copy, or redistribute it subject to the terms and conditions
|
|
||||||
* of the GNU Lesser General Public License v.2.1.
|
|
||||||
*/
|
|
||||||
#ifndef _LVM_CLOG_COMPAT_H
|
|
||||||
#define _LVM_CLOG_COMPAT_H
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The intermachine communication structure version are:
|
|
||||||
* 0: Unused
|
|
||||||
* 1: Never in the wild
|
|
||||||
* 2: RHEL 5.2
|
|
||||||
* 3: RHEL 5.3
|
|
||||||
* 4: RHEL 5.4, RHEL 5.5
|
|
||||||
* 5: RHEL 6, Current Upstream Format
|
|
||||||
*/
|
|
||||||
#define CLOG_TFR_VERSION 5
|
|
||||||
|
|
||||||
int clog_request_to_network(struct clog_request *rq);
|
|
||||||
int clog_request_from_network(void *data, size_t data_len);
|
|
||||||
|
|
||||||
#endif /* _LVM_CLOG_COMPAT_H */
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,34 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use,
|
|
||||||
* modify, copy, or redistribute it subject to the terms and conditions
|
|
||||||
* of the GNU Lesser General Public License v.2.1.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this program; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
#ifndef _LVM_CLOG_FUNCTIONS_H
|
|
||||||
#define _LVM_CLOG_FUNCTIONS_H
|
|
||||||
|
|
||||||
#include "dm-log-userspace.h"
|
|
||||||
#include "cluster.h"
|
|
||||||
|
|
||||||
#define LOG_RESUMED 1
|
|
||||||
#define LOG_SUSPENDED 2
|
|
||||||
|
|
||||||
int local_resume(struct dm_ulog_request *rq);
|
|
||||||
int cluster_postsuspend(char *, uint64_t);
|
|
||||||
|
|
||||||
int do_request(struct clog_request *rq, int server);
|
|
||||||
int push_state(const char *uuid, uint64_t luid,
|
|
||||||
const char *which, char **buf, uint32_t debug_who);
|
|
||||||
int pull_state(const char *uuid, uint64_t luid,
|
|
||||||
const char *which, char *buf, int size);
|
|
||||||
|
|
||||||
int log_get_state(struct dm_ulog_request *rq);
|
|
||||||
int log_status(void);
|
|
||||||
void log_debug(void);
|
|
||||||
|
|
||||||
#endif /* _LVM_CLOG_FUNCTIONS_H */
|
|
||||||
@@ -1,151 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use,
|
|
||||||
* modify, copy, or redistribute it subject to the terms and conditions
|
|
||||||
* of the GNU Lesser General Public License v.2.1.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this program; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
#include "logging.h"
|
|
||||||
#include "link_mon.h"
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <poll.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
struct link_callback {
|
|
||||||
int fd;
|
|
||||||
const char *name;
|
|
||||||
void *data;
|
|
||||||
int (*callback)(void *data);
|
|
||||||
|
|
||||||
struct link_callback *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
static unsigned used_pfds = 0;
|
|
||||||
static unsigned free_pfds = 0;
|
|
||||||
static struct pollfd *pfds = NULL;
|
|
||||||
static struct link_callback *callbacks = NULL;
|
|
||||||
|
|
||||||
int links_register(int fd, const char *name, int (*callback)(void *data), void *data)
|
|
||||||
{
|
|
||||||
unsigned i;
|
|
||||||
struct link_callback *lc;
|
|
||||||
|
|
||||||
for (i = 0; i < used_pfds; i++) {
|
|
||||||
if (fd == pfds[i].fd) {
|
|
||||||
LOG_ERROR("links_register: Duplicate file descriptor");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lc = malloc(sizeof(*lc));
|
|
||||||
if (!lc)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
lc->fd = fd;
|
|
||||||
lc->name = name;
|
|
||||||
lc->data = data;
|
|
||||||
lc->callback = callback;
|
|
||||||
|
|
||||||
if (!free_pfds) {
|
|
||||||
struct pollfd *tmp;
|
|
||||||
tmp = realloc(pfds, sizeof(struct pollfd) * ((used_pfds*2) + 1));
|
|
||||||
if (!tmp) {
|
|
||||||
free(lc);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
pfds = tmp;
|
|
||||||
free_pfds = used_pfds + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
free_pfds--;
|
|
||||||
pfds[used_pfds].fd = fd;
|
|
||||||
pfds[used_pfds].events = POLLIN;
|
|
||||||
pfds[used_pfds].revents = 0;
|
|
||||||
used_pfds++;
|
|
||||||
|
|
||||||
lc->next = callbacks;
|
|
||||||
callbacks = lc;
|
|
||||||
LOG_DBG("Adding %s/%d", lc->name, lc->fd);
|
|
||||||
LOG_DBG(" used_pfds = %u, free_pfds = %u",
|
|
||||||
used_pfds, free_pfds);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int links_unregister(int fd)
|
|
||||||
{
|
|
||||||
unsigned i;
|
|
||||||
struct link_callback *p, *c;
|
|
||||||
|
|
||||||
for (i = 0; i < used_pfds; i++)
|
|
||||||
if (fd == pfds[i].fd) {
|
|
||||||
/* entire struct is copied (overwritten) */
|
|
||||||
pfds[i] = pfds[used_pfds - 1];
|
|
||||||
used_pfds--;
|
|
||||||
free_pfds++;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (p = NULL, c = callbacks; c; p = c, c = c->next)
|
|
||||||
if (fd == c->fd) {
|
|
||||||
LOG_DBG("Freeing up %s/%d", c->name, c->fd);
|
|
||||||
LOG_DBG(" used_pfds = %u, free_pfds = %u",
|
|
||||||
used_pfds, free_pfds);
|
|
||||||
if (p)
|
|
||||||
p->next = c->next;
|
|
||||||
else
|
|
||||||
callbacks = c->next;
|
|
||||||
free(c);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int links_monitor(void)
|
|
||||||
{
|
|
||||||
unsigned i;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
for (i = 0; i < used_pfds; i++) {
|
|
||||||
pfds[i].revents = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = poll(pfds, used_pfds, -1);
|
|
||||||
if (r <= 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
r = 0;
|
|
||||||
/* FIXME: handle POLLHUP */
|
|
||||||
for (i = 0; i < used_pfds; i++)
|
|
||||||
if (pfds[i].revents & POLLIN) {
|
|
||||||
LOG_DBG("Data ready on %d", pfds[i].fd);
|
|
||||||
|
|
||||||
/* FIXME: Add this back return 1;*/
|
|
||||||
r++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
int links_issue_callbacks(void)
|
|
||||||
{
|
|
||||||
unsigned i;
|
|
||||||
struct link_callback *lc;
|
|
||||||
|
|
||||||
for (i = 0; i < used_pfds; i++)
|
|
||||||
if (pfds[i].revents & POLLIN)
|
|
||||||
for (lc = callbacks; lc; lc = lc->next)
|
|
||||||
if (pfds[i].fd == lc->fd) {
|
|
||||||
LOG_DBG("Issuing callback on %s/%d",
|
|
||||||
lc->name, lc->fd);
|
|
||||||
lc->callback(lc->data);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use,
|
|
||||||
* modify, copy, or redistribute it subject to the terms and conditions
|
|
||||||
* of the GNU Lesser General Public License v.2.1.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this program; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
#ifndef _LVM_CLOG_LINK_MON_H
|
|
||||||
#define _LVM_CLOG_LINK_MON_H
|
|
||||||
|
|
||||||
int links_register(int fd, const char *name, int (*callback)(void *data), void *data);
|
|
||||||
int links_unregister(int fd);
|
|
||||||
int links_monitor(void);
|
|
||||||
int links_issue_callbacks(void);
|
|
||||||
|
|
||||||
#endif /* _LVM_CLOG_LINK_MON_H */
|
|
||||||
@@ -1,424 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use,
|
|
||||||
* modify, copy, or redistribute it subject to the terms and conditions
|
|
||||||
* of the GNU Lesser General Public License v.2.1.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this program; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
#include "logging.h"
|
|
||||||
#include "common.h"
|
|
||||||
#include "functions.h"
|
|
||||||
#include "link_mon.h"
|
|
||||||
#include "local.h"
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <linux/connector.h>
|
|
||||||
#include <linux/netlink.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#ifndef CN_IDX_DM
|
|
||||||
/* Kernel 2.6.31 is required to run this code */
|
|
||||||
#define CN_IDX_DM 0x7 /* Device Mapper */
|
|
||||||
#define CN_VAL_DM_USERSPACE_LOG 0x1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int cn_fd = -1; /* Connector (netlink) socket fd */
|
|
||||||
static char recv_buf[2048];
|
|
||||||
static char send_buf[2048];
|
|
||||||
|
|
||||||
|
|
||||||
/* FIXME: merge this function with kernel_send_helper */
|
|
||||||
static int kernel_ack(uint32_t seq, int error)
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
struct nlmsghdr *nlh = (struct nlmsghdr *)send_buf;
|
|
||||||
struct cn_msg *msg = NLMSG_DATA(nlh);
|
|
||||||
|
|
||||||
if (error < 0) {
|
|
||||||
LOG_ERROR("Programmer error: error codes must be positive");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(send_buf, 0, sizeof(send_buf));
|
|
||||||
|
|
||||||
nlh->nlmsg_seq = 0;
|
|
||||||
nlh->nlmsg_pid = getpid();
|
|
||||||
nlh->nlmsg_type = NLMSG_DONE;
|
|
||||||
nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct cn_msg));
|
|
||||||
nlh->nlmsg_flags = 0;
|
|
||||||
|
|
||||||
msg->len = 0;
|
|
||||||
msg->id.idx = CN_IDX_DM;
|
|
||||||
msg->id.val = CN_VAL_DM_USERSPACE_LOG;
|
|
||||||
msg->seq = seq;
|
|
||||||
msg->ack = error;
|
|
||||||
|
|
||||||
r = send(cn_fd, nlh, NLMSG_LENGTH(sizeof(struct cn_msg)), 0);
|
|
||||||
/* FIXME: do better error processing */
|
|
||||||
if (r <= 0)
|
|
||||||
return -EBADE;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* kernel_recv
|
|
||||||
* @rq: the newly allocated request from kernel
|
|
||||||
*
|
|
||||||
* Read requests from the kernel and allocate space for the new request.
|
|
||||||
* If there is no request from the kernel, *rq is NULL.
|
|
||||||
*
|
|
||||||
* This function is not thread safe due to returned stack pointer. In fact,
|
|
||||||
* the returned pointer must not be in-use when this function is called again.
|
|
||||||
*
|
|
||||||
* Returns: 0 on success, -EXXX on error
|
|
||||||
*/
|
|
||||||
static int kernel_recv(struct clog_request **rq)
|
|
||||||
{
|
|
||||||
int r = 0;
|
|
||||||
ssize_t len;
|
|
||||||
char *foo;
|
|
||||||
struct cn_msg *msg;
|
|
||||||
struct dm_ulog_request *u_rq;
|
|
||||||
struct nlmsghdr *nlmsg_h;
|
|
||||||
|
|
||||||
*rq = NULL;
|
|
||||||
memset(recv_buf, 0, sizeof(recv_buf));
|
|
||||||
|
|
||||||
len = recv(cn_fd, recv_buf, sizeof(recv_buf), 0);
|
|
||||||
if (len < 0) {
|
|
||||||
LOG_ERROR("Failed to recv message from kernel");
|
|
||||||
r = -errno;
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
nlmsg_h = (struct nlmsghdr *)recv_buf;
|
|
||||||
switch (nlmsg_h->nlmsg_type) {
|
|
||||||
case NLMSG_ERROR:
|
|
||||||
LOG_ERROR("Unable to recv message from kernel: NLMSG_ERROR");
|
|
||||||
r = -EBADE;
|
|
||||||
goto fail;
|
|
||||||
case NLMSG_DONE:
|
|
||||||
msg = (struct cn_msg *)NLMSG_DATA((struct nlmsghdr *)recv_buf);
|
|
||||||
len -= (ssize_t)sizeof(struct nlmsghdr);
|
|
||||||
|
|
||||||
if (len < (ssize_t)sizeof(struct cn_msg)) {
|
|
||||||
LOG_ERROR("Incomplete request from kernel received");
|
|
||||||
r = -EBADE;
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (msg->len > DM_ULOG_REQUEST_SIZE) {
|
|
||||||
LOG_ERROR("Not enough space to receive kernel request (%d/%d)",
|
|
||||||
msg->len, DM_ULOG_REQUEST_SIZE);
|
|
||||||
r = -EBADE;
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!msg->len)
|
|
||||||
LOG_ERROR("Zero length message received");
|
|
||||||
|
|
||||||
len -= (ssize_t)sizeof(struct cn_msg);
|
|
||||||
|
|
||||||
if (len < msg->len)
|
|
||||||
LOG_ERROR("len = %zd, msg->len = %" PRIu16, len, msg->len);
|
|
||||||
|
|
||||||
msg->data[msg->len] = '\0'; /* Cleaner way to ensure this? */
|
|
||||||
u_rq = (struct dm_ulog_request *)msg->data;
|
|
||||||
|
|
||||||
if (!u_rq->request_type) {
|
|
||||||
LOG_DBG("Bad transmission, requesting resend [%u]",
|
|
||||||
msg->seq);
|
|
||||||
r = -EAGAIN;
|
|
||||||
|
|
||||||
if (kernel_ack(msg->seq, EAGAIN)) {
|
|
||||||
LOG_ERROR("Failed to NACK kernel transmission [%u]",
|
|
||||||
msg->seq);
|
|
||||||
r = -EBADE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Now we've got sizeof(struct cn_msg) + sizeof(struct nlmsghdr)
|
|
||||||
* worth of space that precede the request structure from the
|
|
||||||
* kernel. Since that space isn't going to be used again, we
|
|
||||||
* can take it for our purposes; rather than allocating a whole
|
|
||||||
* new structure and doing a memcpy.
|
|
||||||
*
|
|
||||||
* We should really make sure 'clog_request' doesn't grow
|
|
||||||
* beyond what is available to us, but we need only check it
|
|
||||||
* once... perhaps at compile time?
|
|
||||||
*/
|
|
||||||
foo = (char *)u_rq;
|
|
||||||
foo -= (sizeof(struct clog_request) - sizeof(struct dm_ulog_request));
|
|
||||||
*rq = (struct clog_request *) foo;
|
|
||||||
|
|
||||||
/* Clear the wrapper container fields */
|
|
||||||
memset(*rq, 0, (size_t)((char *)u_rq - (char *)(*rq)));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG_ERROR("Unknown nlmsg_type");
|
|
||||||
r = -EBADE;
|
|
||||||
}
|
|
||||||
|
|
||||||
fail:
|
|
||||||
if (r)
|
|
||||||
*rq = NULL;
|
|
||||||
|
|
||||||
return (r == -EAGAIN) ? 0 : r;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int kernel_send_helper(void *data, uint16_t out_size)
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
struct nlmsghdr *nlh;
|
|
||||||
struct cn_msg *msg;
|
|
||||||
|
|
||||||
memset(send_buf, 0, sizeof(send_buf));
|
|
||||||
|
|
||||||
nlh = (struct nlmsghdr *)send_buf;
|
|
||||||
nlh->nlmsg_seq = 0; /* FIXME: Is this used? */
|
|
||||||
nlh->nlmsg_pid = getpid();
|
|
||||||
nlh->nlmsg_type = NLMSG_DONE;
|
|
||||||
nlh->nlmsg_len = NLMSG_LENGTH(out_size + sizeof(struct cn_msg));
|
|
||||||
nlh->nlmsg_flags = 0;
|
|
||||||
|
|
||||||
msg = NLMSG_DATA(nlh);
|
|
||||||
memcpy(msg->data, data, out_size);
|
|
||||||
msg->len = out_size;
|
|
||||||
msg->id.idx = CN_IDX_DM;
|
|
||||||
msg->id.val = CN_VAL_DM_USERSPACE_LOG;
|
|
||||||
msg->seq = 0;
|
|
||||||
|
|
||||||
r = send(cn_fd, nlh, NLMSG_LENGTH(out_size + sizeof(struct cn_msg)), 0);
|
|
||||||
/* FIXME: do better error processing */
|
|
||||||
if (r <= 0)
|
|
||||||
return -EBADE;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* do_local_work
|
|
||||||
*
|
|
||||||
* Any processing errors are placed in the 'rq'
|
|
||||||
* structure to be reported back to the kernel.
|
|
||||||
* It may be pointless for this function to
|
|
||||||
* return an int.
|
|
||||||
*
|
|
||||||
* Returns: 0 on success, -EXXX on failure
|
|
||||||
*/
|
|
||||||
static int do_local_work(void *data __attribute__((unused)))
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
struct clog_request *rq;
|
|
||||||
struct dm_ulog_request *u_rq = NULL;
|
|
||||||
|
|
||||||
r = kernel_recv(&rq);
|
|
||||||
if (r)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
if (!rq)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
u_rq = &rq->u_rq;
|
|
||||||
LOG_DBG("[%s] Request from kernel received: [%s/%u]",
|
|
||||||
SHORT_UUID(u_rq->uuid), RQ_TYPE(u_rq->request_type),
|
|
||||||
u_rq->seq);
|
|
||||||
switch (u_rq->request_type) {
|
|
||||||
case DM_ULOG_CTR:
|
|
||||||
case DM_ULOG_DTR:
|
|
||||||
case DM_ULOG_GET_REGION_SIZE:
|
|
||||||
case DM_ULOG_IN_SYNC:
|
|
||||||
case DM_ULOG_GET_SYNC_COUNT:
|
|
||||||
case DM_ULOG_STATUS_TABLE:
|
|
||||||
case DM_ULOG_PRESUSPEND:
|
|
||||||
/* We do not specify ourselves as server here */
|
|
||||||
r = do_request(rq, 0);
|
|
||||||
if (r)
|
|
||||||
LOG_DBG("Returning failed request to kernel [%s]",
|
|
||||||
RQ_TYPE(u_rq->request_type));
|
|
||||||
r = kernel_send(u_rq);
|
|
||||||
if (r)
|
|
||||||
LOG_ERROR("Failed to respond to kernel [%s]",
|
|
||||||
RQ_TYPE(u_rq->request_type));
|
|
||||||
|
|
||||||
break;
|
|
||||||
case DM_ULOG_RESUME:
|
|
||||||
/*
|
|
||||||
* Resume is a special case that requires a local
|
|
||||||
* component to join the CPG, and a cluster component
|
|
||||||
* to handle the request.
|
|
||||||
*/
|
|
||||||
r = local_resume(u_rq);
|
|
||||||
if (r) {
|
|
||||||
LOG_DBG("Returning failed request to kernel [%s]",
|
|
||||||
RQ_TYPE(u_rq->request_type));
|
|
||||||
r = kernel_send(u_rq);
|
|
||||||
if (r)
|
|
||||||
LOG_ERROR("Failed to respond to kernel [%s]",
|
|
||||||
RQ_TYPE(u_rq->request_type));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* ELSE, fall through */
|
|
||||||
case DM_ULOG_IS_CLEAN:
|
|
||||||
case DM_ULOG_FLUSH:
|
|
||||||
case DM_ULOG_MARK_REGION:
|
|
||||||
case DM_ULOG_GET_RESYNC_WORK:
|
|
||||||
case DM_ULOG_SET_REGION_SYNC:
|
|
||||||
case DM_ULOG_STATUS_INFO:
|
|
||||||
case DM_ULOG_IS_REMOTE_RECOVERING:
|
|
||||||
case DM_ULOG_POSTSUSPEND:
|
|
||||||
r = cluster_send(rq);
|
|
||||||
if (r) {
|
|
||||||
u_rq->data_size = 0;
|
|
||||||
u_rq->error = r;
|
|
||||||
if (kernel_send(u_rq))
|
|
||||||
LOG_ERROR("Failed to respond to kernel [%s]",
|
|
||||||
RQ_TYPE(u_rq->request_type));
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case DM_ULOG_CLEAR_REGION:
|
|
||||||
r = kernel_ack(u_rq->seq, 0);
|
|
||||||
|
|
||||||
r = cluster_send(rq);
|
|
||||||
if (r) {
|
|
||||||
/*
|
|
||||||
* FIXME: store error for delivery on flush
|
|
||||||
* This would allow us to optimize MARK_REGION
|
|
||||||
* too.
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG_ERROR("Invalid log request received (%u), ignoring.",
|
|
||||||
u_rq->request_type);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (r && !u_rq->error)
|
|
||||||
u_rq->error = r;
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* kernel_send
|
|
||||||
* @u_rq: result to pass back to kernel
|
|
||||||
*
|
|
||||||
* This function returns the u_rq structure
|
|
||||||
* (containing the results) to the kernel.
|
|
||||||
* It then frees the structure.
|
|
||||||
*
|
|
||||||
* WARNING: should the structure be freed if
|
|
||||||
* there is an error? I vote 'yes'. If the
|
|
||||||
* kernel doesn't get the response, it should
|
|
||||||
* resend the request.
|
|
||||||
*
|
|
||||||
* Returns: 0 on success, -EXXX on failure
|
|
||||||
*/
|
|
||||||
int kernel_send(struct dm_ulog_request *u_rq)
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
uint16_t size;
|
|
||||||
|
|
||||||
if (!u_rq)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
size = (uint16_t)(sizeof(struct dm_ulog_request) + u_rq->data_size);
|
|
||||||
|
|
||||||
if (!u_rq->data_size && !u_rq->error) {
|
|
||||||
/* An ACK is all that is needed */
|
|
||||||
|
|
||||||
/* FIXME: add ACK code */
|
|
||||||
} else if (size > DM_ULOG_REQUEST_SIZE) {
|
|
||||||
/*
|
|
||||||
* If we gotten here, we've already overrun
|
|
||||||
* our allotted space somewhere.
|
|
||||||
*
|
|
||||||
* We must do something, because the kernel
|
|
||||||
* is waiting for a response.
|
|
||||||
*/
|
|
||||||
LOG_ERROR("Not enough space to respond to server");
|
|
||||||
u_rq->error = -ENOSPC;
|
|
||||||
size = sizeof(struct dm_ulog_request);
|
|
||||||
}
|
|
||||||
|
|
||||||
r = kernel_send_helper(u_rq, size);
|
|
||||||
if (r)
|
|
||||||
LOG_ERROR("Failed to send msg to kernel.");
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* init_local
|
|
||||||
*
|
|
||||||
* Initialize kernel communication socket (netlink)
|
|
||||||
*
|
|
||||||
* Returns: 0 on success, values from common.h on failure
|
|
||||||
*/
|
|
||||||
int init_local(void)
|
|
||||||
{
|
|
||||||
int r = 0;
|
|
||||||
unsigned opt;
|
|
||||||
struct sockaddr_nl addr;
|
|
||||||
|
|
||||||
cn_fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
|
|
||||||
if (cn_fd < 0)
|
|
||||||
return EXIT_KERNEL_SOCKET;
|
|
||||||
|
|
||||||
/* memset to fix valgrind complaint */
|
|
||||||
memset(&addr, 0, sizeof(struct sockaddr_nl));
|
|
||||||
|
|
||||||
addr.nl_family = AF_NETLINK;
|
|
||||||
addr.nl_groups = CN_IDX_DM;
|
|
||||||
addr.nl_pid = 0;
|
|
||||||
|
|
||||||
r = bind(cn_fd, (struct sockaddr *) &addr, sizeof(addr));
|
|
||||||
if (r < 0) {
|
|
||||||
if (close(cn_fd))
|
|
||||||
LOG_ERROR("Failed to close socket: %s",
|
|
||||||
strerror(errno));
|
|
||||||
return EXIT_KERNEL_BIND;
|
|
||||||
}
|
|
||||||
|
|
||||||
opt = addr.nl_groups;
|
|
||||||
r = setsockopt(cn_fd, 270, NETLINK_ADD_MEMBERSHIP, &opt, sizeof(opt));
|
|
||||||
if (r) {
|
|
||||||
if (close(cn_fd))
|
|
||||||
LOG_ERROR("Failed to close socket: %s",
|
|
||||||
strerror(errno));
|
|
||||||
return EXIT_KERNEL_SETSOCKOPT;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
r = fcntl(cn_fd, F_SETFL, FNDELAY);
|
|
||||||
*/
|
|
||||||
|
|
||||||
links_register(cn_fd, "local", do_local_work, NULL);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* cleanup_local
|
|
||||||
*
|
|
||||||
* Clean up before exiting
|
|
||||||
*/
|
|
||||||
void cleanup_local(void)
|
|
||||||
{
|
|
||||||
links_unregister(cn_fd);
|
|
||||||
if (cn_fd >= 0 && close(cn_fd))
|
|
||||||
LOG_ERROR("Failed to close socket: %s",
|
|
||||||
strerror(errno));
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use,
|
|
||||||
* modify, copy, or redistribute it subject to the terms and conditions
|
|
||||||
* of the GNU Lesser General Public License v.2.1.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this program; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
#ifndef _LVM_CLOG_LOCAL_H
|
|
||||||
#define _LVM_CLOG_LOCAL_H
|
|
||||||
|
|
||||||
int init_local(void);
|
|
||||||
void cleanup_local(void);
|
|
||||||
|
|
||||||
int kernel_send(struct dm_ulog_request *rq);
|
|
||||||
|
|
||||||
#endif /* _LVM_CLOG_LOCAL_H */
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use,
|
|
||||||
* modify, copy, or redistribute it subject to the terms and conditions
|
|
||||||
* of the GNU Lesser General Public License v.2.1.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this program; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
#include "logging.h"
|
|
||||||
|
|
||||||
const char *__rq_types_off_by_one[] = {
|
|
||||||
"DM_ULOG_CTR",
|
|
||||||
"DM_ULOG_DTR",
|
|
||||||
"DM_ULOG_PRESUSPEND",
|
|
||||||
"DM_ULOG_POSTSUSPEND",
|
|
||||||
"DM_ULOG_RESUME",
|
|
||||||
"DM_ULOG_GET_REGION_SIZE",
|
|
||||||
"DM_ULOG_IS_CLEAN",
|
|
||||||
"DM_ULOG_IN_SYNC",
|
|
||||||
"DM_ULOG_FLUSH",
|
|
||||||
"DM_ULOG_MARK_REGION",
|
|
||||||
"DM_ULOG_CLEAR_REGION",
|
|
||||||
"DM_ULOG_GET_RESYNC_WORK",
|
|
||||||
"DM_ULOG_SET_REGION_SYNC",
|
|
||||||
"DM_ULOG_GET_SYNC_COUNT",
|
|
||||||
"DM_ULOG_STATUS_INFO",
|
|
||||||
"DM_ULOG_STATUS_TABLE",
|
|
||||||
"DM_ULOG_IS_REMOTE_RECOVERING",
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
int log_tabbing = 0;
|
|
||||||
int log_is_open = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Variables for various conditional logging
|
|
||||||
*/
|
|
||||||
#ifdef MEMB
|
|
||||||
int log_membership_change = 1;
|
|
||||||
#else
|
|
||||||
int log_membership_change = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CKPT
|
|
||||||
int log_checkpoint = 1;
|
|
||||||
#else
|
|
||||||
int log_checkpoint = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef RESEND
|
|
||||||
int log_resend_requests = 1;
|
|
||||||
#else
|
|
||||||
int log_resend_requests = 0;
|
|
||||||
#endif
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use,
|
|
||||||
* modify, copy, or redistribute it subject to the terms and conditions
|
|
||||||
* of the GNU Lesser General Public License v.2.1.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this program; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _LVM_CLOG_LOGGING_H
|
|
||||||
#define _LVM_CLOG_LOGGING_H
|
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
#define _FILE_OFFSET_BITS 64
|
|
||||||
|
|
||||||
#include "configure.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <syslog.h>
|
|
||||||
|
|
||||||
/* SHORT_UUID - print last 8 chars of a string */
|
|
||||||
#define SHORT_UUID(x) (strlen(x) > 8) ? ((x) + (strlen(x) - 8)) : (x)
|
|
||||||
|
|
||||||
extern const char *__rq_types_off_by_one[];
|
|
||||||
#define RQ_TYPE(x) __rq_types_off_by_one[(x) - 1]
|
|
||||||
|
|
||||||
extern int log_tabbing;
|
|
||||||
extern int log_is_open;
|
|
||||||
extern int log_membership_change;
|
|
||||||
extern int log_checkpoint;
|
|
||||||
extern int log_resend_requests;
|
|
||||||
|
|
||||||
#define LOG_OPEN(ident, option, facility) do { \
|
|
||||||
openlog(ident, option, facility); \
|
|
||||||
log_is_open = 1; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LOG_CLOSE(void) do { \
|
|
||||||
log_is_open = 0; \
|
|
||||||
closelog(); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LOG_OUTPUT(level, f, arg...) do { \
|
|
||||||
int __i; \
|
|
||||||
char __buffer[16]; \
|
|
||||||
FILE *fp = (level > LOG_NOTICE) ? stderr : stdout; \
|
|
||||||
if (log_is_open) { \
|
|
||||||
for (__i = 0; (__i < log_tabbing) && (__i < 15); __i++) \
|
|
||||||
__buffer[__i] = '\t'; \
|
|
||||||
__buffer[__i] = '\0'; \
|
|
||||||
syslog(level, "%s" f "\n", __buffer, ## arg); \
|
|
||||||
} else { \
|
|
||||||
for (__i = 0; __i < log_tabbing; __i++) \
|
|
||||||
fprintf(fp, "\t"); \
|
|
||||||
fprintf(fp, f "\n", ## arg); \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
#define LOG_DBG(f, arg...) LOG_OUTPUT(LOG_DEBUG, f, ## arg)
|
|
||||||
#else /* DEBUG */
|
|
||||||
#define LOG_DBG(f, arg...) do {} while (0)
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
#define LOG_COND(__X, f, arg...) do {\
|
|
||||||
if (__X) { \
|
|
||||||
LOG_OUTPUT(LOG_NOTICE, f, ## arg); \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
#define LOG_PRINT(f, arg...) LOG_OUTPUT(LOG_NOTICE, f, ## arg)
|
|
||||||
#define LOG_ERROR(f, arg...) LOG_OUTPUT(LOG_ERR, f, ## arg)
|
|
||||||
|
|
||||||
#endif /* _LVM_CLOG_LOGGING_H */
|
|
||||||
@@ -1,4 +1,19 @@
|
|||||||
init_fifos
|
dm_event_handler_create
|
||||||
fini_fifos
|
dm_event_handler_destroy
|
||||||
daemon_talk
|
dm_event_handler_set_dso
|
||||||
dm_event_get_version
|
dm_event_handler_set_dev_name
|
||||||
|
dm_event_handler_set_uuid
|
||||||
|
dm_event_handler_set_major
|
||||||
|
dm_event_handler_set_minor
|
||||||
|
dm_event_handler_set_event_mask
|
||||||
|
dm_event_handler_get_dso
|
||||||
|
dm_event_handler_get_devname
|
||||||
|
dm_event_handler_get_uuid
|
||||||
|
dm_event_handler_get_major
|
||||||
|
dm_event_handler_get_minor
|
||||||
|
dm_event_handler_get_event_mask
|
||||||
|
dm_event_register_handler
|
||||||
|
dm_event_unregister_handler
|
||||||
|
dm_event_get_registered_device
|
||||||
|
dm_event_handler_set_timeout
|
||||||
|
dm_event_handler_get_timeout
|
||||||
|
|||||||
1
daemons/dmeventd/.gitignore
vendored
1
daemons/dmeventd/.gitignore
vendored
@@ -1 +0,0 @@
|
|||||||
dmeventd
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# Copyright (C) 2005-2011 Red Hat, Inc. All rights reserved.
|
# Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved.
|
||||||
#
|
#
|
||||||
# This file is part of the device-mapper userspace tools.
|
# This file is part of the device-mapper userspace tools.
|
||||||
#
|
#
|
||||||
@@ -13,98 +13,76 @@
|
|||||||
|
|
||||||
srcdir = @srcdir@
|
srcdir = @srcdir@
|
||||||
top_srcdir = @top_srcdir@
|
top_srcdir = @top_srcdir@
|
||||||
top_builddir = @top_builddir@
|
VPATH = @srcdir@
|
||||||
|
|
||||||
SOURCES = libdevmapper-event.c
|
SOURCES = libdevmapper-event.c
|
||||||
SOURCES2 = dmeventd.c
|
|
||||||
|
LIB_STATIC = libdevmapper-event.a
|
||||||
|
|
||||||
|
ifeq ("@LIB_SUFFIX@","dylib")
|
||||||
|
LIB_SHARED = libdevmapper-event.dylib
|
||||||
|
else
|
||||||
|
LIB_SHARED = libdevmapper-event.so
|
||||||
|
VERSIONED_SHLIB = $(LIB_SHARED).$(LIB_VERSION)
|
||||||
|
endif
|
||||||
|
|
||||||
TARGETS = dmeventd
|
TARGETS = dmeventd
|
||||||
|
CLEAN_TARGETS = dmeventd.o
|
||||||
|
|
||||||
.PHONY: install_lib_dynamic install_lib_static install_include \
|
include ../make.tmpl
|
||||||
install_pkgconfig install_dmeventd_dynamic install_dmeventd_static \
|
|
||||||
install_lib install_dmeventd
|
|
||||||
|
|
||||||
INSTALL_DMEVENTD_TARGETS = install_dmeventd_dynamic
|
LDFLAGS += -ldl -ldevmapper -lpthread
|
||||||
INSTALL_LIB_TARGETS = install_lib_dynamic
|
CLDFLAGS += -ldl -ldevmapper -lpthread
|
||||||
|
|
||||||
|
dmeventd: $(LIB_SHARED) $(VERSIONED_SHLIB) dmeventd.o
|
||||||
|
$(CC) -o $@ dmeventd.o $(CFLAGS) $(LDFLAGS) \
|
||||||
|
-L. -ldevmapper-event $(LIBS) -rdynamic
|
||||||
|
|
||||||
|
.PHONY: install_dynamic install_static install_include \
|
||||||
|
install_pkgconfig install_dmeventd
|
||||||
|
|
||||||
|
INSTALL_TYPE = install_dynamic
|
||||||
|
|
||||||
LIB_NAME = libdevmapper-event
|
|
||||||
ifeq ("@STATIC_LINK@", "yes")
|
ifeq ("@STATIC_LINK@", "yes")
|
||||||
LIB_STATIC = $(LIB_NAME).a
|
INSTALL_TYPE += install_static
|
||||||
TARGETS += $(LIB_STATIC) dmeventd.static
|
|
||||||
INSTALL_DMEVENTD_TARGETS += install_dmeventd_static
|
|
||||||
INSTALL_LIB_TARGETS += install_lib_static
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
LIB_VERSION = $(LIB_VERSION_DM)
|
|
||||||
LIB_SHARED = $(LIB_NAME).$(LIB_SUFFIX)
|
|
||||||
|
|
||||||
CLEAN_TARGETS = dmeventd.static $(LIB_NAME).a
|
|
||||||
|
|
||||||
ifneq ($(MAKECMDGOALS),device-mapper)
|
|
||||||
SUBDIRS+=plugins
|
|
||||||
endif
|
|
||||||
|
|
||||||
CFLOW_LIST = $(SOURCES)
|
|
||||||
CFLOW_LIST_TARGET = $(LIB_NAME).cflow
|
|
||||||
CFLOW_TARGET = dmeventd
|
|
||||||
|
|
||||||
EXPORTED_HEADER = $(srcdir)/libdevmapper-event.h
|
|
||||||
EXPORTED_FN_PREFIX = dm_event
|
|
||||||
|
|
||||||
include $(top_builddir)/make.tmpl
|
|
||||||
|
|
||||||
all: device-mapper
|
|
||||||
device-mapper: $(TARGETS)
|
|
||||||
|
|
||||||
LIBS += -ldevmapper
|
|
||||||
LVMLIBS += -ldevmapper-event $(PTHREAD_LIBS)
|
|
||||||
|
|
||||||
CFLAGS_dmeventd.o += $(EXTRA_EXEC_CFLAGS)
|
|
||||||
|
|
||||||
dmeventd: $(LIB_SHARED) dmeventd.o
|
|
||||||
$(CC) $(CFLAGS) $(LDFLAGS) $(EXTRA_EXEC_LDFLAGS) $(ELDFLAGS) -L. -o $@ dmeventd.o \
|
|
||||||
$(DL_LIBS) $(LVMLIBS) $(LIBS) -rdynamic
|
|
||||||
|
|
||||||
dmeventd.static: $(LIB_STATIC) dmeventd.o $(interfacebuilddir)/libdevmapper.a
|
|
||||||
$(CC) $(CFLAGS) $(LDFLAGS) $(ELDFLAGS) -static -L. -L$(interfacebuilddir) -o $@ \
|
|
||||||
dmeventd.o $(DL_LIBS) $(LVMLIBS) $(LIBS) $(STATIC_LIBS)
|
|
||||||
|
|
||||||
ifeq ("@PKGCONFIG@", "yes")
|
ifeq ("@PKGCONFIG@", "yes")
|
||||||
INSTALL_LIB_TARGETS += install_pkgconfig
|
INSTALL_TYPE += install_pkgconfig
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ("$(CFLOW_CMD)", "")
|
install: $(INSTALL_TYPE) install_include install_dmeventd
|
||||||
CFLOW_SOURCES = $(addprefix $(srcdir)/, $(SOURCES))
|
|
||||||
-include $(top_builddir)/libdm/libdevmapper.cflow
|
|
||||||
-include $(top_builddir)/lib/liblvm-internal.cflow
|
|
||||||
-include $(top_builddir)/lib/liblvm2cmd.cflow
|
|
||||||
-include $(top_builddir)/daemons/dmeventd/$(LIB_NAME).cflow
|
|
||||||
-include $(top_builddir)/daemons/dmeventd/plugins/mirror/$(LIB_NAME)-lvm2mirror.cflow
|
|
||||||
endif
|
|
||||||
|
|
||||||
install_include: $(srcdir)/libdevmapper-event.h
|
install_include:
|
||||||
$(INSTALL_DATA) -D $< $(includedir)/$(<F)
|
$(INSTALL) -D $(OWNER) $(GROUP) -m 444 libdevmapper-event.h \
|
||||||
|
$(includedir)/libdevmapper-event.h
|
||||||
|
|
||||||
install_pkgconfig: libdevmapper-event.pc
|
install_dynamic: libdevmapper-event.$(LIB_SUFFIX)
|
||||||
$(INSTALL_DATA) -D $< $(pkgconfigdir)/devmapper-event.pc
|
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \
|
||||||
|
$(libdir)/libdevmapper-event.$(LIB_SUFFIX).$(LIB_VERSION)
|
||||||
|
$(LN_S) -f libdevmapper-event.$(LIB_SUFFIX).$(LIB_VERSION) \
|
||||||
|
$(libdir)/libdevmapper-event.$(LIB_SUFFIX)
|
||||||
|
|
||||||
install_lib_dynamic: install_lib_shared
|
install_dmeventd: dmeventd
|
||||||
|
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< $(sbindir)/$<
|
||||||
|
|
||||||
install_lib_static: $(LIB_STATIC)
|
install_pkgconfig:
|
||||||
$(INSTALL_DATA) -D $< $(usrlibdir)/$(<F)
|
$(INSTALL) -D $(OWNER) $(GROUP) -m 444 libdevmapper-event.pc \
|
||||||
|
$(usrlibdir)/pkgconfig/devmapper-event.pc
|
||||||
|
|
||||||
install_lib: $(INSTALL_LIB_TARGETS)
|
install_static: libdevmapper-event.a
|
||||||
|
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \
|
||||||
|
$(libdir)/libdevmapper-event.a.$(LIB_VERSION)
|
||||||
|
$(LN_S) -f libdevmapper-event.a.$(LIB_VERSION) $(libdir)/libdevmapper-event.a
|
||||||
|
|
||||||
install_dmeventd_dynamic: dmeventd
|
$(VERSIONED_SHLIB): $(LIB_SHARED)
|
||||||
$(INSTALL_PROGRAM) -D $< $(sbindir)/$(<F)
|
$(RM) -f $@
|
||||||
|
$(LN_S) $(LIB_SHARED) $@
|
||||||
|
|
||||||
install_dmeventd_static: dmeventd.static
|
.PHONY: distclean_lib distclean
|
||||||
$(INSTALL_PROGRAM) -D $< $(staticdir)/$(<F)
|
|
||||||
|
|
||||||
install_dmeventd: $(INSTALL_DMEVENTD_TARGETS)
|
distclean_lib:
|
||||||
|
$(RM) libdevmapper-event.pc
|
||||||
|
|
||||||
install: install_include install_lib install_dmeventd
|
distclean: distclean_lib
|
||||||
|
|
||||||
install_device-mapper: install_include install_lib install_dmeventd
|
|
||||||
|
|
||||||
DISTCLEAN_TARGETS += libdevmapper-event.pc
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -17,8 +17,11 @@
|
|||||||
|
|
||||||
/* FIXME This stuff must be configurable. */
|
/* FIXME This stuff must be configurable. */
|
||||||
|
|
||||||
#define DM_EVENT_FIFO_CLIENT DEFAULT_DM_RUN_DIR "/dmeventd-client"
|
#define DM_EVENT_DAEMON "/sbin/dmeventd"
|
||||||
#define DM_EVENT_FIFO_SERVER DEFAULT_DM_RUN_DIR "/dmeventd-server"
|
#define DM_EVENT_LOCKFILE "/var/lock/dmeventd"
|
||||||
|
#define DM_EVENT_FIFO_CLIENT "/var/run/dmeventd-client"
|
||||||
|
#define DM_EVENT_FIFO_SERVER "/var/run/dmeventd-server"
|
||||||
|
#define DM_EVENT_PIDFILE "/var/run/dmeventd.pid"
|
||||||
|
|
||||||
#define DM_EVENT_DEFAULT_TIMEOUT 10
|
#define DM_EVENT_DEFAULT_TIMEOUT 10
|
||||||
|
|
||||||
@@ -32,9 +35,6 @@ enum dm_event_command {
|
|||||||
DM_EVENT_CMD_SET_TIMEOUT,
|
DM_EVENT_CMD_SET_TIMEOUT,
|
||||||
DM_EVENT_CMD_GET_TIMEOUT,
|
DM_EVENT_CMD_GET_TIMEOUT,
|
||||||
DM_EVENT_CMD_HELLO,
|
DM_EVENT_CMD_HELLO,
|
||||||
DM_EVENT_CMD_DIE,
|
|
||||||
DM_EVENT_CMD_GET_STATUS,
|
|
||||||
DM_EVENT_CMD_GET_PARAMETERS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Message passed between client and daemon. */
|
/* Message passed between client and daemon. */
|
||||||
@@ -56,21 +56,11 @@ struct dm_event_fifos {
|
|||||||
|
|
||||||
/* EXIT_SUCCESS 0 -- stdlib.h */
|
/* EXIT_SUCCESS 0 -- stdlib.h */
|
||||||
/* EXIT_FAILURE 1 -- stdlib.h */
|
/* EXIT_FAILURE 1 -- stdlib.h */
|
||||||
/* EXIT_LOCKFILE_INUSE 2 -- obsoleted */
|
#define EXIT_LOCKFILE_INUSE 2
|
||||||
#define EXIT_DESC_CLOSE_FAILURE 3
|
#define EXIT_DESC_CLOSE_FAILURE 3
|
||||||
#define EXIT_DESC_OPEN_FAILURE 4
|
#define EXIT_DESC_OPEN_FAILURE 4
|
||||||
/* EXIT_OPEN_PID_FAILURE 5 -- obsoleted */
|
#define EXIT_OPEN_PID_FAILURE 5
|
||||||
#define EXIT_FIFO_FAILURE 6
|
#define EXIT_FIFO_FAILURE 6
|
||||||
#define EXIT_CHDIR_FAILURE 7
|
#define EXIT_CHDIR_FAILURE 7
|
||||||
|
|
||||||
/* Implemented in libdevmapper-event.c, but not part of public API. */
|
|
||||||
// FIXME misuse of bitmask as enum
|
|
||||||
int daemon_talk(struct dm_event_fifos *fifos,
|
|
||||||
struct dm_event_daemon_message *msg, int cmd,
|
|
||||||
const char *dso_name, const char *dev_name,
|
|
||||||
enum dm_event_mask evmask, uint32_t timeout);
|
|
||||||
int init_fifos(struct dm_event_fifos *fifos);
|
|
||||||
void fini_fifos(struct dm_event_fifos *fifos);
|
|
||||||
int dm_event_get_version(struct dm_event_fifos *fifos, int *version);
|
|
||||||
|
|
||||||
#endif /* __DMEVENTD_DOT_H__ */
|
#endif /* __DMEVENTD_DOT_H__ */
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2015 Red Hat, Inc. All rights reserved.
|
* Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* This file is part of the device-mapper userspace tools.
|
* This file is part of the device-mapper userspace tools.
|
||||||
*
|
*
|
||||||
@@ -12,29 +12,29 @@
|
|||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "dm-logging.h"
|
#include "lib.h"
|
||||||
#include "dmlib.h"
|
|
||||||
#include "libdevmapper-event.h"
|
#include "libdevmapper-event.h"
|
||||||
|
//#include "libmultilog.h"
|
||||||
#include "dmeventd.h"
|
#include "dmeventd.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <sys/file.h>
|
#include <sys/file.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <arpa/inet.h> /* for htonl, ntohl */
|
#include <arpa/inet.h> /* for htonl, ntohl */
|
||||||
#include <pthread.h>
|
|
||||||
#include <syslog.h>
|
|
||||||
|
|
||||||
static int _debug_level = 0;
|
|
||||||
static int _use_syslog = 0;
|
|
||||||
static int _sequence_nr = 0;
|
static int _sequence_nr = 0;
|
||||||
|
|
||||||
struct dm_event_handler {
|
struct dm_event_handler {
|
||||||
char *dso;
|
char *dso;
|
||||||
|
|
||||||
char *dmeventd_path;
|
|
||||||
|
|
||||||
char *dev_name;
|
char *dev_name;
|
||||||
|
|
||||||
char *uuid;
|
char *uuid;
|
||||||
@@ -47,20 +47,25 @@ struct dm_event_handler {
|
|||||||
|
|
||||||
static void _dm_event_handler_clear_dev_info(struct dm_event_handler *dmevh)
|
static void _dm_event_handler_clear_dev_info(struct dm_event_handler *dmevh)
|
||||||
{
|
{
|
||||||
dm_free(dmevh->dev_name);
|
if (dmevh->dev_name)
|
||||||
dm_free(dmevh->uuid);
|
dm_free(dmevh->dev_name);
|
||||||
|
if (dmevh->uuid)
|
||||||
|
dm_free(dmevh->uuid);
|
||||||
dmevh->dev_name = dmevh->uuid = NULL;
|
dmevh->dev_name = dmevh->uuid = NULL;
|
||||||
dmevh->major = dmevh->minor = 0;
|
dmevh->major = dmevh->minor = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct dm_event_handler *dm_event_handler_create(void)
|
struct dm_event_handler *dm_event_handler_create(void)
|
||||||
{
|
{
|
||||||
struct dm_event_handler *dmevh;
|
struct dm_event_handler *dmevh = NULL;
|
||||||
|
|
||||||
if (!(dmevh = dm_zalloc(sizeof(*dmevh)))) {
|
if (!(dmevh = dm_malloc(sizeof(*dmevh))))
|
||||||
log_error("Failed to allocate event handler.");
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
|
dmevh->dso = dmevh->dev_name = dmevh->uuid = NULL;
|
||||||
|
dmevh->major = dmevh->minor = 0;
|
||||||
|
dmevh->mask = 0;
|
||||||
|
dmevh->timeout = 0;
|
||||||
|
|
||||||
return dmevh;
|
return dmevh;
|
||||||
}
|
}
|
||||||
@@ -68,32 +73,20 @@ struct dm_event_handler *dm_event_handler_create(void)
|
|||||||
void dm_event_handler_destroy(struct dm_event_handler *dmevh)
|
void dm_event_handler_destroy(struct dm_event_handler *dmevh)
|
||||||
{
|
{
|
||||||
_dm_event_handler_clear_dev_info(dmevh);
|
_dm_event_handler_clear_dev_info(dmevh);
|
||||||
dm_free(dmevh->dso);
|
if (dmevh->dso)
|
||||||
dm_free(dmevh->dmeventd_path);
|
dm_free(dmevh->dso);
|
||||||
dm_free(dmevh);
|
dm_free(dmevh);
|
||||||
}
|
}
|
||||||
|
|
||||||
int dm_event_handler_set_dmeventd_path(struct dm_event_handler *dmevh, const char *dmeventd_path)
|
|
||||||
{
|
|
||||||
if (!dmeventd_path) /* noop */
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
dm_free(dmevh->dmeventd_path);
|
|
||||||
|
|
||||||
if (!(dmevh->dmeventd_path = dm_strdup(dmeventd_path)))
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int dm_event_handler_set_dso(struct dm_event_handler *dmevh, const char *path)
|
int dm_event_handler_set_dso(struct dm_event_handler *dmevh, const char *path)
|
||||||
{
|
{
|
||||||
if (!path) /* noop */
|
if (!path) /* noop */
|
||||||
return 0;
|
return 0;
|
||||||
|
if (dmevh->dso)
|
||||||
|
dm_free(dmevh->dso);
|
||||||
|
|
||||||
dm_free(dmevh->dso);
|
dmevh->dso = dm_strdup(path);
|
||||||
|
if (!dmevh->dso)
|
||||||
if (!(dmevh->dso = dm_strdup(path)))
|
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -106,9 +99,9 @@ int dm_event_handler_set_dev_name(struct dm_event_handler *dmevh, const char *de
|
|||||||
|
|
||||||
_dm_event_handler_clear_dev_info(dmevh);
|
_dm_event_handler_clear_dev_info(dmevh);
|
||||||
|
|
||||||
if (!(dmevh->dev_name = dm_strdup(dev_name)))
|
dmevh->dev_name = dm_strdup(dev_name);
|
||||||
|
if (!dmevh->dev_name)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,9 +112,9 @@ int dm_event_handler_set_uuid(struct dm_event_handler *dmevh, const char *uuid)
|
|||||||
|
|
||||||
_dm_event_handler_clear_dev_info(dmevh);
|
_dm_event_handler_clear_dev_info(dmevh);
|
||||||
|
|
||||||
if (!(dmevh->uuid = dm_strdup(uuid)))
|
dmevh->uuid = dm_strdup(uuid);
|
||||||
|
if (!dmevh->dev_name)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,7 +191,7 @@ static int _check_message_id(struct dm_event_daemon_message *msg)
|
|||||||
if ((sscanf(msg->data, "%d:%d", &pid, &seq_nr) != 2) ||
|
if ((sscanf(msg->data, "%d:%d", &pid, &seq_nr) != 2) ||
|
||||||
(pid != getpid()) || (seq_nr != _sequence_nr)) {
|
(pid != getpid()) || (seq_nr != _sequence_nr)) {
|
||||||
log_error("Ignoring out-of-sequence reply from dmeventd. "
|
log_error("Ignoring out-of-sequence reply from dmeventd. "
|
||||||
"Expected %d:%d but received %s.", getpid(),
|
"Expected %d:%d but received %s", getpid(),
|
||||||
_sequence_nr, msg->data);
|
_sequence_nr, msg->data);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -221,23 +214,21 @@ static int _daemon_read(struct dm_event_fifos *fifos,
|
|||||||
unsigned bytes = 0;
|
unsigned bytes = 0;
|
||||||
int ret, i;
|
int ret, i;
|
||||||
fd_set fds;
|
fd_set fds;
|
||||||
|
struct timeval tval = { 0, 0 };
|
||||||
size_t size = 2 * sizeof(uint32_t); /* status + size */
|
size_t size = 2 * sizeof(uint32_t); /* status + size */
|
||||||
uint32_t *header = alloca(size);
|
char *buf = alloca(size);
|
||||||
char *buf = (char *)header;
|
int header = 1;
|
||||||
|
|
||||||
while (bytes < size) {
|
while (bytes < size) {
|
||||||
for (i = 0, ret = 0; (i < 20) && (ret < 1); i++) {
|
for (i = 0, ret = 0; (i < 20) && (ret < 1); i++) {
|
||||||
/* Watch daemon read FIFO for input. */
|
/* Watch daemon read FIFO for input. */
|
||||||
struct timeval tval = { .tv_sec = 1 };
|
|
||||||
FD_ZERO(&fds);
|
FD_ZERO(&fds);
|
||||||
FD_SET(fifos->server, &fds);
|
FD_SET(fifos->server, &fds);
|
||||||
ret = select(fifos->server + 1, &fds, NULL, NULL, &tval);
|
tval.tv_sec = 1;
|
||||||
|
ret = select(fifos->server + 1, &fds, NULL, NULL,
|
||||||
|
&tval);
|
||||||
if (ret < 0 && errno != EINTR) {
|
if (ret < 0 && errno != EINTR) {
|
||||||
log_error("Unable to read from event server.");
|
log_error("Unable to read from event server");
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if ((ret == 0) && (i > 4) && !bytes) {
|
|
||||||
log_error("No input from event server.");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -257,9 +248,9 @@ static int _daemon_read(struct dm_event_fifos *fifos,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bytes += ret;
|
bytes += ret;
|
||||||
if (header && (bytes == 2 * sizeof(uint32_t))) {
|
if (bytes == 2 * sizeof(uint32_t) && header) {
|
||||||
msg->cmd = ntohl(header[0]);
|
msg->cmd = ntohl(*((uint32_t *)buf));
|
||||||
msg->size = ntohl(header[1]);
|
msg->size = ntohl(*((uint32_t *)buf + 1));
|
||||||
buf = msg->data = dm_malloc(msg->size);
|
buf = msg->data = dm_malloc(msg->size);
|
||||||
size = msg->size;
|
size = msg->size;
|
||||||
bytes = 0;
|
bytes = 0;
|
||||||
@@ -268,9 +259,11 @@ static int _daemon_read(struct dm_event_fifos *fifos,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (bytes != size) {
|
if (bytes != size) {
|
||||||
dm_free(msg->data);
|
if (msg->data)
|
||||||
|
dm_free(msg->data);
|
||||||
msg->data = NULL;
|
msg->data = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return bytes == size;
|
return bytes == size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -278,39 +271,32 @@ static int _daemon_read(struct dm_event_fifos *fifos,
|
|||||||
static int _daemon_write(struct dm_event_fifos *fifos,
|
static int _daemon_write(struct dm_event_fifos *fifos,
|
||||||
struct dm_event_daemon_message *msg)
|
struct dm_event_daemon_message *msg)
|
||||||
{
|
{
|
||||||
int ret;
|
unsigned bytes = 0;
|
||||||
|
int ret = 0;
|
||||||
fd_set fds;
|
fd_set fds;
|
||||||
size_t bytes = 0;
|
|
||||||
size_t size = 2 * sizeof(uint32_t) + msg->size;
|
|
||||||
uint32_t *header = alloca(size);
|
|
||||||
char *buf = (char *)header;
|
|
||||||
char drainbuf[128];
|
|
||||||
|
|
||||||
header[0] = htonl(msg->cmd);
|
size_t size = 2 * sizeof(uint32_t) + msg->size;
|
||||||
header[1] = htonl(msg->size);
|
char *buf = alloca(size);
|
||||||
|
char drainbuf[128];
|
||||||
|
struct timeval tval = { 0, 0 };
|
||||||
|
|
||||||
|
*((uint32_t *)buf) = htonl(msg->cmd);
|
||||||
|
*((uint32_t *)buf + 1) = htonl(msg->size);
|
||||||
memcpy(buf + 2 * sizeof(uint32_t), msg->data, msg->size);
|
memcpy(buf + 2 * sizeof(uint32_t), msg->data, msg->size);
|
||||||
|
|
||||||
/* drain the answer fifo */
|
/* drain the answer fifo */
|
||||||
while (1) {
|
while (1) {
|
||||||
struct timeval tval = { .tv_usec = 100 };
|
|
||||||
FD_ZERO(&fds);
|
FD_ZERO(&fds);
|
||||||
FD_SET(fifos->server, &fds);
|
FD_SET(fifos->server, &fds);
|
||||||
|
tval.tv_usec = 100;
|
||||||
ret = select(fifos->server + 1, &fds, NULL, NULL, &tval);
|
ret = select(fifos->server + 1, &fds, NULL, NULL, &tval);
|
||||||
if (ret < 0) {
|
if ((ret < 0) && (errno != EINTR)) {
|
||||||
if (errno == EINTR)
|
log_error("Unable to talk to event daemon");
|
||||||
continue;
|
|
||||||
log_error("Unable to talk to event daemon.");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
break;
|
break;
|
||||||
ret = read(fifos->server, drainbuf, sizeof(drainbuf));
|
read(fifos->server, drainbuf, 127);
|
||||||
if (ret < 0) {
|
|
||||||
if ((errno == EINTR) || (errno == EAGAIN))
|
|
||||||
continue;
|
|
||||||
log_error("Unable to talk to event daemon.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (bytes < size) {
|
while (bytes < size) {
|
||||||
@@ -320,17 +306,18 @@ static int _daemon_write(struct dm_event_fifos *fifos,
|
|||||||
FD_SET(fifos->client, &fds);
|
FD_SET(fifos->client, &fds);
|
||||||
ret = select(fifos->client + 1, NULL, &fds, NULL, NULL);
|
ret = select(fifos->client + 1, NULL, &fds, NULL, NULL);
|
||||||
if ((ret < 0) && (errno != EINTR)) {
|
if ((ret < 0) && (errno != EINTR)) {
|
||||||
log_error("Unable to talk to event daemon.");
|
log_error("Unable to talk to event daemon");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} while (ret < 1);
|
} while (ret < 1);
|
||||||
|
|
||||||
ret = write(fifos->client, buf + bytes, size - bytes);
|
ret = write(fifos->client, ((char *) buf) + bytes,
|
||||||
|
size - bytes);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
if ((errno == EINTR) || (errno == EAGAIN))
|
if ((errno == EINTR) || (errno == EAGAIN))
|
||||||
continue;
|
continue;
|
||||||
else {
|
else {
|
||||||
log_error("Unable to talk to event daemon.");
|
log_error("Unable to talk to event daemon");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -341,11 +328,14 @@ static int _daemon_write(struct dm_event_fifos *fifos,
|
|||||||
return bytes == size;
|
return bytes == size;
|
||||||
}
|
}
|
||||||
|
|
||||||
int daemon_talk(struct dm_event_fifos *fifos,
|
static int _daemon_talk(struct dm_event_fifos *fifos,
|
||||||
struct dm_event_daemon_message *msg, int cmd,
|
struct dm_event_daemon_message *msg, int cmd,
|
||||||
const char *dso_name, const char *dev_name,
|
const char *dso_name, const char *dev_name,
|
||||||
enum dm_event_mask evmask, uint32_t timeout)
|
enum dm_event_mask evmask, uint32_t timeout)
|
||||||
{
|
{
|
||||||
|
const char *dso = dso_name ? dso_name : "";
|
||||||
|
const char *dev = dev_name ? dev_name : "";
|
||||||
|
const char *fmt = "%d:%d %s %s %u %" PRIu32;
|
||||||
int msg_size;
|
int msg_size;
|
||||||
memset(msg, 0, sizeof(*msg));
|
memset(msg, 0, sizeof(*msg));
|
||||||
|
|
||||||
@@ -353,17 +343,14 @@ int daemon_talk(struct dm_event_fifos *fifos,
|
|||||||
* Set command and pack the arguments
|
* Set command and pack the arguments
|
||||||
* into ASCII message string.
|
* into ASCII message string.
|
||||||
*/
|
*/
|
||||||
if ((msg_size =
|
msg->cmd = cmd;
|
||||||
((cmd == DM_EVENT_CMD_HELLO) ?
|
if (cmd == DM_EVENT_CMD_HELLO)
|
||||||
dm_asprintf(&(msg->data), "%d:%d HELLO", getpid(), _sequence_nr) :
|
fmt = "%d:%d HELLO";
|
||||||
dm_asprintf(&(msg->data), "%d:%d %s %s %u %" PRIu32,
|
if ((msg_size = dm_asprintf(&(msg->data), fmt, getpid(), _sequence_nr,
|
||||||
getpid(), _sequence_nr,
|
dso, dev, evmask, timeout)) < 0) {
|
||||||
dso_name ? : "-", dev_name ? : "-", evmask, timeout)))
|
log_error("_daemon_talk: message allocation failed");
|
||||||
< 0) {
|
|
||||||
log_error("_daemon_talk: message allocation failed.");
|
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
msg->cmd = cmd;
|
|
||||||
msg->size = msg_size;
|
msg->size = msg_size;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -373,13 +360,15 @@ int daemon_talk(struct dm_event_fifos *fifos,
|
|||||||
if (!_daemon_write(fifos, msg)) {
|
if (!_daemon_write(fifos, msg)) {
|
||||||
stack;
|
stack;
|
||||||
dm_free(msg->data);
|
dm_free(msg->data);
|
||||||
msg->data = NULL;
|
msg->data = 0;
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
dm_free(msg->data);
|
|
||||||
msg->data = NULL;
|
if (msg->data)
|
||||||
|
dm_free(msg->data);
|
||||||
|
msg->data = 0;
|
||||||
|
|
||||||
if (!_daemon_read(fifos, msg)) {
|
if (!_daemon_read(fifos, msg)) {
|
||||||
stack;
|
stack;
|
||||||
@@ -404,13 +393,11 @@ int daemon_talk(struct dm_event_fifos *fifos,
|
|||||||
*
|
*
|
||||||
* Returns: 1 on success, 0 otherwise
|
* Returns: 1 on success, 0 otherwise
|
||||||
*/
|
*/
|
||||||
static int _start_daemon(char *dmeventd_path, struct dm_event_fifos *fifos)
|
static int _start_daemon(struct dm_event_fifos *fifos)
|
||||||
{
|
{
|
||||||
int pid, ret = 0;
|
int pid, ret = 0;
|
||||||
int status;
|
int status;
|
||||||
struct stat statbuf;
|
struct stat statbuf;
|
||||||
char default_dmeventd_path[] = DMEVENTD_PATH;
|
|
||||||
char *args[] = { dmeventd_path ? : default_dmeventd_path, NULL };
|
|
||||||
|
|
||||||
if (stat(fifos->client_path, &statbuf))
|
if (stat(fifos->client_path, &statbuf))
|
||||||
goto start_server;
|
goto start_server;
|
||||||
@@ -424,35 +411,31 @@ static int _start_daemon(char *dmeventd_path, struct dm_event_fifos *fifos)
|
|||||||
fifos->client = open(fifos->client_path, O_WRONLY | O_NONBLOCK);
|
fifos->client = open(fifos->client_path, O_WRONLY | O_NONBLOCK);
|
||||||
if (fifos->client >= 0) {
|
if (fifos->client >= 0) {
|
||||||
/* server is running and listening */
|
/* server is running and listening */
|
||||||
if (close(fifos->client))
|
|
||||||
log_sys_debug("close", fifos->client_path);
|
close(fifos->client);
|
||||||
return 1;
|
return 1;
|
||||||
} else if (errno != ENXIO) {
|
} else if (errno != ENXIO) {
|
||||||
/* problem */
|
/* problem */
|
||||||
log_sys_error("open", fifos->client_path);
|
|
||||||
|
log_error("%s: Can't open client fifo %s: %s",
|
||||||
|
__func__, fifos->client_path, strerror(errno));
|
||||||
|
stack;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
start_server:
|
start_server:
|
||||||
/* server is not running */
|
/* server is not running */
|
||||||
|
|
||||||
if ((args[0][0] == '/') && stat(args[0], &statbuf)) {
|
|
||||||
log_sys_error("stat", args[0]);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pid = fork();
|
pid = fork();
|
||||||
|
|
||||||
if (pid < 0)
|
if (pid < 0)
|
||||||
log_sys_error("fork", "");
|
log_error("Unable to fork.");
|
||||||
|
|
||||||
else if (!pid) {
|
else if (!pid) {
|
||||||
execvp(args[0], args);
|
execvp(DMEVENTD_PATH, NULL);
|
||||||
log_error("Unable to exec dmeventd: %s.", strerror(errno));
|
exit(EXIT_FAILURE);
|
||||||
_exit(EXIT_FAILURE);
|
|
||||||
} else {
|
} else {
|
||||||
if (waitpid(pid, &status, 0) < 0)
|
if (waitpid(pid, &status, 0) < 0)
|
||||||
log_error("Unable to start dmeventd: %s.",
|
log_error("Unable to start dmeventd: %s",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
else if (WEXITSTATUS(status))
|
else if (WEXITSTATUS(status))
|
||||||
log_error("Unable to start dmeventd.");
|
log_error("Unable to start dmeventd.");
|
||||||
@@ -463,59 +446,56 @@ static int _start_daemon(char *dmeventd_path, struct dm_event_fifos *fifos)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int init_fifos(struct dm_event_fifos *fifos)
|
/* Initialize client. */
|
||||||
|
static int _init_client(struct dm_event_fifos *fifos)
|
||||||
{
|
{
|
||||||
/* FIXME? Is fifo the most suitable method? Why not share
|
/* FIXME? Is fifo the most suitable method? Why not share
|
||||||
comms/daemon code with something else e.g. multipath? */
|
comms/daemon code with something else e.g. multipath? */
|
||||||
|
|
||||||
|
/* init fifos */
|
||||||
|
memset(fifos, 0, sizeof(*fifos));
|
||||||
|
fifos->client_path = DM_EVENT_FIFO_CLIENT;
|
||||||
|
fifos->server_path = DM_EVENT_FIFO_SERVER;
|
||||||
|
|
||||||
|
if (!_start_daemon(fifos)) {
|
||||||
|
stack;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Open the fifo used to read from the daemon. */
|
/* Open the fifo used to read from the daemon. */
|
||||||
if ((fifos->server = open(fifos->server_path, O_RDWR)) < 0) {
|
if ((fifos->server = open(fifos->server_path, O_RDWR)) < 0) {
|
||||||
log_sys_error("open", fifos->server_path);
|
log_error("%s: open server fifo %s",
|
||||||
|
__func__, fifos->server_path);
|
||||||
|
stack;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lock out anyone else trying to do communication with the daemon. */
|
/* Lock out anyone else trying to do communication with the daemon. */
|
||||||
if (flock(fifos->server, LOCK_EX) < 0) {
|
if (flock(fifos->server, LOCK_EX) < 0) {
|
||||||
log_sys_error("flock", fifos->server_path);
|
log_error("%s: flock %s", __func__, fifos->server_path);
|
||||||
goto bad;
|
close(fifos->server);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if ((fifos->client = open(fifos->client_path, O_WRONLY | O_NONBLOCK)) < 0) {*/
|
/* if ((fifos->client = open(fifos->client_path, O_WRONLY | O_NONBLOCK)) < 0) {*/
|
||||||
if ((fifos->client = open(fifos->client_path, O_RDWR | O_NONBLOCK)) < 0) {
|
if ((fifos->client = open(fifos->client_path, O_RDWR | O_NONBLOCK)) < 0) {
|
||||||
log_sys_error("open", fifos->client_path);
|
log_error("%s: Can't open client fifo %s: %s",
|
||||||
goto bad;
|
__func__, fifos->client_path, strerror(errno));
|
||||||
|
close(fifos->server);
|
||||||
|
stack;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
bad:
|
|
||||||
if (close(fifos->server))
|
|
||||||
log_sys_debug("close", fifos->server_path);
|
|
||||||
fifos->server = -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize client. */
|
static void _dtr_client(struct dm_event_fifos *fifos)
|
||||||
static int _init_client(char *dmeventd_path, struct dm_event_fifos *fifos)
|
|
||||||
{
|
{
|
||||||
if (!_start_daemon(dmeventd_path, fifos))
|
if (flock(fifos->server, LOCK_UN))
|
||||||
return_0;
|
log_error("flock unlock %s", fifos->server_path);
|
||||||
|
|
||||||
return init_fifos(fifos);
|
close(fifos->client);
|
||||||
}
|
close(fifos->server);
|
||||||
|
|
||||||
void fini_fifos(struct dm_event_fifos *fifos)
|
|
||||||
{
|
|
||||||
if (fifos->client >= 0 && close(fifos->client))
|
|
||||||
log_sys_debug("close", fifos->client_path);
|
|
||||||
|
|
||||||
if (fifos->server >= 0) {
|
|
||||||
if (flock(fifos->server, LOCK_UN))
|
|
||||||
log_sys_debug("flock unlock", fifos->server_path);
|
|
||||||
|
|
||||||
if (close(fifos->server))
|
|
||||||
log_sys_debug("close", fifos->server_path);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get uuid of a device */
|
/* Get uuid of a device */
|
||||||
@@ -525,82 +505,66 @@ static struct dm_task *_get_device_info(const struct dm_event_handler *dmevh)
|
|||||||
struct dm_info info;
|
struct dm_info info;
|
||||||
|
|
||||||
if (!(dmt = dm_task_create(DM_DEVICE_INFO))) {
|
if (!(dmt = dm_task_create(DM_DEVICE_INFO))) {
|
||||||
log_error("_get_device_info: dm_task creation for info failed.");
|
log_error("_get_device_info: dm_task creation for info failed");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dmevh->uuid) {
|
if (dmevh->uuid)
|
||||||
if (!dm_task_set_uuid(dmt, dmevh->uuid))
|
dm_task_set_uuid(dmt, dmevh->uuid);
|
||||||
goto_bad;
|
else if (dmevh->dev_name)
|
||||||
} else if (dmevh->dev_name) {
|
dm_task_set_name(dmt, dmevh->dev_name);
|
||||||
if (!dm_task_set_name(dmt, dmevh->dev_name))
|
else if (dmevh->major && dmevh->minor) {
|
||||||
goto_bad;
|
dm_task_set_major(dmt, dmevh->major);
|
||||||
} else if (dmevh->major && dmevh->minor) {
|
dm_task_set_minor(dmt, dmevh->minor);
|
||||||
if (!dm_task_set_major(dmt, dmevh->major) ||
|
}
|
||||||
!dm_task_set_minor(dmt, dmevh->minor))
|
|
||||||
goto_bad;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* FIXME Add name or uuid or devno to messages */
|
/* FIXME Add name or uuid or devno to messages */
|
||||||
if (!dm_task_run(dmt)) {
|
if (!dm_task_run(dmt)) {
|
||||||
log_error("_get_device_info: dm_task_run() failed.");
|
log_error("_get_device_info: dm_task_run() failed");
|
||||||
goto bad;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dm_task_get_info(dmt, &info)) {
|
if (!dm_task_get_info(dmt, &info)) {
|
||||||
log_error("_get_device_info: failed to get info for device.");
|
log_error("_get_device_info: failed to get info for device");
|
||||||
goto bad;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!info.exists) {
|
if (!info.exists) {
|
||||||
log_error("_get_device_info: %s%s%s%.0d%s%.0d%s%s: device not found.",
|
log_error("_get_device_info: device not found");
|
||||||
dmevh->uuid ? : "",
|
goto failed;
|
||||||
(!dmevh->uuid && dmevh->dev_name) ? dmevh->dev_name : "",
|
|
||||||
(!dmevh->uuid && !dmevh->dev_name && dmevh->major > 0) ? "(" : "",
|
|
||||||
(!dmevh->uuid && !dmevh->dev_name && dmevh->major > 0) ? dmevh->major : 0,
|
|
||||||
(!dmevh->uuid && !dmevh->dev_name && dmevh->major > 0) ? ":" : "",
|
|
||||||
(!dmevh->uuid && !dmevh->dev_name && dmevh->minor > 0) ? dmevh->minor : 0,
|
|
||||||
(!dmevh->uuid && !dmevh->dev_name && dmevh->major > 0) && dmevh->minor == 0 ? "0" : "",
|
|
||||||
(!dmevh->uuid && !dmevh->dev_name && dmevh->major > 0) ? ") " : "");
|
|
||||||
goto bad;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return dmt;
|
return dmt;
|
||||||
|
|
||||||
bad:
|
failed:
|
||||||
dm_task_destroy(dmt);
|
dm_task_destroy(dmt);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle the event (de)registration call and return negative error codes. */
|
/* Handle the event (de)registration call and return negative error codes. */
|
||||||
static int _do_event(int cmd, char *dmeventd_path, struct dm_event_daemon_message *msg,
|
static int _do_event(int cmd, struct dm_event_daemon_message *msg,
|
||||||
const char *dso_name, const char *dev_name,
|
const char *dso_name, const char *dev_name,
|
||||||
enum dm_event_mask evmask, uint32_t timeout)
|
enum dm_event_mask evmask, uint32_t timeout)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct dm_event_fifos fifos = {
|
struct dm_event_fifos fifos;
|
||||||
.server = -1,
|
|
||||||
.client = -1,
|
|
||||||
/* FIXME Make these either configurable or depend directly on dmeventd_path */
|
|
||||||
.client_path = DM_EVENT_FIFO_CLIENT,
|
|
||||||
.server_path = DM_EVENT_FIFO_SERVER
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!_init_client(dmeventd_path, &fifos)) {
|
if (!_init_client(&fifos)) {
|
||||||
stack;
|
stack;
|
||||||
return -ESRCH;
|
return -ESRCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = daemon_talk(&fifos, msg, DM_EVENT_CMD_HELLO, NULL, NULL, 0, 0);
|
ret = _daemon_talk(&fifos, msg, DM_EVENT_CMD_HELLO, 0, 0, 0, 0);
|
||||||
|
|
||||||
dm_free(msg->data);
|
if (msg->data)
|
||||||
|
dm_free(msg->data);
|
||||||
msg->data = 0;
|
msg->data = 0;
|
||||||
|
|
||||||
if (!ret)
|
if (!ret)
|
||||||
ret = daemon_talk(&fifos, msg, cmd, dso_name, dev_name, evmask, timeout);
|
ret = _daemon_talk(&fifos, msg, cmd, dso_name, dev_name, evmask, timeout);
|
||||||
|
|
||||||
/* what is the opposite of init? */
|
/* what is the opposite of init? */
|
||||||
fini_fifos(&fifos);
|
_dtr_client(&fifos);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -611,29 +575,25 @@ int dm_event_register_handler(const struct dm_event_handler *dmevh)
|
|||||||
int ret = 1, err;
|
int ret = 1, err;
|
||||||
const char *uuid;
|
const char *uuid;
|
||||||
struct dm_task *dmt;
|
struct dm_task *dmt;
|
||||||
struct dm_event_daemon_message msg = { 0 };
|
struct dm_event_daemon_message msg = { 0, 0, NULL };
|
||||||
|
|
||||||
if (!(dmt = _get_device_info(dmevh)))
|
if (!(dmt = _get_device_info(dmevh))) {
|
||||||
return_0;
|
stack;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
uuid = dm_task_get_uuid(dmt);
|
uuid = dm_task_get_uuid(dmt);
|
||||||
|
|
||||||
if (!strstr(dmevh->dso, "libdevmapper-event-lvm2thin.so") &&
|
if ((err = _do_event(DM_EVENT_CMD_REGISTER_FOR_EVENT, &msg,
|
||||||
!strstr(dmevh->dso, "libdevmapper-event-lvm2snapshot.so") &&
|
|
||||||
!strstr(dmevh->dso, "libdevmapper-event-lvm2mirror.so") &&
|
|
||||||
!strstr(dmevh->dso, "libdevmapper-event-lvm2raid.so"))
|
|
||||||
log_warn("WARNING: %s: dmeventd plugins are deprecated.", dmevh->dso);
|
|
||||||
|
|
||||||
|
|
||||||
if ((err = _do_event(DM_EVENT_CMD_REGISTER_FOR_EVENT, dmevh->dmeventd_path, &msg,
|
|
||||||
dmevh->dso, uuid, dmevh->mask, dmevh->timeout)) < 0) {
|
dmevh->dso, uuid, dmevh->mask, dmevh->timeout)) < 0) {
|
||||||
log_error("%s: event registration failed: %s.",
|
log_error("%s: event registration failed: %s",
|
||||||
dm_task_get_name(dmt),
|
dm_task_get_name(dmt),
|
||||||
msg.data ? msg.data : strerror(-err));
|
msg.data ? msg.data : strerror(-err));
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
dm_free(msg.data);
|
if (msg.data)
|
||||||
|
dm_free(msg.data);
|
||||||
|
|
||||||
dm_task_destroy(dmt);
|
dm_task_destroy(dmt);
|
||||||
|
|
||||||
@@ -645,22 +605,25 @@ int dm_event_unregister_handler(const struct dm_event_handler *dmevh)
|
|||||||
int ret = 1, err;
|
int ret = 1, err;
|
||||||
const char *uuid;
|
const char *uuid;
|
||||||
struct dm_task *dmt;
|
struct dm_task *dmt;
|
||||||
struct dm_event_daemon_message msg = { 0 };
|
struct dm_event_daemon_message msg = { 0, 0, NULL };
|
||||||
|
|
||||||
if (!(dmt = _get_device_info(dmevh)))
|
if (!(dmt = _get_device_info(dmevh))) {
|
||||||
return_0;
|
stack;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
uuid = dm_task_get_uuid(dmt);
|
uuid = dm_task_get_uuid(dmt);
|
||||||
|
|
||||||
if ((err = _do_event(DM_EVENT_CMD_UNREGISTER_FOR_EVENT, dmevh->dmeventd_path, &msg,
|
if ((err = _do_event(DM_EVENT_CMD_UNREGISTER_FOR_EVENT, &msg,
|
||||||
dmevh->dso, uuid, dmevh->mask, dmevh->timeout)) < 0) {
|
dmevh->dso, uuid, dmevh->mask, dmevh->timeout)) < 0) {
|
||||||
log_error("%s: event deregistration failed: %s.",
|
log_error("%s: event deregistration failed: %s",
|
||||||
dm_task_get_name(dmt),
|
dm_task_get_name(dmt),
|
||||||
msg.data ? msg.data : strerror(-err));
|
msg.data ? msg.data : strerror(-err));
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
dm_free(msg.data);
|
if (msg.data)
|
||||||
|
dm_free(msg.data);
|
||||||
|
|
||||||
dm_task_destroy(dmt);
|
dm_task_destroy(dmt);
|
||||||
|
|
||||||
@@ -689,18 +652,20 @@ static char *_fetch_string(char **src, const int delimiter)
|
|||||||
static int _parse_message(struct dm_event_daemon_message *msg, char **dso_name,
|
static int _parse_message(struct dm_event_daemon_message *msg, char **dso_name,
|
||||||
char **uuid, enum dm_event_mask *evmask)
|
char **uuid, enum dm_event_mask *evmask)
|
||||||
{
|
{
|
||||||
char *id;
|
char *id = NULL;
|
||||||
char *p = msg->data;
|
char *p = msg->data;
|
||||||
|
|
||||||
if ((id = _fetch_string(&p, ' ')) &&
|
if ((id = _fetch_string(&p, ' ')) &&
|
||||||
(*dso_name = _fetch_string(&p, ' ')) &&
|
(*dso_name = _fetch_string(&p, ' ')) &&
|
||||||
(*uuid = _fetch_string(&p, ' '))) {
|
(*uuid = _fetch_string(&p, ' '))) {
|
||||||
*evmask = atoi(p);
|
*evmask = atoi(p);
|
||||||
|
|
||||||
dm_free(id);
|
dm_free(id);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
dm_free(id);
|
if (id)
|
||||||
|
dm_free(id);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -714,44 +679,37 @@ int dm_event_get_registered_device(struct dm_event_handler *dmevh, int next)
|
|||||||
char *reply_dso = NULL, *reply_uuid = NULL;
|
char *reply_dso = NULL, *reply_uuid = NULL;
|
||||||
enum dm_event_mask reply_mask = 0;
|
enum dm_event_mask reply_mask = 0;
|
||||||
struct dm_task *dmt = NULL;
|
struct dm_task *dmt = NULL;
|
||||||
struct dm_event_daemon_message msg = { 0 };
|
struct dm_event_daemon_message msg = { 0, 0, NULL };
|
||||||
struct dm_info info;
|
|
||||||
|
|
||||||
if (!(dmt = _get_device_info(dmevh))) {
|
if (!(dmt = _get_device_info(dmevh))) {
|
||||||
log_debug("Device does not exists (uuid=%s, name=%s, %d:%d).",
|
stack;
|
||||||
dmevh->uuid, dmevh->dev_name,
|
return 0;
|
||||||
dmevh->major, dmevh->minor);
|
|
||||||
ret = -ENODEV;
|
|
||||||
goto fail;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uuid = dm_task_get_uuid(dmt);
|
uuid = dm_task_get_uuid(dmt);
|
||||||
|
|
||||||
if (_do_event(next ? DM_EVENT_CMD_GET_NEXT_REGISTERED_DEVICE :
|
if (!(ret = _do_event(next ? DM_EVENT_CMD_GET_NEXT_REGISTERED_DEVICE :
|
||||||
DM_EVENT_CMD_GET_REGISTERED_DEVICE, dmevh->dmeventd_path,
|
DM_EVENT_CMD_GET_REGISTERED_DEVICE,
|
||||||
&msg, dmevh->dso, uuid, dmevh->mask, 0)) {
|
&msg, dmevh->dso, uuid, dmevh->mask, 0))) {
|
||||||
log_debug("%s: device not registered.", dm_task_get_name(dmt));
|
/* FIXME this will probably horribly break if we get
|
||||||
|
ill-formatted reply */
|
||||||
|
ret = _parse_message(&msg, &reply_dso, &reply_uuid, &reply_mask);
|
||||||
|
} else {
|
||||||
ret = -ENOENT;
|
ret = -ENOENT;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME this will probably horribly break if we get
|
|
||||||
ill-formatted reply */
|
|
||||||
ret = _parse_message(&msg, &reply_dso, &reply_uuid, &reply_mask);
|
|
||||||
|
|
||||||
dm_task_destroy(dmt);
|
dm_task_destroy(dmt);
|
||||||
dmt = NULL;
|
dmt = NULL;
|
||||||
|
|
||||||
dm_free(msg.data);
|
if (msg.data) {
|
||||||
msg.data = NULL;
|
dm_free(msg.data);
|
||||||
|
msg.data = NULL;
|
||||||
_dm_event_handler_clear_dev_info(dmevh);
|
|
||||||
if (!reply_uuid) {
|
|
||||||
ret = -ENXIO; /* dmeventd probably gave us bogus uuid back */
|
|
||||||
goto fail;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(dmevh->uuid = dm_strdup(reply_uuid))) {
|
_dm_event_handler_clear_dev_info(dmevh);
|
||||||
|
dmevh->uuid = dm_strdup(reply_uuid);
|
||||||
|
if (!dmevh->uuid) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
@@ -764,17 +722,23 @@ int dm_event_get_registered_device(struct dm_event_handler *dmevh, int next)
|
|||||||
dm_event_handler_set_dso(dmevh, reply_dso);
|
dm_event_handler_set_dso(dmevh, reply_dso);
|
||||||
dm_event_handler_set_event_mask(dmevh, reply_mask);
|
dm_event_handler_set_event_mask(dmevh, reply_mask);
|
||||||
|
|
||||||
dm_free(reply_dso);
|
if (reply_dso) {
|
||||||
reply_dso = NULL;
|
dm_free(reply_dso);
|
||||||
|
reply_dso = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
dm_free(reply_uuid);
|
if (reply_uuid) {
|
||||||
reply_uuid = NULL;
|
dm_free(reply_uuid);
|
||||||
|
reply_uuid = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(dmevh->dev_name = dm_strdup(dm_task_get_name(dmt)))) {
|
dmevh->dev_name = dm_strdup(dm_task_get_name(dmt));
|
||||||
|
if (!dmevh->dev_name) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct dm_info info;
|
||||||
if (!dm_task_get_info(dmt, &info)) {
|
if (!dm_task_get_info(dmt, &info)) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto fail;
|
goto fail;
|
||||||
@@ -788,118 +752,18 @@ int dm_event_get_registered_device(struct dm_event_handler *dmevh, int next)
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
dm_free(msg.data);
|
if (msg.data)
|
||||||
dm_free(reply_dso);
|
dm_free(msg.data);
|
||||||
dm_free(reply_uuid);
|
if (reply_dso)
|
||||||
|
dm_free(reply_dso);
|
||||||
|
if (reply_uuid)
|
||||||
|
dm_free(reply_uuid);
|
||||||
_dm_event_handler_clear_dev_info(dmevh);
|
_dm_event_handler_clear_dev_info(dmevh);
|
||||||
if (dmt)
|
if (dmt)
|
||||||
dm_task_destroy(dmt);
|
dm_task_destroy(dmt);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* You can (and have to) call this at the stage of the protocol where
|
|
||||||
* daemon_talk(fifos, &msg, DM_EVENT_CMD_HELLO, NULL, NULL, 0, 0)
|
|
||||||
*
|
|
||||||
* would be normally sent. This call will parse the version reply from
|
|
||||||
* dmeventd, in addition to above call. It is not safe to call this at any
|
|
||||||
* other place in the protocol.
|
|
||||||
*
|
|
||||||
* This is an internal function, not exposed in the public API.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int dm_event_get_version(struct dm_event_fifos *fifos, int *version) {
|
|
||||||
char *p;
|
|
||||||
struct dm_event_daemon_message msg = { 0 };
|
|
||||||
|
|
||||||
if (daemon_talk(fifos, &msg, DM_EVENT_CMD_HELLO, NULL, NULL, 0, 0))
|
|
||||||
return 0;
|
|
||||||
p = msg.data;
|
|
||||||
*version = 0;
|
|
||||||
|
|
||||||
if (!p || !(p = strchr(p, ' '))) /* Message ID */
|
|
||||||
return 0;
|
|
||||||
if (!(p = strchr(p + 1, ' '))) /* HELLO */
|
|
||||||
return 0;
|
|
||||||
if ((p = strchr(p + 1, ' '))) /* HELLO, once more */
|
|
||||||
*version = atoi(p);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dm_event_log_set(int debug_level, int use_syslog)
|
|
||||||
{
|
|
||||||
_debug_level = debug_level;
|
|
||||||
_use_syslog = use_syslog;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dm_event_log(const char *subsys, int level, const char *file,
|
|
||||||
int line, int dm_errno_or_class,
|
|
||||||
const char *format, va_list ap)
|
|
||||||
{
|
|
||||||
static pthread_mutex_t _log_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
||||||
static time_t start = 0;
|
|
||||||
const char *indent = "";
|
|
||||||
FILE *stream = stdout;
|
|
||||||
int prio = -1;
|
|
||||||
time_t now;
|
|
||||||
|
|
||||||
switch (level & ~(_LOG_STDERR | _LOG_ONCE)) {
|
|
||||||
case _LOG_DEBUG:
|
|
||||||
if (_debug_level < 3)
|
|
||||||
return;
|
|
||||||
prio = LOG_DEBUG;
|
|
||||||
indent = " ";
|
|
||||||
break;
|
|
||||||
case _LOG_INFO:
|
|
||||||
if (_debug_level < 2)
|
|
||||||
return;
|
|
||||||
prio = LOG_INFO;
|
|
||||||
indent = " ";
|
|
||||||
break;
|
|
||||||
case _LOG_NOTICE:
|
|
||||||
if (_debug_level < 1)
|
|
||||||
return;
|
|
||||||
prio = LOG_NOTICE;
|
|
||||||
indent = " ";
|
|
||||||
break;
|
|
||||||
case _LOG_WARN:
|
|
||||||
prio = LOG_WARNING;
|
|
||||||
break;
|
|
||||||
case _LOG_ERR:
|
|
||||||
prio = LOG_ERR;
|
|
||||||
stream = stderr;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
prio = LOG_CRIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Serialize to keep lines readable */
|
|
||||||
pthread_mutex_lock(&_log_mutex);
|
|
||||||
|
|
||||||
if (_use_syslog) {
|
|
||||||
vsyslog(prio, format, ap);
|
|
||||||
} else {
|
|
||||||
now = time(NULL);
|
|
||||||
if (!start)
|
|
||||||
start = now;
|
|
||||||
now -= start;
|
|
||||||
fprintf(stream, "[%2d:%02d] %8x:%-6s%s",
|
|
||||||
(int)now / 60, (int)now % 60,
|
|
||||||
// TODO: Maybe use shorter ID
|
|
||||||
// ((int)(pthread_self()) >> 6) & 0xffff,
|
|
||||||
(int)pthread_self(), subsys,
|
|
||||||
(_debug_level > 3) ? "" : indent);
|
|
||||||
if (_debug_level > 3)
|
|
||||||
fprintf(stream, "%28s:%4d %s", file, line, indent);
|
|
||||||
vfprintf(stream, _(format), ap);
|
|
||||||
fputc('\n', stream);
|
|
||||||
fflush(stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&_log_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0 /* left out for now */
|
#if 0 /* left out for now */
|
||||||
|
|
||||||
static char *_skip_string(char *src, const int delimiter)
|
static char *_skip_string(char *src, const int delimiter)
|
||||||
@@ -912,7 +776,7 @@ static char *_skip_string(char *src, const int delimiter)
|
|||||||
|
|
||||||
int dm_event_set_timeout(const char *device_path, uint32_t timeout)
|
int dm_event_set_timeout(const char *device_path, uint32_t timeout)
|
||||||
{
|
{
|
||||||
struct dm_event_daemon_message msg = { 0 };
|
struct dm_event_daemon_message msg = { 0, 0, NULL };
|
||||||
|
|
||||||
if (!device_exists(device_path))
|
if (!device_exists(device_path))
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
@@ -924,24 +788,22 @@ int dm_event_set_timeout(const char *device_path, uint32_t timeout)
|
|||||||
int dm_event_get_timeout(const char *device_path, uint32_t *timeout)
|
int dm_event_get_timeout(const char *device_path, uint32_t *timeout)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct dm_event_daemon_message msg = { 0 };
|
struct dm_event_daemon_message msg = { 0, 0, NULL };
|
||||||
|
|
||||||
if (!device_exists(device_path))
|
if (!device_exists(device_path))
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
if (!(ret = _do_event(DM_EVENT_CMD_GET_TIMEOUT, &msg, NULL, device_path,
|
if (!(ret = _do_event(DM_EVENT_CMD_GET_TIMEOUT, &msg, NULL, device_path,
|
||||||
0, 0))) {
|
0, 0))) {
|
||||||
char *p = _skip_string(msg.data, ' ');
|
char *p = _skip_string(msg.data, ' ');
|
||||||
if (!p) {
|
if (!p) {
|
||||||
log_error("Malformed reply from dmeventd '%s'.",
|
log_error("malformed reply from dmeventd '%s'\n",
|
||||||
msg.data);
|
msg.data);
|
||||||
dm_free(msg.data);
|
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
*timeout = atoi(p);
|
*timeout = atoi(p);
|
||||||
}
|
}
|
||||||
dm_free(msg.data);
|
if (msg.data)
|
||||||
|
dm_free(msg.data);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2015 Red Hat, Inc. All rights reserved.
|
* Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* This file is part of the device-mapper userspace tools.
|
* This file is part of the device-mapper userspace tools.
|
||||||
*
|
*
|
||||||
@@ -46,9 +46,7 @@ enum dm_event_mask {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#define DM_EVENT_ALL_ERRORS DM_EVENT_ERROR_MASK
|
#define DM_EVENT_ALL_ERRORS DM_EVENT_ERROR_MASK
|
||||||
#define DM_EVENT_PROTOCOL_VERSION 2
|
|
||||||
|
|
||||||
struct dm_task;
|
|
||||||
struct dm_event_handler;
|
struct dm_event_handler;
|
||||||
|
|
||||||
struct dm_event_handler *dm_event_handler_create(void);
|
struct dm_event_handler *dm_event_handler_create(void);
|
||||||
@@ -57,17 +55,12 @@ void dm_event_handler_destroy(struct dm_event_handler *dmevh);
|
|||||||
/*
|
/*
|
||||||
* Path of shared library to handle events.
|
* Path of shared library to handle events.
|
||||||
*
|
*
|
||||||
* All of dmeventd, dso, device_name and uuid strings are duplicated so
|
* All of dso, device_name and uuid strings are duplicated, you do not
|
||||||
* you do not need to keep the pointers valid after the call succeeds.
|
* need to keep the pointers valid after the call succeeds. Thes may
|
||||||
* They may return -ENOMEM though.
|
* return -ENOMEM though.
|
||||||
*/
|
*/
|
||||||
int dm_event_handler_set_dso(struct dm_event_handler *dmevh, const char *path);
|
int dm_event_handler_set_dso(struct dm_event_handler *dmevh, const char *path);
|
||||||
|
|
||||||
/*
|
|
||||||
* Path of dmeventd binary.
|
|
||||||
*/
|
|
||||||
int dm_event_handler_set_dmeventd_path(struct dm_event_handler *dmevh, const char *dmeventd_path);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Identify the device to monitor by exactly one of device_name, uuid or
|
* Identify the device to monitor by exactly one of device_name, uuid or
|
||||||
* device number. String arguments are duplicated, see above.
|
* device number. String arguments are duplicated, see above.
|
||||||
@@ -83,7 +76,6 @@ void dm_event_handler_set_timeout(struct dm_event_handler *dmevh, int timeout);
|
|||||||
/*
|
/*
|
||||||
* Specify mask for events to monitor.
|
* Specify mask for events to monitor.
|
||||||
*/
|
*/
|
||||||
// FIXME misuse of bitmask as enum
|
|
||||||
void dm_event_handler_set_event_mask(struct dm_event_handler *dmevh,
|
void dm_event_handler_set_event_mask(struct dm_event_handler *dmevh,
|
||||||
enum dm_event_mask evmask);
|
enum dm_event_mask evmask);
|
||||||
|
|
||||||
@@ -93,7 +85,6 @@ const char *dm_event_handler_get_uuid(const struct dm_event_handler *dmevh);
|
|||||||
int dm_event_handler_get_major(const struct dm_event_handler *dmevh);
|
int dm_event_handler_get_major(const struct dm_event_handler *dmevh);
|
||||||
int dm_event_handler_get_minor(const struct dm_event_handler *dmevh);
|
int dm_event_handler_get_minor(const struct dm_event_handler *dmevh);
|
||||||
int dm_event_handler_get_timeout(const struct dm_event_handler *dmevh);
|
int dm_event_handler_get_timeout(const struct dm_event_handler *dmevh);
|
||||||
// FIXME misuse of bitmask as enum
|
|
||||||
enum dm_event_mask dm_event_handler_get_event_mask(const struct dm_event_handler *dmevh);
|
enum dm_event_mask dm_event_handler_get_event_mask(const struct dm_event_handler *dmevh);
|
||||||
|
|
||||||
/* FIXME Review interface (what about this next thing?) */
|
/* FIXME Review interface (what about this next thing?) */
|
||||||
@@ -105,28 +96,8 @@ int dm_event_get_registered_device(struct dm_event_handler *dmevh, int next);
|
|||||||
int dm_event_register_handler(const struct dm_event_handler *dmevh);
|
int dm_event_register_handler(const struct dm_event_handler *dmevh);
|
||||||
int dm_event_unregister_handler(const struct dm_event_handler *dmevh);
|
int dm_event_unregister_handler(const struct dm_event_handler *dmevh);
|
||||||
|
|
||||||
/* Set debug level for logging, and whether to log on stdout/stderr or syslog */
|
|
||||||
void dm_event_log_set(int debug_level, int use_syslog);
|
|
||||||
|
|
||||||
/* Log messages acroding to current debug level */
|
|
||||||
__attribute__((format(printf, 6, 0)))
|
|
||||||
void dm_event_log(const char *subsys, int level, const char *file,
|
|
||||||
int line, int dm_errno_or_class,
|
|
||||||
const char *format, va_list ap);
|
|
||||||
/* Macro to route print_log do dm_event_log() */
|
|
||||||
#define DM_EVENT_LOG_FN(subsys) \
|
|
||||||
void print_log(int level, const char *file, int line, int dm_errno_or_class,\
|
|
||||||
const char *format, ...)\
|
|
||||||
{\
|
|
||||||
va_list ap;\
|
|
||||||
va_start(ap, format);\
|
|
||||||
dm_event_log(subsys, level, file, line, dm_errno_or_class, format, ap);\
|
|
||||||
va_end(ap);\
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Prototypes for DSO interface, see dmeventd.c, struct dso_data for
|
/* Prototypes for DSO interface, see dmeventd.c, struct dso_data for
|
||||||
detailed descriptions. */
|
detailed descriptions. */
|
||||||
// FIXME misuse of bitmask as enum
|
|
||||||
void process_event(struct dm_task *dmt, enum dm_event_mask evmask, void **user);
|
void process_event(struct dm_task *dmt, enum dm_event_mask evmask, void **user);
|
||||||
int register_device(const char *device_name, const char *uuid, int major, int minor, void **user);
|
int register_device(const char *device_name, const char *uuid, int major, int minor, void **user);
|
||||||
int unregister_device(const char *device_name, const char *uuid, int major,
|
int unregister_device(const char *device_name, const char *uuid, int major,
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ includedir=@includedir@
|
|||||||
|
|
||||||
Name: devmapper-event
|
Name: devmapper-event
|
||||||
Description: device-mapper event library
|
Description: device-mapper event library
|
||||||
Version: @DM_LIB_PATCHLEVEL@
|
Version: @DM_LIB_VERSION@
|
||||||
|
Requires: devmapper
|
||||||
Cflags: -I${includedir}
|
Cflags: -I${includedir}
|
||||||
Libs: -L${libdir} -ldevmapper-event
|
Libs: -L${libdir} -ldevmapper-event
|
||||||
Requires.private: devmapper
|
Libs.private: -lpthread -ldl
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#
|
#
|
||||||
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||||
# Copyright (C) 2004-2005, 2011 Red Hat, Inc. All rights reserved.
|
# Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
|
||||||
#
|
#
|
||||||
# This file is part of LVM2.
|
# This file is part of LVM2.
|
||||||
#
|
#
|
||||||
@@ -14,33 +14,9 @@
|
|||||||
|
|
||||||
srcdir = @srcdir@
|
srcdir = @srcdir@
|
||||||
top_srcdir = @top_srcdir@
|
top_srcdir = @top_srcdir@
|
||||||
top_builddir = @top_builddir@
|
VPATH = @srcdir@
|
||||||
|
|
||||||
SUBDIRS += lvm2
|
SUBDIRS += mirror snapshot
|
||||||
|
|
||||||
ifneq ("@MIRRORS@", "none")
|
include $(top_srcdir)/make.tmpl
|
||||||
SUBDIRS += mirror
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifneq ("@SNAPSHOTS@", "none")
|
|
||||||
SUBDIRS += snapshot
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifneq ("@RAID@", "none")
|
|
||||||
SUBDIRS += raid
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifneq ("@THIN@", "none")
|
|
||||||
SUBDIRS += thin
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(MAKECMDGOALS),distclean)
|
|
||||||
SUBDIRS = lvm2 mirror snapshot raid thin
|
|
||||||
endif
|
|
||||||
|
|
||||||
include $(top_builddir)/make.tmpl
|
|
||||||
|
|
||||||
snapshot: lvm2
|
|
||||||
mirror: lvm2
|
|
||||||
raid: lvm2
|
|
||||||
thin: lvm2
|
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
dmeventd_lvm2_init
|
|
||||||
dmeventd_lvm2_exit
|
|
||||||
dmeventd_lvm2_lock
|
|
||||||
dmeventd_lvm2_unlock
|
|
||||||
dmeventd_lvm2_pool
|
|
||||||
dmeventd_lvm2_run
|
|
||||||
dmeventd_lvm2_command
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
#
|
|
||||||
# Copyright (C) 2010-2014 Red Hat, Inc. All rights reserved.
|
|
||||||
#
|
|
||||||
# This file is part of LVM2.
|
|
||||||
#
|
|
||||||
# This copyrighted material is made available to anyone wishing to use,
|
|
||||||
# modify, copy, or redistribute it subject to the terms and conditions
|
|
||||||
# of the GNU General Public License v.2.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation,
|
|
||||||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
srcdir = @srcdir@
|
|
||||||
top_srcdir = @top_srcdir@
|
|
||||||
top_builddir = @top_builddir@
|
|
||||||
|
|
||||||
CLDFLAGS += -L$(top_builddir)/tools
|
|
||||||
|
|
||||||
SOURCES = dmeventd_lvm.c
|
|
||||||
|
|
||||||
LIB_SHARED = libdevmapper-event-lvm2.$(LIB_SUFFIX)
|
|
||||||
LIB_VERSION = $(LIB_VERSION_LVM)
|
|
||||||
|
|
||||||
include $(top_builddir)/make.tmpl
|
|
||||||
|
|
||||||
LIBS += @LVM2CMD_LIB@ -ldevmapper $(PTHREAD_LIBS)
|
|
||||||
|
|
||||||
install_lvm2: install_lib_shared
|
|
||||||
|
|
||||||
install: install_lvm2
|
|
||||||
@@ -1,148 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2010-2015 Red Hat, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* This file is part of LVM2.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use,
|
|
||||||
* modify, copy, or redistribute it subject to the terms and conditions
|
|
||||||
* of the GNU Lesser General Public License v.2.1.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this program; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "lib.h"
|
|
||||||
#include "dmeventd_lvm.h"
|
|
||||||
#include "libdevmapper-event.h"
|
|
||||||
#include "lvm2cmd.h"
|
|
||||||
|
|
||||||
#include <pthread.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* register_device() is called first and performs initialisation.
|
|
||||||
* Only one device may be registered or unregistered at a time.
|
|
||||||
*/
|
|
||||||
static pthread_mutex_t _register_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Number of active registrations.
|
|
||||||
*/
|
|
||||||
static int _register_count = 0;
|
|
||||||
static struct dm_pool *_mem_pool = NULL;
|
|
||||||
static void *_lvm_handle = NULL;
|
|
||||||
|
|
||||||
DM_EVENT_LOG_FN("lvm")
|
|
||||||
|
|
||||||
static void _lvm2_print_log(int level, const char *file, int line,
|
|
||||||
int dm_errno_or_class, const char *msg)
|
|
||||||
{
|
|
||||||
print_log(level, file, line, dm_errno_or_class, "%s", msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Currently only one event can be processed at a time.
|
|
||||||
*/
|
|
||||||
static pthread_mutex_t _event_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
||||||
|
|
||||||
void dmeventd_lvm2_lock(void)
|
|
||||||
{
|
|
||||||
pthread_mutex_lock(&_event_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
void dmeventd_lvm2_unlock(void)
|
|
||||||
{
|
|
||||||
pthread_mutex_unlock(&_event_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
int dmeventd_lvm2_init(void)
|
|
||||||
{
|
|
||||||
int r = 0;
|
|
||||||
|
|
||||||
pthread_mutex_lock(&_register_mutex);
|
|
||||||
|
|
||||||
if (!_lvm_handle) {
|
|
||||||
lvm2_log_fn(_lvm2_print_log);
|
|
||||||
|
|
||||||
if (!(_lvm_handle = lvm2_init()))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Need some space for allocations. 1024 should be more
|
|
||||||
* than enough for what we need (device mapper name splitting)
|
|
||||||
*/
|
|
||||||
if (!_mem_pool && !(_mem_pool = dm_pool_create("mirror_dso", 1024))) {
|
|
||||||
lvm2_exit(_lvm_handle);
|
|
||||||
_lvm_handle = NULL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
lvm2_disable_dmeventd_monitoring(_lvm_handle);
|
|
||||||
/* FIXME Temporary: move to dmeventd core */
|
|
||||||
lvm2_run(_lvm_handle, "_memlock_inc");
|
|
||||||
log_debug("lvm plugin initilized.");
|
|
||||||
}
|
|
||||||
|
|
||||||
_register_count++;
|
|
||||||
r = 1;
|
|
||||||
|
|
||||||
out:
|
|
||||||
pthread_mutex_unlock(&_register_mutex);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dmeventd_lvm2_exit(void)
|
|
||||||
{
|
|
||||||
pthread_mutex_lock(&_register_mutex);
|
|
||||||
|
|
||||||
if (!--_register_count) {
|
|
||||||
log_debug("lvm plugin shuting down.");
|
|
||||||
lvm2_run(_lvm_handle, "_memlock_dec");
|
|
||||||
dm_pool_destroy(_mem_pool);
|
|
||||||
_mem_pool = NULL;
|
|
||||||
lvm2_exit(_lvm_handle);
|
|
||||||
_lvm_handle = NULL;
|
|
||||||
log_debug("lvm plugin exited.");
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&_register_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct dm_pool *dmeventd_lvm2_pool(void)
|
|
||||||
{
|
|
||||||
return _mem_pool;
|
|
||||||
}
|
|
||||||
|
|
||||||
int dmeventd_lvm2_run(const char *cmdline)
|
|
||||||
{
|
|
||||||
return (lvm2_run(_lvm_handle, cmdline) == LVM2_COMMAND_SUCCEEDED);
|
|
||||||
}
|
|
||||||
|
|
||||||
int dmeventd_lvm2_command(struct dm_pool *mem, char *buffer, size_t size,
|
|
||||||
const char *cmd, const char *device)
|
|
||||||
{
|
|
||||||
char *vg = NULL, *lv = NULL, *layer;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
if (!dm_split_lvm_name(mem, device, &vg, &lv, &layer)) {
|
|
||||||
log_error("Unable to determine VG name from %s.",
|
|
||||||
device);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* strip off the mirror component designations */
|
|
||||||
if ((layer = strstr(lv, "_mimagetmp")) ||
|
|
||||||
(layer = strstr(lv, "_mlog")))
|
|
||||||
*layer = '\0';
|
|
||||||
|
|
||||||
r = dm_snprintf(buffer, size, "%s %s/%s", cmd, vg, lv);
|
|
||||||
|
|
||||||
dm_pool_free(mem, vg);
|
|
||||||
|
|
||||||
if (r < 0) {
|
|
||||||
log_error("Unable to form LVM command. (too long).");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2010-2015 Red Hat, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* This file is part of LVM2.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use,
|
|
||||||
* modify, copy, or redistribute it subject to the terms and conditions
|
|
||||||
* of the GNU Lesser General Public License v.2.1.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this program; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Wrappers around liblvm2cmd functions for dmeventd plug-ins.
|
|
||||||
*
|
|
||||||
* liblvm2cmd is not thread-safe so the locking in this library helps dmeventd
|
|
||||||
* threads to co-operate in sharing a single instance.
|
|
||||||
*
|
|
||||||
* FIXME Either support this properly as a generic liblvm2cmd wrapper or make
|
|
||||||
* liblvm2cmd thread-safe so this can go away.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _DMEVENTD_LVMWRAP_H
|
|
||||||
#define _DMEVENTD_LVMWRAP_H
|
|
||||||
|
|
||||||
struct dm_pool;
|
|
||||||
|
|
||||||
int dmeventd_lvm2_init(void);
|
|
||||||
void dmeventd_lvm2_exit(void);
|
|
||||||
int dmeventd_lvm2_run(const char *cmdline);
|
|
||||||
|
|
||||||
void dmeventd_lvm2_lock(void);
|
|
||||||
void dmeventd_lvm2_unlock(void);
|
|
||||||
|
|
||||||
struct dm_pool *dmeventd_lvm2_pool(void);
|
|
||||||
|
|
||||||
int dmeventd_lvm2_command(struct dm_pool *mem, char *buffer, size_t size,
|
|
||||||
const char *cmd, const char *device);
|
|
||||||
|
|
||||||
#define dmeventd_lvm2_run_with_lock(cmdline) \
|
|
||||||
({\
|
|
||||||
int rc;\
|
|
||||||
dmeventd_lvm2_lock();\
|
|
||||||
rc = dmeventd_lvm2_run(cmdline);\
|
|
||||||
dmeventd_lvm2_unlock();\
|
|
||||||
rc;\
|
|
||||||
})
|
|
||||||
|
|
||||||
#define dmeventd_lvm2_init_with_pool(name, st) \
|
|
||||||
({\
|
|
||||||
struct dm_pool *mem;\
|
|
||||||
st = NULL;\
|
|
||||||
if (dmeventd_lvm2_init()) {\
|
|
||||||
if ((mem = dm_pool_create(name, 2048)) &&\
|
|
||||||
(st = dm_pool_zalloc(mem, sizeof(*st))))\
|
|
||||||
st->mem = mem;\
|
|
||||||
else {\
|
|
||||||
if (mem)\
|
|
||||||
dm_pool_destroy(mem);\
|
|
||||||
dmeventd_lvm2_exit();\
|
|
||||||
}\
|
|
||||||
}\
|
|
||||||
st;\
|
|
||||||
})
|
|
||||||
|
|
||||||
#define dmeventd_lvm2_exit_with_pool(pool) \
|
|
||||||
do {\
|
|
||||||
dm_pool_destroy(pool->mem);\
|
|
||||||
dmeventd_lvm2_exit();\
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
#endif /* _DMEVENTD_LVMWRAP_H */
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#
|
#
|
||||||
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||||
# Copyright (C) 2004-2005, 2008-2014 Red Hat, Inc. All rights reserved.
|
# Copyright (C) 2004-2005, 2008 Red Hat, Inc. All rights reserved.
|
||||||
#
|
#
|
||||||
# This file is part of LVM2.
|
# This file is part of LVM2.
|
||||||
#
|
#
|
||||||
@@ -14,24 +14,22 @@
|
|||||||
|
|
||||||
srcdir = @srcdir@
|
srcdir = @srcdir@
|
||||||
top_srcdir = @top_srcdir@
|
top_srcdir = @top_srcdir@
|
||||||
top_builddir = @top_builddir@
|
VPATH = @srcdir@
|
||||||
|
|
||||||
INCLUDES += -I$(top_srcdir)/daemons/dmeventd/plugins/lvm2
|
INCLUDES += -I${top_srcdir}/tools
|
||||||
CLDFLAGS += -L$(top_builddir)/daemons/dmeventd/plugins/lvm2
|
CLDFLAGS += -L${top_srcdir}/tools -ldevmapper @LVM2CMD_LIB@
|
||||||
|
|
||||||
SOURCES = dmeventd_mirror.c
|
SOURCES = dmeventd_mirror.c
|
||||||
|
|
||||||
LIB_NAME = libdevmapper-event-lvm2mirror
|
ifeq ("@LIB_SUFFIX@","dylib")
|
||||||
LIB_SHARED = $(LIB_NAME).$(LIB_SUFFIX)
|
LIB_SHARED = libdevmapper-event-lvm2mirror.dylib
|
||||||
LIB_VERSION = $(LIB_VERSION_LVM)
|
else
|
||||||
|
LIB_SHARED = libdevmapper-event-lvm2mirror.so
|
||||||
|
endif
|
||||||
|
|
||||||
CFLOW_LIST = $(SOURCES)
|
include $(top_srcdir)/make.tmpl
|
||||||
CFLOW_LIST_TARGET = $(LIB_NAME).cflow
|
|
||||||
|
|
||||||
include $(top_builddir)/make.tmpl
|
install: libdevmapper-event-lvm2mirror.$(LIB_SUFFIX)
|
||||||
|
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \
|
||||||
LIBS += -ldevmapper-event-lvm2 -ldevmapper
|
$(libdir)/$<.$(LIB_VERSION)
|
||||||
|
$(LN_S) -f $<.$(LIB_VERSION) $(libdir)/$<
|
||||||
install_lvm2: install_dm_plugin
|
|
||||||
|
|
||||||
install: install_lvm2
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2015 Red Hat, Inc. All rights reserved.
|
* Copyright (C) 2005 Red Hat, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* This file is part of LVM2.
|
* This file is part of LVM2.
|
||||||
*
|
*
|
||||||
@@ -12,51 +12,43 @@
|
|||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "lib.h"
|
#include "lvm2cmd.h"
|
||||||
#include "libdevmapper-event.h"
|
|
||||||
#include "dmeventd_lvm.h"
|
|
||||||
#include "defaults.h"
|
|
||||||
|
|
||||||
/* FIXME Reformat to 80 char lines. */
|
#include <libdevmapper.h>
|
||||||
|
#include <libdevmapper-event.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <syslog.h> /* FIXME Replace syslog with multilog */
|
||||||
|
/* FIXME Missing openlog? */
|
||||||
|
|
||||||
#define ME_IGNORE 0
|
#define ME_IGNORE 0
|
||||||
#define ME_INSYNC 1
|
#define ME_INSYNC 1
|
||||||
#define ME_FAILURE 2
|
#define ME_FAILURE 2
|
||||||
|
|
||||||
struct dso_state {
|
/*
|
||||||
struct dm_pool *mem;
|
* register_device() is called first and performs initialisation.
|
||||||
char cmd_lvscan[512];
|
* Only one device may be registered or unregistered at a time.
|
||||||
char cmd_lvconvert[512];
|
*/
|
||||||
};
|
static pthread_mutex_t _register_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
DM_EVENT_LOG_FN("mirr")
|
/*
|
||||||
|
* Number of active registrations.
|
||||||
|
*/
|
||||||
|
static int _register_count = 0;
|
||||||
|
|
||||||
static int _process_status_code(const char status_code, const char *dev_name,
|
static struct dm_pool *_mem_pool = NULL;
|
||||||
const char *dev_type, int r)
|
static void *_lvm_handle = NULL;
|
||||||
{
|
|
||||||
/*
|
|
||||||
* A => Alive - No failures
|
|
||||||
* D => Dead - A write failure occurred leaving mirror out-of-sync
|
|
||||||
* F => Flush failed.
|
|
||||||
* S => Sync - A sychronization failure occurred, mirror out-of-sync
|
|
||||||
* R => Read - A read failure occurred, mirror data unaffected
|
|
||||||
* U => Unclassified failure (bug)
|
|
||||||
*/
|
|
||||||
if (status_code == 'F') {
|
|
||||||
log_error("%s device %s flush failed.", dev_type, dev_name);
|
|
||||||
r = ME_FAILURE;
|
|
||||||
} else if (status_code == 'S')
|
|
||||||
log_error("%s device %s sync failed.", dev_type, dev_name);
|
|
||||||
else if (status_code == 'R')
|
|
||||||
log_error("%s device %s read failed.", dev_type, dev_name);
|
|
||||||
else if (status_code != 'A') {
|
|
||||||
log_error("%s device %s has failed (%c).",
|
|
||||||
dev_type, dev_name, status_code);
|
|
||||||
r = ME_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return r;
|
/*
|
||||||
}
|
* Currently only one event can be processed at a time.
|
||||||
|
*/
|
||||||
|
static pthread_mutex_t _event_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
static int _get_mirror_event(char *params)
|
static int _get_mirror_event(char *params)
|
||||||
{
|
{
|
||||||
@@ -81,8 +73,7 @@ static int _get_mirror_event(char *params)
|
|||||||
if (!dm_split_words(params, 1, 0, &p))
|
if (!dm_split_words(params, 1, 0, &p))
|
||||||
goto out_parse;
|
goto out_parse;
|
||||||
|
|
||||||
if (!(num_devs = atoi(p)) ||
|
if (!(num_devs = atoi(p)))
|
||||||
(num_devs > DEFAULT_MIRROR_MAX_IMAGES) || (num_devs < 0))
|
|
||||||
goto out_parse;
|
goto out_parse;
|
||||||
p += strlen(p) + 1;
|
p += strlen(p) + 1;
|
||||||
|
|
||||||
@@ -91,7 +82,6 @@ static int _get_mirror_event(char *params)
|
|||||||
if (!args || dm_split_words(p, num_devs + 7, 0, args) < num_devs + 5)
|
if (!args || dm_split_words(p, num_devs + 7, 0, args) < num_devs + 5)
|
||||||
goto out_parse;
|
goto out_parse;
|
||||||
|
|
||||||
/* FIXME: Code differs from lib/mirror/mirrored.c */
|
|
||||||
dev_status_str = args[2 + num_devs];
|
dev_status_str = args[2 + num_devs];
|
||||||
log_argc = atoi(args[3 + num_devs]);
|
log_argc = atoi(args[3 + num_devs]);
|
||||||
log_status_str = args[3 + num_devs + log_argc];
|
log_status_str = args[3 + num_devs + log_argc];
|
||||||
@@ -99,14 +89,17 @@ static int _get_mirror_event(char *params)
|
|||||||
|
|
||||||
/* Check for bad mirror devices */
|
/* Check for bad mirror devices */
|
||||||
for (i = 0; i < num_devs; i++)
|
for (i = 0; i < num_devs; i++)
|
||||||
r = _process_status_code(dev_status_str[i], args[i],
|
if (dev_status_str[i] == 'D') {
|
||||||
i ? "Secondary mirror" : "Primary mirror", r);
|
syslog(LOG_ERR, "Mirror device, %s, has failed.\n", args[i]);
|
||||||
|
r = ME_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check for bad disk log device */
|
/* Check for bad disk log device */
|
||||||
if (log_argc > 1)
|
if (log_argc > 1 && log_status_str[0] == 'D') {
|
||||||
r = _process_status_code(log_status_str[0],
|
syslog(LOG_ERR, "Log device, %s, has failed.\n",
|
||||||
args[2 + num_devs + log_argc],
|
args[2 + num_devs + log_argc]);
|
||||||
"Log", r);
|
r = ME_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
if (r == ME_FAILURE)
|
if (r == ME_FAILURE)
|
||||||
goto out;
|
goto out;
|
||||||
@@ -121,54 +114,82 @@ static int _get_mirror_event(char *params)
|
|||||||
goto out_parse;
|
goto out_parse;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
dm_free(args);
|
if (args)
|
||||||
|
dm_free(args);
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
out_parse:
|
out_parse:
|
||||||
dm_free(args);
|
if (args)
|
||||||
log_error("Unable to parse mirror status string.");
|
dm_free(args);
|
||||||
|
syslog(LOG_ERR, "Unable to parse mirror status string.");
|
||||||
return ME_IGNORE;
|
return ME_IGNORE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _remove_failed_devices(const char *cmd_lvscan, const char *cmd_lvconvert)
|
static void _temporary_log_fn(int level, const char *file __attribute((unused)),
|
||||||
|
int line __attribute((unused)),
|
||||||
|
const char *format)
|
||||||
|
{
|
||||||
|
if (!strncmp(format, "WARNING: ", 9) && (level < 5))
|
||||||
|
syslog(LOG_CRIT, "%s", format);
|
||||||
|
else
|
||||||
|
syslog(LOG_DEBUG, "%s", format);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _remove_failed_devices(const char *device)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
#define CMD_SIZE 256 /* FIXME Use system restriction */
|
||||||
|
char cmd_str[CMD_SIZE];
|
||||||
|
char *vg = NULL, *lv = NULL, *layer = NULL;
|
||||||
|
|
||||||
if (!dmeventd_lvm2_run_with_lock(cmd_lvscan))
|
if (strlen(device) > 200) /* FIXME Use real restriction */
|
||||||
log_info("Re-scan of mirrored device failed.");
|
return -ENAMETOOLONG; /* FIXME These return code distinctions are not used so remove them! */
|
||||||
|
|
||||||
/* if repair goes OK, report success even if lvscan has failed */
|
if (!dm_split_lvm_name(_mem_pool, device, &vg, &lv, &layer)) {
|
||||||
r = dmeventd_lvm2_run_with_lock(cmd_lvconvert);
|
syslog(LOG_ERR, "Unable to determine VG name from %s",
|
||||||
|
device);
|
||||||
|
return -ENOMEM; /* FIXME Replace with generic error return - reason for failure has already got logged */
|
||||||
|
}
|
||||||
|
|
||||||
log_info("Repair of mirrored device %s.",
|
/* FIXME Is any sanity-checking required on %s? */
|
||||||
(r) ? "finished successfully" : "failed");
|
if (CMD_SIZE <= snprintf(cmd_str, CMD_SIZE, "vgreduce --config devices{ignore_suspended_devices=1} --removemissing --force %s", vg)) {
|
||||||
|
/* this error should be caught above, but doesn't hurt to check again */
|
||||||
|
syslog(LOG_ERR, "Unable to form LVM command: Device name too long");
|
||||||
|
dm_pool_empty(_mem_pool); /* FIXME: not safe with multiple threads */
|
||||||
|
return -ENAMETOOLONG; /* FIXME Replace with generic error return - reason for failure has already got logged */
|
||||||
|
}
|
||||||
|
|
||||||
return r;
|
r = lvm2_run(_lvm_handle, cmd_str);
|
||||||
|
|
||||||
|
dm_pool_empty(_mem_pool); /* FIXME: not safe with multiple threads */
|
||||||
|
return (r == 1) ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_event(struct dm_task *dmt,
|
void process_event(struct dm_task *dmt,
|
||||||
enum dm_event_mask event __attribute__((unused)),
|
enum dm_event_mask event __attribute((unused)),
|
||||||
void **user)
|
void **unused __attribute((unused)))
|
||||||
{
|
{
|
||||||
struct dso_state *state = *user;
|
|
||||||
void *next = NULL;
|
void *next = NULL;
|
||||||
uint64_t start, length;
|
uint64_t start, length;
|
||||||
char *target_type = NULL;
|
char *target_type = NULL;
|
||||||
char *params;
|
char *params;
|
||||||
const char *device = dm_task_get_name(dmt);
|
const char *device = dm_task_get_name(dmt);
|
||||||
|
|
||||||
|
if (pthread_mutex_trylock(&_event_mutex)) {
|
||||||
|
syslog(LOG_NOTICE, "Another thread is handling an event. Waiting...");
|
||||||
|
pthread_mutex_lock(&_event_mutex);
|
||||||
|
}
|
||||||
do {
|
do {
|
||||||
next = dm_get_next_target(dmt, next, &start, &length,
|
next = dm_get_next_target(dmt, next, &start, &length,
|
||||||
&target_type, ¶ms);
|
&target_type, ¶ms);
|
||||||
|
|
||||||
if (!target_type) {
|
if (!target_type) {
|
||||||
log_info("%s mapping lost.", device);
|
syslog(LOG_INFO, "%s mapping lost.\n", device);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(target_type, "mirror")) {
|
if (strcmp(target_type, "mirror")) {
|
||||||
log_info("%s has unmirrored portion.", device);
|
syslog(LOG_INFO, "%s has unmirrored portion.\n", device);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,75 +199,91 @@ void process_event(struct dm_task *dmt,
|
|||||||
_part_ of the device is in sync
|
_part_ of the device is in sync
|
||||||
Also, this is not an error
|
Also, this is not an error
|
||||||
*/
|
*/
|
||||||
log_notice("%s is now in-sync.", device);
|
syslog(LOG_NOTICE, "%s is now in-sync\n", device);
|
||||||
break;
|
break;
|
||||||
case ME_FAILURE:
|
case ME_FAILURE:
|
||||||
log_error("Device failure in %s.", device);
|
syslog(LOG_ERR, "Device failure in %s\n", device);
|
||||||
if (!_remove_failed_devices(state->cmd_lvscan,
|
if (_remove_failed_devices(device))
|
||||||
state->cmd_lvconvert))
|
|
||||||
/* FIXME Why are all the error return codes unused? Get rid of them? */
|
/* FIXME Why are all the error return codes unused? Get rid of them? */
|
||||||
log_error("Failed to remove faulty devices in %s.",
|
syslog(LOG_ERR, "Failed to remove faulty devices in %s\n",
|
||||||
device);
|
device);
|
||||||
/* Should check before warning user that device is now linear
|
/* Should check before warning user that device is now linear
|
||||||
else
|
else
|
||||||
log_notice("%s is now a linear device.",
|
syslog(LOG_NOTICE, "%s is now a linear device.\n",
|
||||||
device);
|
device);
|
||||||
*/
|
*/
|
||||||
break;
|
break;
|
||||||
case ME_IGNORE:
|
case ME_IGNORE:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* FIXME Provide value then! */
|
/* FIXME Provide value then! */
|
||||||
log_info("Unknown event received.");
|
syslog(LOG_INFO, "Unknown event received.\n");
|
||||||
}
|
}
|
||||||
} while (next);
|
} while (next);
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&_event_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
int register_device(const char *device,
|
int register_device(const char *device,
|
||||||
const char *uuid __attribute__((unused)),
|
const char *uuid __attribute((unused)),
|
||||||
int major __attribute__((unused)),
|
int major __attribute((unused)),
|
||||||
int minor __attribute__((unused)),
|
int minor __attribute((unused)),
|
||||||
void **user)
|
void **unused __attribute((unused)))
|
||||||
{
|
{
|
||||||
struct dso_state *state;
|
int r = 0;
|
||||||
|
|
||||||
if (!dmeventd_lvm2_init_with_pool("mirror_state", state))
|
pthread_mutex_lock(&_register_mutex);
|
||||||
goto_bad;
|
|
||||||
|
|
||||||
if (!dmeventd_lvm2_command(state->mem, state->cmd_lvscan, sizeof(state->cmd_lvscan),
|
syslog(LOG_INFO, "Monitoring mirror device %s for events\n", device);
|
||||||
"lvscan --cache", device)) {
|
|
||||||
dmeventd_lvm2_exit_with_pool(state);
|
/*
|
||||||
goto_bad;
|
* Need some space for allocations. 1024 should be more
|
||||||
|
* than enough for what we need (device mapper name splitting)
|
||||||
|
*/
|
||||||
|
if (!_mem_pool && !(_mem_pool = dm_pool_create("mirror_dso", 1024)))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (!_lvm_handle) {
|
||||||
|
lvm2_log_fn(_temporary_log_fn);
|
||||||
|
if (!(_lvm_handle = lvm2_init())) {
|
||||||
|
dm_pool_destroy(_mem_pool);
|
||||||
|
_mem_pool = NULL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
lvm2_log_level(_lvm_handle, LVM2_LOG_SUPPRESS);
|
||||||
|
/* FIXME Temporary: move to dmeventd core */
|
||||||
|
lvm2_run(_lvm_handle, "_memlock_inc");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dmeventd_lvm2_command(state->mem, state->cmd_lvconvert, sizeof(state->cmd_lvconvert),
|
_register_count++;
|
||||||
"lvconvert --repair --use-policies", device)) {
|
r = 1;
|
||||||
dmeventd_lvm2_exit_with_pool(state);
|
|
||||||
goto_bad;
|
|
||||||
}
|
|
||||||
|
|
||||||
*user = state;
|
out:
|
||||||
|
pthread_mutex_unlock(&_register_mutex);
|
||||||
|
|
||||||
log_info("Monitoring mirror device %s for events.", device);
|
return r;
|
||||||
|
|
||||||
return 1;
|
|
||||||
bad:
|
|
||||||
log_error("Failed to monitor mirror %s.", device);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int unregister_device(const char *device,
|
int unregister_device(const char *device,
|
||||||
const char *uuid __attribute__((unused)),
|
const char *uuid __attribute((unused)),
|
||||||
int major __attribute__((unused)),
|
int major __attribute((unused)),
|
||||||
int minor __attribute__((unused)),
|
int minor __attribute((unused)),
|
||||||
void **user)
|
void **unused __attribute((unused)))
|
||||||
{
|
{
|
||||||
struct dso_state *state = *user;
|
pthread_mutex_lock(&_register_mutex);
|
||||||
|
|
||||||
dmeventd_lvm2_exit_with_pool(state);
|
syslog(LOG_INFO, "No longer monitoring mirror device %s for events\n",
|
||||||
log_info("No longer monitoring mirror device %s for events.",
|
device);
|
||||||
device);
|
|
||||||
|
if (!--_register_count) {
|
||||||
|
dm_pool_destroy(_mem_pool);
|
||||||
|
_mem_pool = NULL;
|
||||||
|
lvm2_run(_lvm_handle, "_memlock_dec");
|
||||||
|
lvm2_exit(_lvm_handle);
|
||||||
|
_lvm_handle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&_register_mutex);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
#
|
|
||||||
# Copyright (C) 2011-2014 Red Hat, Inc. All rights reserved.
|
|
||||||
#
|
|
||||||
# This file is part of LVM2.
|
|
||||||
#
|
|
||||||
# This copyrighted material is made available to anyone wishing to use,
|
|
||||||
# modify, copy, or redistribute it subject to the terms and conditions
|
|
||||||
# of the GNU General Public License v.2.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation,
|
|
||||||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
srcdir = @srcdir@
|
|
||||||
top_srcdir = @top_srcdir@
|
|
||||||
top_builddir = @top_builddir@
|
|
||||||
|
|
||||||
INCLUDES += -I$(top_srcdir)/daemons/dmeventd/plugins/lvm2
|
|
||||||
CLDFLAGS += -L$(top_builddir)/daemons/dmeventd/plugins/lvm2
|
|
||||||
|
|
||||||
SOURCES = dmeventd_raid.c
|
|
||||||
|
|
||||||
LIB_NAME = libdevmapper-event-lvm2raid
|
|
||||||
LIB_SHARED = $(LIB_NAME).$(LIB_SUFFIX)
|
|
||||||
LIB_VERSION = $(LIB_VERSION_LVM)
|
|
||||||
|
|
||||||
CFLOW_LIST = $(SOURCES)
|
|
||||||
CFLOW_LIST_TARGET = $(LIB_NAME).cflow
|
|
||||||
|
|
||||||
include $(top_builddir)/make.tmpl
|
|
||||||
|
|
||||||
LIBS += -ldevmapper-event-lvm2 -ldevmapper
|
|
||||||
|
|
||||||
install_lvm2: install_dm_plugin
|
|
||||||
|
|
||||||
install: install_lvm2
|
|
||||||
@@ -1,145 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2005-2015 Red Hat, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* This file is part of LVM2.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use,
|
|
||||||
* modify, copy, or redistribute it subject to the terms and conditions
|
|
||||||
* of the GNU Lesser General Public License v.2.1.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this program; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "lib.h"
|
|
||||||
#include "dmeventd_lvm.h"
|
|
||||||
#include "libdevmapper-event.h"
|
|
||||||
|
|
||||||
struct dso_state {
|
|
||||||
struct dm_pool *mem;
|
|
||||||
char cmd_lvscan[512];
|
|
||||||
char cmd_lvconvert[512];
|
|
||||||
int failed;
|
|
||||||
};
|
|
||||||
|
|
||||||
DM_EVENT_LOG_FN("raid")
|
|
||||||
|
|
||||||
/* FIXME Reformat to 80 char lines. */
|
|
||||||
|
|
||||||
static int _process_raid_event(struct dso_state *state, char *params, const char *device)
|
|
||||||
{
|
|
||||||
struct dm_status_raid *status;
|
|
||||||
const char *d;
|
|
||||||
|
|
||||||
if (!dm_get_status_raid(state->mem, params, &status)) {
|
|
||||||
log_error("Failed to process status line for %s.", device);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((d = strchr(status->dev_health, 'D'))) {
|
|
||||||
if (state->failed)
|
|
||||||
goto out; /* already reported */
|
|
||||||
|
|
||||||
log_error("Device #%d of %s array, %s, has failed.",
|
|
||||||
(int)(d - status->dev_health),
|
|
||||||
status->raid_type, device);
|
|
||||||
|
|
||||||
state->failed = 1;
|
|
||||||
if (!dmeventd_lvm2_run_with_lock(state->cmd_lvscan))
|
|
||||||
log_warn("WARNING: Re-scan of RAID device %s failed.", device);
|
|
||||||
|
|
||||||
/* if repair goes OK, report success even if lvscan has failed */
|
|
||||||
if (!dmeventd_lvm2_run_with_lock(state->cmd_lvconvert)) {
|
|
||||||
log_info("Repair of RAID device %s failed.", device);
|
|
||||||
dm_pool_free(state->mem, status);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
state->failed = 0;
|
|
||||||
log_info("%s array, %s, is %s in-sync.",
|
|
||||||
status->raid_type, device,
|
|
||||||
(status->insync_regions == status->total_regions) ? "now" : "not");
|
|
||||||
}
|
|
||||||
out:
|
|
||||||
dm_pool_free(state->mem, status);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void process_event(struct dm_task *dmt,
|
|
||||||
enum dm_event_mask event __attribute__((unused)),
|
|
||||||
void **user)
|
|
||||||
{
|
|
||||||
struct dso_state *state = *user;
|
|
||||||
void *next = NULL;
|
|
||||||
uint64_t start, length;
|
|
||||||
char *target_type = NULL;
|
|
||||||
char *params;
|
|
||||||
const char *device = dm_task_get_name(dmt);
|
|
||||||
|
|
||||||
do {
|
|
||||||
next = dm_get_next_target(dmt, next, &start, &length,
|
|
||||||
&target_type, ¶ms);
|
|
||||||
|
|
||||||
if (!target_type) {
|
|
||||||
log_info("%s mapping lost.", device);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(target_type, "raid")) {
|
|
||||||
log_info("%s has non-raid portion.", device);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_process_raid_event(state, params, device))
|
|
||||||
log_error("Failed to process event for %s.",
|
|
||||||
device);
|
|
||||||
} while (next);
|
|
||||||
}
|
|
||||||
|
|
||||||
int register_device(const char *device,
|
|
||||||
const char *uuid __attribute__((unused)),
|
|
||||||
int major __attribute__((unused)),
|
|
||||||
int minor __attribute__((unused)),
|
|
||||||
void **user)
|
|
||||||
{
|
|
||||||
struct dso_state *state;
|
|
||||||
|
|
||||||
if (!dmeventd_lvm2_init_with_pool("raid_state", state))
|
|
||||||
goto_bad;
|
|
||||||
|
|
||||||
if (!dmeventd_lvm2_command(state->mem, state->cmd_lvscan, sizeof(state->cmd_lvscan),
|
|
||||||
"lvscan --cache", device) ||
|
|
||||||
!dmeventd_lvm2_command(state->mem, state->cmd_lvconvert, sizeof(state->cmd_lvconvert),
|
|
||||||
"lvconvert --config devices{ignore_suspended_devices=1} "
|
|
||||||
"--repair --use-policies", device)) {
|
|
||||||
dmeventd_lvm2_exit_with_pool(state);
|
|
||||||
goto_bad;
|
|
||||||
}
|
|
||||||
|
|
||||||
*user = state;
|
|
||||||
|
|
||||||
log_info("Monitoring RAID device %s for events.", device);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
bad:
|
|
||||||
log_error("Failed to monitor RAID %s.", device);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int unregister_device(const char *device,
|
|
||||||
const char *uuid __attribute__((unused)),
|
|
||||||
int major __attribute__((unused)),
|
|
||||||
int minor __attribute__((unused)),
|
|
||||||
void **user)
|
|
||||||
{
|
|
||||||
struct dso_state *state = *user;
|
|
||||||
|
|
||||||
dmeventd_lvm2_exit_with_pool(state);
|
|
||||||
log_info("No longer monitoring RAID device %s for events.",
|
|
||||||
device);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#
|
#
|
||||||
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||||
# Copyright (C) 2004-2014 Red Hat, Inc. All rights reserved.
|
# Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
|
||||||
#
|
#
|
||||||
# This file is part of the LVM2.
|
# This file is part of the LVM2.
|
||||||
#
|
#
|
||||||
@@ -14,20 +14,22 @@
|
|||||||
|
|
||||||
srcdir = @srcdir@
|
srcdir = @srcdir@
|
||||||
top_srcdir = @top_srcdir@
|
top_srcdir = @top_srcdir@
|
||||||
top_builddir = @top_builddir@
|
VPATH = @srcdir@
|
||||||
|
|
||||||
INCLUDES += -I$(top_srcdir)/daemons/dmeventd/plugins/lvm2
|
INCLUDES += -I${top_srcdir}/tools
|
||||||
CLDFLAGS += -L$(top_builddir)/daemons/dmeventd/plugins/lvm2
|
CLDFLAGS += -L${top_srcdir}/tools -ldevmapper @LVM2CMD_LIB@
|
||||||
|
|
||||||
SOURCES = dmeventd_snapshot.c
|
SOURCES = dmeventd_snapshot.c
|
||||||
|
|
||||||
LIB_SHARED = libdevmapper-event-lvm2snapshot.$(LIB_SUFFIX)
|
ifeq ("@LIB_SUFFIX@","dylib")
|
||||||
LIB_VERSION = $(LIB_VERSION_LVM)
|
LIB_SHARED = libdevmapper-event-lvm2snapshot.dylib
|
||||||
|
else
|
||||||
|
LIB_SHARED = libdevmapper-event-lvm2snapshot.so
|
||||||
|
endif
|
||||||
|
|
||||||
include $(top_builddir)/make.tmpl
|
include $(top_srcdir)/make.tmpl
|
||||||
|
|
||||||
LIBS += -ldevmapper-event-lvm2 -ldevmapper
|
install: libdevmapper-event-lvm2snapshot.$(LIB_SUFFIX)
|
||||||
|
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \
|
||||||
install_lvm2: install_dm_plugin
|
$(libdir)/$<.$(LIB_VERSION)
|
||||||
|
$(LN_S) -f $<.$(LIB_VERSION) $(libdir)/$<
|
||||||
install: install_lvm2
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2007-2015 Red Hat, Inc. All rights reserved.
|
* Copyright (C) 2007-2008 Red Hat, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* This file is part of LVM2.
|
* This file is part of LVM2.
|
||||||
*
|
*
|
||||||
@@ -12,274 +12,202 @@
|
|||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "lib.h"
|
#include "libdevmapper.h"
|
||||||
#include "dmeventd_lvm.h"
|
|
||||||
#include "libdevmapper-event.h"
|
#include "libdevmapper-event.h"
|
||||||
|
#include "lvm2cmd.h"
|
||||||
|
#include "lvm-string.h"
|
||||||
|
|
||||||
#include <sys/wait.h>
|
#include <errno.h>
|
||||||
#include <stdarg.h>
|
#include <signal.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <syslog.h> /* FIXME Replace syslog with multilog */
|
||||||
|
/* FIXME Missing openlog? */
|
||||||
|
|
||||||
/* First warning when snapshot is 80% full. */
|
/* First warning when snapshot is 80% full. */
|
||||||
#define WARNING_THRESH (DM_PERCENT_1 * 80)
|
#define WARNING_THRESH 80
|
||||||
/* Run a check every 5%. */
|
/* Further warnings at 85%, 90% and 95% fullness. */
|
||||||
#define CHECK_STEP (DM_PERCENT_1 * 5)
|
#define WARNING_STEP 5
|
||||||
/* Do not bother checking snapshots less than 50% full. */
|
|
||||||
#define CHECK_MINIMUM (DM_PERCENT_1 * 50)
|
|
||||||
|
|
||||||
#define UMOUNT_COMMAND "/bin/umount"
|
static pthread_mutex_t _register_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
struct dso_state {
|
/*
|
||||||
struct dm_pool *mem;
|
* Number of active registrations.
|
||||||
dm_percent_t percent_check;
|
*/
|
||||||
uint64_t known_size;
|
static int _register_count = 0;
|
||||||
char cmd_lvextend[512];
|
|
||||||
|
static struct dm_pool *_mem_pool = NULL;
|
||||||
|
static void *_lvm_handle = NULL;
|
||||||
|
|
||||||
|
struct snap_status {
|
||||||
|
int invalid;
|
||||||
|
int used;
|
||||||
|
int max;
|
||||||
};
|
};
|
||||||
|
|
||||||
DM_EVENT_LOG_FN("snap")
|
/*
|
||||||
|
* Currently only one event can be processed at a time.
|
||||||
|
*/
|
||||||
|
static pthread_mutex_t _event_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
static int _run(const char *cmd, ...)
|
static void _temporary_log_fn(int level,
|
||||||
|
const char *file __attribute((unused)),
|
||||||
|
int line __attribute((unused)),
|
||||||
|
const char *format)
|
||||||
{
|
{
|
||||||
va_list ap;
|
if (!strncmp(format, "WARNING: ", 9) && (level < 5))
|
||||||
int argc = 1; /* for argv[0], i.e. cmd */
|
syslog(LOG_CRIT, "%s", format);
|
||||||
int i = 0;
|
else
|
||||||
const char **argv;
|
syslog(LOG_DEBUG, "%s", format);
|
||||||
pid_t pid = fork();
|
|
||||||
int status;
|
|
||||||
|
|
||||||
if (pid == 0) { /* child */
|
|
||||||
va_start(ap, cmd);
|
|
||||||
while (va_arg(ap, const char *))
|
|
||||||
++ argc;
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
/* + 1 for the terminating NULL */
|
|
||||||
argv = alloca(sizeof(const char *) * (argc + 1));
|
|
||||||
|
|
||||||
argv[0] = cmd;
|
|
||||||
va_start(ap, cmd);
|
|
||||||
while ((argv[++i] = va_arg(ap, const char *)));
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
execvp(cmd, (char **)argv);
|
|
||||||
log_sys_error("exec", cmd);
|
|
||||||
exit(127);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pid > 0) { /* parent */
|
|
||||||
if (waitpid(pid, &status, 0) != pid)
|
|
||||||
return 0; /* waitpid failed */
|
|
||||||
if (!WIFEXITED(status) || WEXITSTATUS(status))
|
|
||||||
return 0; /* the child failed */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pid < 0)
|
|
||||||
return 0; /* fork failed */
|
|
||||||
|
|
||||||
return 1; /* all good */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _extend(const char *cmd)
|
/* FIXME possibly reconcile this with target_percent when we gain
|
||||||
|
access to regular LVM library here. */
|
||||||
|
static void _parse_snapshot_params(char *params, struct snap_status *stat)
|
||||||
{
|
{
|
||||||
log_debug("Extending snapshot via %s.", cmd);
|
char *p;
|
||||||
return dmeventd_lvm2_run_with_lock(cmd);
|
/*
|
||||||
}
|
* xx/xx -- fractions used/max
|
||||||
|
* Invalid -- snapshot invalidated
|
||||||
|
* Unknown -- status unknown
|
||||||
|
*/
|
||||||
|
stat->used = stat->max = 0;
|
||||||
|
|
||||||
#ifdef SNAPSHOT_REMOVE
|
if (!strncmp(params, "Invalid", 7)) {
|
||||||
/* Remove invalid snapshot from dm-table */
|
stat->invalid = 1;
|
||||||
/* Experimental for now and not used by default */
|
|
||||||
static int _remove(const char *uuid)
|
|
||||||
{
|
|
||||||
int r = 1;
|
|
||||||
uint32_t cookie = 0;
|
|
||||||
struct dm_task *dmt;
|
|
||||||
|
|
||||||
if (!(dmt = dm_task_create(DM_DEVICE_REMOVE)))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (!dm_task_set_uuid(dmt, uuid)) {
|
|
||||||
r = 0;
|
|
||||||
goto_out;
|
|
||||||
}
|
|
||||||
|
|
||||||
dm_task_retry_remove(dmt);
|
|
||||||
|
|
||||||
if (!dm_task_set_cookie(dmt, &cookie, 0)) {
|
|
||||||
r = 0;
|
|
||||||
goto_out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!dm_task_run(dmt)) {
|
|
||||||
r = 0;
|
|
||||||
goto_out;
|
|
||||||
}
|
|
||||||
out:
|
|
||||||
dm_task_destroy(dmt);
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
#endif /* SNAPSHOT_REMOVE */
|
|
||||||
|
|
||||||
static void _umount(const char *device, int major, int minor)
|
|
||||||
{
|
|
||||||
FILE *mounts;
|
|
||||||
char buffer[4096];
|
|
||||||
char *words[3];
|
|
||||||
struct stat st;
|
|
||||||
const char procmounts[] = "/proc/mounts";
|
|
||||||
|
|
||||||
if (!(mounts = fopen(procmounts, "r"))) {
|
|
||||||
log_sys_error("fopen", procmounts);
|
|
||||||
log_error("Not umounting %s.", device);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!feof(mounts)) {
|
|
||||||
/* read a line of /proc/mounts */
|
|
||||||
if (!fgets(buffer, sizeof(buffer), mounts))
|
|
||||||
break; /* eof, likely */
|
|
||||||
|
|
||||||
/* words[0] is the mount point and words[1] is the device path */
|
|
||||||
if (dm_split_words(buffer, 3, 0, words) < 2)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* find the major/minor of the device */
|
|
||||||
if (stat(words[0], &st))
|
|
||||||
continue; /* can't stat, skip this one */
|
|
||||||
|
|
||||||
if (S_ISBLK(st.st_mode) &&
|
|
||||||
major(st.st_rdev) == major &&
|
|
||||||
minor(st.st_rdev) == minor) {
|
|
||||||
log_error("Unmounting invalid snapshot %s from %s.", device, words[1]);
|
|
||||||
if (!_run(UMOUNT_COMMAND, "-fl", words[1], NULL))
|
|
||||||
log_error("Failed to umount snapshot %s from %s: %s.",
|
|
||||||
device, words[1], strerror(errno));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fclose(mounts))
|
|
||||||
log_sys_error("close", procmounts);
|
|
||||||
}
|
|
||||||
|
|
||||||
void process_event(struct dm_task *dmt,
|
|
||||||
enum dm_event_mask event __attribute__((unused)),
|
|
||||||
void **user)
|
|
||||||
{
|
|
||||||
struct dso_state *state = *user;
|
|
||||||
void *next = NULL;
|
|
||||||
uint64_t start, length;
|
|
||||||
char *target_type = NULL;
|
|
||||||
char *params;
|
|
||||||
struct dm_status_snapshot *status = NULL;
|
|
||||||
const char *device = dm_task_get_name(dmt);
|
|
||||||
int percent;
|
|
||||||
struct dm_info info;
|
|
||||||
|
|
||||||
/* No longer monitoring, waiting for remove */
|
|
||||||
if (!state->percent_check)
|
|
||||||
return;
|
|
||||||
|
|
||||||
dm_get_next_target(dmt, next, &start, &length, &target_type, ¶ms);
|
|
||||||
if (!target_type || strcmp(target_type, "snapshot")) {
|
|
||||||
log_error("Target %s is not snapshot.", target_type);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!dm_get_status_snapshot(state->mem, params, &status)) {
|
|
||||||
log_error("Cannot parse snapshot %s state: %s.", device, params);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When we return without setting non-zero max, the parent is
|
||||||
|
* responsible for reporting errors.
|
||||||
|
*/
|
||||||
|
if (!strncmp(params, "Unknown", 7))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!(p = strstr(params, "/")))
|
||||||
|
return;
|
||||||
|
|
||||||
|
*p = '\0';
|
||||||
|
p++;
|
||||||
|
|
||||||
|
stat->used = atoi(params);
|
||||||
|
stat->max = atoi(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void process_event(struct dm_task *dmt,
|
||||||
|
enum dm_event_mask event __attribute((unused)),
|
||||||
|
void **private)
|
||||||
|
{
|
||||||
|
void *next = NULL;
|
||||||
|
uint64_t start, length;
|
||||||
|
char *target_type = NULL;
|
||||||
|
char *params;
|
||||||
|
struct snap_status stat = { 0 };
|
||||||
|
const char *device = dm_task_get_name(dmt);
|
||||||
|
int percent, *percent_warning = (int*)private;
|
||||||
|
|
||||||
|
/* No longer monitoring, waiting for remove */
|
||||||
|
if (!*percent_warning)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (pthread_mutex_trylock(&_event_mutex)) {
|
||||||
|
syslog(LOG_NOTICE, "Another thread is handling an event. Waiting...");
|
||||||
|
pthread_mutex_lock(&_event_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
dm_get_next_target(dmt, next, &start, &length, &target_type, ¶ms);
|
||||||
|
if (!target_type)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
_parse_snapshot_params(params, &stat);
|
||||||
/*
|
/*
|
||||||
* If the snapshot has been invalidated or we failed to parse
|
* If the snapshot has been invalidated or we failed to parse
|
||||||
* the status string. Report the full status string to syslog.
|
* the status string. Report the full status string to syslog.
|
||||||
*/
|
*/
|
||||||
if (status->invalid || status->overflow || !status->total_sectors) {
|
if (stat.invalid || !stat.max) {
|
||||||
log_warn("WARNING: Snapshot %s changed state to: %s and should be removed.",
|
syslog(LOG_ERR, "Snapshot %s changed state to: %s\n", device, params);
|
||||||
device, params);
|
*percent_warning = 0;
|
||||||
state->percent_check = 0;
|
|
||||||
if (dm_task_get_info(dmt, &info))
|
|
||||||
_umount(device, info.major, info.minor);
|
|
||||||
#ifdef SNAPSHOT_REMOVE
|
|
||||||
/* Maybe configurable ? */
|
|
||||||
_remove(dm_task_get_uuid(dmt));
|
|
||||||
#endif
|
|
||||||
pthread_kill(pthread_self(), SIGALRM);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (length <= (status->used_sectors - status->metadata_sectors)) {
|
percent = 100 * stat.used / stat.max;
|
||||||
/* TODO eventually recognize earlier when room is enough */
|
if (percent >= *percent_warning) {
|
||||||
log_info("Dropping monitoring of fully provisioned snapshot %s.",
|
syslog(LOG_WARNING, "Snapshot %s is now %i%% full.\n", device, percent);
|
||||||
device);
|
/* Print warning on the next multiple of WARNING_STEP. */
|
||||||
pthread_kill(pthread_self(), SIGALRM);
|
*percent_warning = (percent / WARNING_STEP) * WARNING_STEP + WARNING_STEP;
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Snapshot size had changed. Clear the threshold. */
|
|
||||||
if (state->known_size != status->total_sectors) {
|
|
||||||
state->percent_check = CHECK_MINIMUM;
|
|
||||||
state->known_size = status->total_sectors;
|
|
||||||
}
|
|
||||||
|
|
||||||
percent = dm_make_percent(status->used_sectors, status->total_sectors);
|
|
||||||
if (percent >= state->percent_check) {
|
|
||||||
/* Usage has raised more than CHECK_STEP since the last
|
|
||||||
time. Run actions. */
|
|
||||||
state->percent_check = (percent / CHECK_STEP) * CHECK_STEP + CHECK_STEP;
|
|
||||||
|
|
||||||
if (percent >= WARNING_THRESH) /* Print a warning to syslog. */
|
|
||||||
log_warn("WARNING: Snapshot %s is now %.2f%% full.",
|
|
||||||
device, dm_percent_to_float(percent));
|
|
||||||
|
|
||||||
/* Try to extend the snapshot, in accord with user-set policies */
|
|
||||||
if (!_extend(state->cmd_lvextend))
|
|
||||||
log_error("Failed to extend snapshot %s.", device);
|
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
dm_pool_free(state->mem, status);
|
pthread_mutex_unlock(&_event_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
int register_device(const char *device,
|
int register_device(const char *device,
|
||||||
const char *uuid __attribute__((unused)),
|
const char *uuid __attribute((unused)),
|
||||||
int major __attribute__((unused)),
|
int major __attribute((unused)),
|
||||||
int minor __attribute__((unused)),
|
int minor __attribute((unused)),
|
||||||
void **user)
|
void **private)
|
||||||
{
|
{
|
||||||
struct dso_state *state;
|
int r = 0;
|
||||||
|
int *percent_warning = (int*)private;
|
||||||
|
|
||||||
if (!dmeventd_lvm2_init_with_pool("snapshot_state", state))
|
pthread_mutex_lock(&_register_mutex);
|
||||||
goto_bad;
|
|
||||||
|
|
||||||
if (!dmeventd_lvm2_command(state->mem, state->cmd_lvextend,
|
/*
|
||||||
sizeof(state->cmd_lvextend),
|
* Need some space for allocations. 1024 should be more
|
||||||
"lvextend --use-policies", device)) {
|
* than enough for what we need (device mapper name splitting)
|
||||||
dmeventd_lvm2_exit_with_pool(state);
|
*/
|
||||||
goto_bad;
|
if (!_mem_pool && !(_mem_pool = dm_pool_create("snapshot_dso", 1024)))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
*percent_warning = WARNING_THRESH; /* Print warning if snapshot is full */
|
||||||
|
|
||||||
|
if (!_lvm_handle) {
|
||||||
|
lvm2_log_fn(_temporary_log_fn);
|
||||||
|
if (!(_lvm_handle = lvm2_init())) {
|
||||||
|
dm_pool_destroy(_mem_pool);
|
||||||
|
_mem_pool = NULL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
lvm2_log_level(_lvm_handle, LVM2_LOG_SUPPRESS);
|
||||||
|
/* FIXME Temporary: move to dmeventd core */
|
||||||
|
lvm2_run(_lvm_handle, "_memlock_inc");
|
||||||
}
|
}
|
||||||
|
|
||||||
state->percent_check = CHECK_MINIMUM;
|
syslog(LOG_INFO, "Monitoring snapshot %s\n", device);
|
||||||
*user = state;
|
|
||||||
|
|
||||||
log_info("Monitoring snapshot %s.", device);
|
_register_count++;
|
||||||
|
r = 1;
|
||||||
|
|
||||||
return 1;
|
out:
|
||||||
bad:
|
pthread_mutex_unlock(&_register_mutex);
|
||||||
log_error("Failed to monitor snapshot %s.", device);
|
|
||||||
|
|
||||||
return 0;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int unregister_device(const char *device,
|
int unregister_device(const char *device,
|
||||||
const char *uuid __attribute__((unused)),
|
const char *uuid __attribute((unused)),
|
||||||
int major __attribute__((unused)),
|
int major __attribute((unused)),
|
||||||
int minor __attribute__((unused)),
|
int minor __attribute((unused)),
|
||||||
void **user)
|
void **unused __attribute((unused)))
|
||||||
{
|
{
|
||||||
struct dso_state *state = *user;
|
pthread_mutex_lock(&_register_mutex);
|
||||||
|
|
||||||
dmeventd_lvm2_exit_with_pool(state);
|
syslog(LOG_INFO, "No longer monitoring snapshot %s\n",
|
||||||
log_info("No longer monitoring snapshot %s.", device);
|
device);
|
||||||
|
|
||||||
|
if (!--_register_count) {
|
||||||
|
dm_pool_destroy(_mem_pool);
|
||||||
|
_mem_pool = NULL;
|
||||||
|
lvm2_run(_lvm_handle, "_memlock_dec");
|
||||||
|
lvm2_exit(_lvm_handle);
|
||||||
|
_lvm_handle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&_register_mutex);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
#
|
|
||||||
# Copyright (C) 2011-2014 Red Hat, Inc. All rights reserved.
|
|
||||||
#
|
|
||||||
# This file is part of LVM2.
|
|
||||||
#
|
|
||||||
# This copyrighted material is made available to anyone wishing to use,
|
|
||||||
# modify, copy, or redistribute it subject to the terms and conditions
|
|
||||||
# of the GNU General Public License v.2.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation,
|
|
||||||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
srcdir = @srcdir@
|
|
||||||
top_srcdir = @top_srcdir@
|
|
||||||
top_builddir = @top_builddir@
|
|
||||||
|
|
||||||
INCLUDES += -I$(top_srcdir)/daemons/dmeventd/plugins/lvm2
|
|
||||||
CLDFLAGS += -L$(top_builddir)/daemons/dmeventd/plugins/lvm2
|
|
||||||
|
|
||||||
SOURCES = dmeventd_thin.c
|
|
||||||
|
|
||||||
LIB_NAME = libdevmapper-event-lvm2thin
|
|
||||||
LIB_SHARED = $(LIB_NAME).$(LIB_SUFFIX)
|
|
||||||
LIB_VERSION = $(LIB_VERSION_LVM)
|
|
||||||
|
|
||||||
CFLOW_LIST = $(SOURCES)
|
|
||||||
CFLOW_LIST_TARGET = $(LIB_NAME).cflow
|
|
||||||
|
|
||||||
include $(top_builddir)/make.tmpl
|
|
||||||
|
|
||||||
LIBS += -ldevmapper-event-lvm2 -ldevmapper
|
|
||||||
|
|
||||||
install_lvm2: install_dm_plugin
|
|
||||||
|
|
||||||
install: install_lvm2
|
|
||||||
@@ -1,400 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2011-2015 Red Hat, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* This file is part of LVM2.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use,
|
|
||||||
* modify, copy, or redistribute it subject to the terms and conditions
|
|
||||||
* of the GNU Lesser General Public License v.2.1.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this program; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "lib.h" /* using here lvm log */
|
|
||||||
#include "dmeventd_lvm.h"
|
|
||||||
#include "libdevmapper-event.h"
|
|
||||||
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <pthread.h>
|
|
||||||
|
|
||||||
/* TODO - move this mountinfo code into library to be reusable */
|
|
||||||
#ifdef __linux__
|
|
||||||
# include "kdev_t.h"
|
|
||||||
#else
|
|
||||||
# define MAJOR(x) major((x))
|
|
||||||
# define MINOR(x) minor((x))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* First warning when thin data or metadata is 80% full. */
|
|
||||||
#define WARNING_THRESH (DM_PERCENT_1 * 80)
|
|
||||||
/* Run a check every 5%. */
|
|
||||||
#define CHECK_STEP (DM_PERCENT_1 * 5)
|
|
||||||
/* Do not bother checking thin data or metadata is less than 50% full. */
|
|
||||||
#define CHECK_MINIMUM (DM_PERCENT_1 * 50)
|
|
||||||
|
|
||||||
#define UMOUNT_COMMAND "/bin/umount"
|
|
||||||
|
|
||||||
#define MAX_FAILS (10)
|
|
||||||
|
|
||||||
#define THIN_DEBUG 0
|
|
||||||
|
|
||||||
struct dso_state {
|
|
||||||
struct dm_pool *mem;
|
|
||||||
int metadata_percent_check;
|
|
||||||
int data_percent_check;
|
|
||||||
uint64_t known_metadata_size;
|
|
||||||
uint64_t known_data_size;
|
|
||||||
unsigned fails;
|
|
||||||
char cmd_str[1024];
|
|
||||||
};
|
|
||||||
|
|
||||||
DM_EVENT_LOG_FN("thin")
|
|
||||||
|
|
||||||
/* Get dependencies for device, and try to find matching device */
|
|
||||||
static int _has_deps(const char *name, int tp_major, int tp_minor, int *dev_minor)
|
|
||||||
{
|
|
||||||
struct dm_task *dmt;
|
|
||||||
const struct dm_deps *deps;
|
|
||||||
struct dm_info info;
|
|
||||||
int major, minor;
|
|
||||||
int r = 0;
|
|
||||||
|
|
||||||
if (!(dmt = dm_task_create(DM_DEVICE_DEPS)))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (!dm_task_set_name(dmt, name))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (!dm_task_no_open_count(dmt))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (!dm_task_run(dmt))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (!dm_task_get_info(dmt, &info))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (!(deps = dm_task_get_deps(dmt)))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (!info.exists || deps->count != 1)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
major = (int) MAJOR(deps->device[0]);
|
|
||||||
minor = (int) MINOR(deps->device[0]);
|
|
||||||
if ((major != tp_major) || (minor != tp_minor))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
*dev_minor = info.minor;
|
|
||||||
|
|
||||||
#if THIN_DEBUG
|
|
||||||
{
|
|
||||||
char dev_name[PATH_MAX];
|
|
||||||
if (dm_device_get_name(major, minor, 0, dev_name, sizeof(dev_name)))
|
|
||||||
log_debug("Found %s (%u:%u) depends on %s.",
|
|
||||||
name, major, *dev_minor, dev_name);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
r = 1;
|
|
||||||
out:
|
|
||||||
dm_task_destroy(dmt);
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get all active devices */
|
|
||||||
static int _find_all_devs(dm_bitset_t bs, int tp_major, int tp_minor)
|
|
||||||
{
|
|
||||||
struct dm_task *dmt;
|
|
||||||
struct dm_names *names;
|
|
||||||
unsigned next = 0;
|
|
||||||
int minor, r = 1;
|
|
||||||
|
|
||||||
if (!(dmt = dm_task_create(DM_DEVICE_LIST)))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (!dm_task_run(dmt)) {
|
|
||||||
r = 0;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(names = dm_task_get_names(dmt))) {
|
|
||||||
r = 0;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!names->dev)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
do {
|
|
||||||
names = (struct dm_names *)((char *) names + next);
|
|
||||||
if (_has_deps(names->name, tp_major, tp_minor, &minor))
|
|
||||||
dm_bit_set(bs, minor);
|
|
||||||
next = names->next;
|
|
||||||
} while (next);
|
|
||||||
|
|
||||||
out:
|
|
||||||
dm_task_destroy(dmt);
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _run(const char *cmd, ...)
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
int argc = 1; /* for argv[0], i.e. cmd */
|
|
||||||
int i = 0;
|
|
||||||
const char **argv;
|
|
||||||
pid_t pid = fork();
|
|
||||||
int status;
|
|
||||||
|
|
||||||
if (pid == 0) { /* child */
|
|
||||||
va_start(ap, cmd);
|
|
||||||
while (va_arg(ap, const char *))
|
|
||||||
++argc;
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
/* + 1 for the terminating NULL */
|
|
||||||
argv = alloca(sizeof(const char *) * (argc + 1));
|
|
||||||
|
|
||||||
argv[0] = cmd;
|
|
||||||
va_start(ap, cmd);
|
|
||||||
while ((argv[++i] = va_arg(ap, const char *)));
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
execvp(cmd, (char **)argv);
|
|
||||||
log_sys_error("exec", cmd);
|
|
||||||
exit(127);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pid > 0) { /* parent */
|
|
||||||
if (waitpid(pid, &status, 0) != pid)
|
|
||||||
return 0; /* waitpid failed */
|
|
||||||
if (!WIFEXITED(status) || WEXITSTATUS(status))
|
|
||||||
return 0; /* the child failed */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pid < 0)
|
|
||||||
return 0; /* fork failed */
|
|
||||||
|
|
||||||
return 1; /* all good */
|
|
||||||
}
|
|
||||||
|
|
||||||
struct mountinfo_s {
|
|
||||||
const char *device;
|
|
||||||
struct dm_info info;
|
|
||||||
dm_bitset_t minors; /* Bitset for active thin pool minors */
|
|
||||||
};
|
|
||||||
|
|
||||||
static int _umount_device(char *buffer, unsigned major, unsigned minor,
|
|
||||||
char *target, void *cb_data)
|
|
||||||
{
|
|
||||||
struct mountinfo_s *data = cb_data;
|
|
||||||
|
|
||||||
if ((major == data->info.major) && dm_bit(data->minors, minor)) {
|
|
||||||
log_info("Unmounting thin volume %s from %s.",
|
|
||||||
data->device, target);
|
|
||||||
if (!_run(UMOUNT_COMMAND, "-fl", target, NULL))
|
|
||||||
log_error("Failed to umount thin %s from %s: %s.",
|
|
||||||
data->device, target, strerror(errno));
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Find all thin pool users and try to umount them.
|
|
||||||
* TODO: work with read-only thin pool support
|
|
||||||
*/
|
|
||||||
static void _umount(struct dm_task *dmt)
|
|
||||||
{
|
|
||||||
/* TODO: Convert to use hash to reduce memory usage */
|
|
||||||
static const size_t MINORS = (1U << 20); /* 20 bit */
|
|
||||||
struct mountinfo_s data = { NULL };
|
|
||||||
|
|
||||||
if (!dm_task_get_info(dmt, &data.info))
|
|
||||||
return;
|
|
||||||
|
|
||||||
data.device = dm_task_get_name(dmt);
|
|
||||||
|
|
||||||
if (!(data.minors = dm_bitset_create(NULL, MINORS))) {
|
|
||||||
log_error("Failed to allocate bitset. Not unmounting %s.", data.device);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_find_all_devs(data.minors, data.info.major, data.info.minor)) {
|
|
||||||
log_error("Failed to detect mounted volumes for %s.", data.device);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!dm_mountinfo_read(_umount_device, &data)) {
|
|
||||||
log_error("Could not parse mountinfo file.");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
if (data.minors)
|
|
||||||
dm_bitset_destroy(data.minors);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _use_policy(struct dm_task *dmt, struct dso_state *state)
|
|
||||||
{
|
|
||||||
#if THIN_DEBUG
|
|
||||||
log_info("dmeventd executes: %s.", state->cmd_str);
|
|
||||||
#endif
|
|
||||||
if (!dmeventd_lvm2_run_with_lock(state->cmd_str)) {
|
|
||||||
log_error("Failed to extend thin pool %s.",
|
|
||||||
dm_task_get_name(dmt));
|
|
||||||
_umount(dmt);
|
|
||||||
state->fails++;
|
|
||||||
} else
|
|
||||||
state->fails = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void process_event(struct dm_task *dmt,
|
|
||||||
enum dm_event_mask event __attribute__((unused)),
|
|
||||||
void **user)
|
|
||||||
{
|
|
||||||
const char *device = dm_task_get_name(dmt);
|
|
||||||
int percent;
|
|
||||||
struct dso_state *state = *user;
|
|
||||||
struct dm_status_thin_pool *tps = NULL;
|
|
||||||
void *next = NULL;
|
|
||||||
uint64_t start, length;
|
|
||||||
char *target_type = NULL;
|
|
||||||
char *params;
|
|
||||||
int needs_policy = 0;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* No longer monitoring, waiting for remove */
|
|
||||||
if (!state->meta_percent_check && !state->data_percent_check)
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
if (event & DM_EVENT_DEVICE_ERROR) {
|
|
||||||
/* Error -> no need to check and do instant resize */
|
|
||||||
_use_policy(dmt, state);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
dm_get_next_target(dmt, next, &start, &length, &target_type, ¶ms);
|
|
||||||
|
|
||||||
if (!target_type || (strcmp(target_type, "thin-pool") != 0)) {
|
|
||||||
log_error("Invalid target type.");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!dm_get_status_thin_pool(state->mem, params, &tps)) {
|
|
||||||
log_error("Failed to parse status.");
|
|
||||||
_umount(dmt);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if THIN_DEBUG
|
|
||||||
log_debug("Thin pool status " FMTu64 "/" FMTu64 " "
|
|
||||||
FMTu64 "/" FMTu64 ".",
|
|
||||||
tps->used_metadata_blocks, tps->total_metadata_blocks,
|
|
||||||
tps->used_data_blocks, tps->total_data_blocks);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Thin pool size had changed. Clear the threshold. */
|
|
||||||
if (state->known_metadata_size != tps->total_metadata_blocks) {
|
|
||||||
state->metadata_percent_check = CHECK_MINIMUM;
|
|
||||||
state->known_metadata_size = tps->total_metadata_blocks;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state->known_data_size != tps->total_data_blocks) {
|
|
||||||
state->data_percent_check = CHECK_MINIMUM;
|
|
||||||
state->known_data_size = tps->total_data_blocks;
|
|
||||||
}
|
|
||||||
|
|
||||||
percent = dm_make_percent(tps->used_metadata_blocks, tps->total_metadata_blocks);
|
|
||||||
if (percent >= state->metadata_percent_check) {
|
|
||||||
/*
|
|
||||||
* Usage has raised more than CHECK_STEP since the last
|
|
||||||
* time. Run actions.
|
|
||||||
*/
|
|
||||||
state->metadata_percent_check = (percent / CHECK_STEP) * CHECK_STEP + CHECK_STEP;
|
|
||||||
|
|
||||||
/* FIXME: extension of metadata needs to be written! */
|
|
||||||
if (percent >= WARNING_THRESH) /* Print a warning to syslog. */
|
|
||||||
log_warn("WARNING: Thin pool %s metadata is now %.2f%% full.",
|
|
||||||
device, dm_percent_to_float(percent));
|
|
||||||
needs_policy = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
percent = dm_make_percent(tps->used_data_blocks, tps->total_data_blocks);
|
|
||||||
if (percent >= state->data_percent_check) {
|
|
||||||
/*
|
|
||||||
* Usage has raised more than CHECK_STEP since
|
|
||||||
* the last time. Run actions.
|
|
||||||
*/
|
|
||||||
state->data_percent_check = (percent / CHECK_STEP) * CHECK_STEP + CHECK_STEP;
|
|
||||||
|
|
||||||
if (percent >= WARNING_THRESH) /* Print a warning to syslog. */
|
|
||||||
log_warn("WARNING: Thin pool %s data is now %.2f%% full.",
|
|
||||||
device, dm_percent_to_float(percent));
|
|
||||||
needs_policy = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (needs_policy)
|
|
||||||
_use_policy(dmt, state);
|
|
||||||
out:
|
|
||||||
if (tps)
|
|
||||||
dm_pool_free(state->mem, tps);
|
|
||||||
|
|
||||||
if (state->fails >= MAX_FAILS) {
|
|
||||||
log_warn("WARNING: Dropping monitoring of %s. "
|
|
||||||
"lvm2 command fails too often (%u times in raw).",
|
|
||||||
device, state->fails);
|
|
||||||
pthread_kill(pthread_self(), SIGALRM);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int register_device(const char *device,
|
|
||||||
const char *uuid __attribute__((unused)),
|
|
||||||
int major __attribute__((unused)),
|
|
||||||
int minor __attribute__((unused)),
|
|
||||||
void **user)
|
|
||||||
{
|
|
||||||
struct dso_state *state;
|
|
||||||
|
|
||||||
if (!dmeventd_lvm2_init_with_pool("thin_pool_state", state))
|
|
||||||
goto_bad;
|
|
||||||
|
|
||||||
if (!dmeventd_lvm2_command(state->mem, state->cmd_str,
|
|
||||||
sizeof(state->cmd_str),
|
|
||||||
"lvextend --use-policies",
|
|
||||||
device)) {
|
|
||||||
dmeventd_lvm2_exit_with_pool(state);
|
|
||||||
goto_bad;
|
|
||||||
}
|
|
||||||
|
|
||||||
state->metadata_percent_check = CHECK_MINIMUM;
|
|
||||||
state->data_percent_check = CHECK_MINIMUM;
|
|
||||||
*user = state;
|
|
||||||
|
|
||||||
log_info("Monitoring thin %s.", device);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
bad:
|
|
||||||
log_error("Failed to monitor thin %s.", device);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int unregister_device(const char *device,
|
|
||||||
const char *uuid __attribute__((unused)),
|
|
||||||
int major __attribute__((unused)),
|
|
||||||
int minor __attribute__((unused)),
|
|
||||||
void **user)
|
|
||||||
{
|
|
||||||
struct dso_state *state = *user;
|
|
||||||
|
|
||||||
dmeventd_lvm2_exit_with_pool(state);
|
|
||||||
log_info("No longer monitoring thin %s.", device);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
2
daemons/lvmetad/.gitignore
vendored
2
daemons/lvmetad/.gitignore
vendored
@@ -1,2 +0,0 @@
|
|||||||
lvmetad
|
|
||||||
lvmetactl
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
#
|
|
||||||
# Copyright (C) 2011-2012 Red Hat, Inc.
|
|
||||||
#
|
|
||||||
# This file is part of LVM2.
|
|
||||||
#
|
|
||||||
# This copyrighted material is made available to anyone wishing to use,
|
|
||||||
# modify, copy, or redistribute it subject to the terms and conditions
|
|
||||||
# of the GNU Lesser General Public License v.2.1.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation,
|
|
||||||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
srcdir = @srcdir@
|
|
||||||
top_srcdir = @top_srcdir@
|
|
||||||
top_builddir = @top_builddir@
|
|
||||||
|
|
||||||
SOURCES = lvmetad-core.c
|
|
||||||
SOURCES2 = testclient.c
|
|
||||||
|
|
||||||
TARGETS = lvmetad lvmetactl
|
|
||||||
|
|
||||||
.PHONY: install_lvmetad
|
|
||||||
|
|
||||||
CFLOW_LIST = $(SOURCES)
|
|
||||||
CFLOW_LIST_TARGET = $(LIB_NAME).cflow
|
|
||||||
CFLOW_TARGET = lvmetad
|
|
||||||
|
|
||||||
include $(top_builddir)/make.tmpl
|
|
||||||
|
|
||||||
INCLUDES += -I$(top_srcdir)/libdaemon/server
|
|
||||||
LVMLIBS = -ldaemonserver $(LVMINTERNAL_LIBS) -ldevmapper
|
|
||||||
|
|
||||||
LIBS += $(PTHREAD_LIBS)
|
|
||||||
|
|
||||||
LDFLAGS += -L$(top_builddir)/libdaemon/server $(EXTRA_EXEC_LDFLAGS)
|
|
||||||
CLDFLAGS += -L$(top_builddir)/libdaemon/server
|
|
||||||
CFLAGS += $(EXTRA_EXEC_CFLAGS)
|
|
||||||
|
|
||||||
lvmetad: $(OBJECTS) $(top_builddir)/libdaemon/client/libdaemonclient.a \
|
|
||||||
$(top_builddir)/libdaemon/server/libdaemonserver.a
|
|
||||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJECTS) $(LVMLIBS) $(LIBS)
|
|
||||||
|
|
||||||
lvmetactl: lvmetactl.o $(top_builddir)/libdaemon/client/libdaemonclient.a \
|
|
||||||
$(top_builddir)/libdaemon/server/libdaemonserver.a
|
|
||||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ lvmetactl.o $(LVMLIBS)
|
|
||||||
|
|
||||||
CLEAN_TARGETS += lvmetactl.o
|
|
||||||
|
|
||||||
# TODO: No idea. No idea how to test either.
|
|
||||||
#ifneq ("$(CFLOW_CMD)", "")
|
|
||||||
#CFLOW_SOURCES = $(addprefix $(srcdir)/, $(SOURCES))
|
|
||||||
#-include $(top_builddir)/libdm/libdevmapper.cflow
|
|
||||||
#-include $(top_builddir)/lib/liblvm-internal.cflow
|
|
||||||
#-include $(top_builddir)/lib/liblvm2cmd.cflow
|
|
||||||
#-include $(top_builddir)/daemons/dmeventd/$(LIB_NAME).cflow
|
|
||||||
#-include $(top_builddir)/daemons/dmeventd/plugins/mirror/$(LIB_NAME)-lvm2mirror.cflow
|
|
||||||
#endif
|
|
||||||
|
|
||||||
install_lvmetad: lvmetad
|
|
||||||
$(INSTALL_PROGRAM) -D $< $(sbindir)/$(<F)
|
|
||||||
|
|
||||||
install_lvm2: install_lvmetad
|
|
||||||
|
|
||||||
install: install_lvm2
|
|
||||||
@@ -1,208 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2014 Red Hat, Inc.
|
|
||||||
*
|
|
||||||
* This file is part of LVM2.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use,
|
|
||||||
* modify, copy, or redistribute it subject to the terms and conditions
|
|
||||||
* of the GNU Lesser General Public License v.2.1.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "tool.h"
|
|
||||||
|
|
||||||
#include "lvmetad-client.h"
|
|
||||||
|
|
||||||
daemon_handle h;
|
|
||||||
|
|
||||||
static void print_reply(daemon_reply reply)
|
|
||||||
{
|
|
||||||
const char *a = daemon_reply_str(reply, "response", NULL);
|
|
||||||
const char *b = daemon_reply_str(reply, "status", NULL);
|
|
||||||
const char *c = daemon_reply_str(reply, "reason", NULL);
|
|
||||||
|
|
||||||
printf("response \"%s\" status \"%s\" reason \"%s\"\n",
|
|
||||||
a ? a : "", b ? b : "", c ? c : "");
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
daemon_reply reply;
|
|
||||||
char *cmd;
|
|
||||||
char *uuid;
|
|
||||||
char *name;
|
|
||||||
int val;
|
|
||||||
int ver;
|
|
||||||
|
|
||||||
if (argc < 2) {
|
|
||||||
printf("lvmetactl dump\n");
|
|
||||||
printf("lvmetactl pv_list\n");
|
|
||||||
printf("lvmetactl vg_list\n");
|
|
||||||
printf("lvmetactl vg_lookup_name <name>\n");
|
|
||||||
printf("lvmetactl vg_lookup_uuid <uuid>\n");
|
|
||||||
printf("lvmetactl pv_lookup_uuid <uuid>\n");
|
|
||||||
printf("lvmetactl set_global_invalid 0|1\n");
|
|
||||||
printf("lvmetactl get_global_invalid\n");
|
|
||||||
printf("lvmetactl set_vg_version <uuid> <name> <version>\n");
|
|
||||||
printf("lvmetactl vg_lock_type <uuid>\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd = argv[1];
|
|
||||||
|
|
||||||
h = lvmetad_open(NULL);
|
|
||||||
|
|
||||||
if (!strcmp(cmd, "dump")) {
|
|
||||||
reply = daemon_send_simple(h, "dump",
|
|
||||||
"token = %s", "skip",
|
|
||||||
NULL);
|
|
||||||
printf("%s\n", reply.buffer.mem);
|
|
||||||
|
|
||||||
} else if (!strcmp(cmd, "pv_list")) {
|
|
||||||
reply = daemon_send_simple(h, "pv_list",
|
|
||||||
"token = %s", "skip",
|
|
||||||
NULL);
|
|
||||||
printf("%s\n", reply.buffer.mem);
|
|
||||||
|
|
||||||
} else if (!strcmp(cmd, "vg_list")) {
|
|
||||||
reply = daemon_send_simple(h, "vg_list",
|
|
||||||
"token = %s", "skip",
|
|
||||||
NULL);
|
|
||||||
printf("%s\n", reply.buffer.mem);
|
|
||||||
|
|
||||||
} else if (!strcmp(cmd, "set_global_invalid")) {
|
|
||||||
if (argc < 3) {
|
|
||||||
printf("set_global_invalid 0|1\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
val = atoi(argv[2]);
|
|
||||||
|
|
||||||
reply = daemon_send_simple(h, "set_global_info",
|
|
||||||
"global_invalid = %d", val,
|
|
||||||
"token = %s", "skip",
|
|
||||||
NULL);
|
|
||||||
print_reply(reply);
|
|
||||||
|
|
||||||
} else if (!strcmp(cmd, "get_global_invalid")) {
|
|
||||||
reply = daemon_send_simple(h, "get_global_info",
|
|
||||||
"token = %s", "skip",
|
|
||||||
NULL);
|
|
||||||
printf("%s\n", reply.buffer.mem);
|
|
||||||
|
|
||||||
} else if (!strcmp(cmd, "set_vg_version")) {
|
|
||||||
if (argc < 5) {
|
|
||||||
printf("set_vg_version <uuid> <name> <ver>\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
uuid = argv[2];
|
|
||||||
name = argv[3];
|
|
||||||
ver = atoi(argv[4]);
|
|
||||||
|
|
||||||
if ((strlen(uuid) == 1) && (uuid[0] == '-'))
|
|
||||||
uuid = NULL;
|
|
||||||
if ((strlen(name) == 1) && (name[0] == '-'))
|
|
||||||
name = NULL;
|
|
||||||
|
|
||||||
if (uuid && name) {
|
|
||||||
reply = daemon_send_simple(h, "set_vg_info",
|
|
||||||
"uuid = %s", uuid,
|
|
||||||
"name = %s", name,
|
|
||||||
"version = %d", ver,
|
|
||||||
"token = %s", "skip",
|
|
||||||
NULL);
|
|
||||||
} else if (uuid) {
|
|
||||||
reply = daemon_send_simple(h, "set_vg_info",
|
|
||||||
"uuid = %s", uuid,
|
|
||||||
"version = %d", ver,
|
|
||||||
"token = %s", "skip",
|
|
||||||
NULL);
|
|
||||||
} else if (name) {
|
|
||||||
reply = daemon_send_simple(h, "set_vg_info",
|
|
||||||
"name = %s", name,
|
|
||||||
"version = %d", ver,
|
|
||||||
"token = %s", "skip",
|
|
||||||
NULL);
|
|
||||||
} else {
|
|
||||||
printf("name or uuid required\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
print_reply(reply);
|
|
||||||
|
|
||||||
} else if (!strcmp(cmd, "vg_lookup_name")) {
|
|
||||||
if (argc < 3) {
|
|
||||||
printf("vg_lookup_name <name>\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
name = argv[2];
|
|
||||||
|
|
||||||
reply = daemon_send_simple(h, "vg_lookup",
|
|
||||||
"name = %s", name,
|
|
||||||
"token = %s", "skip",
|
|
||||||
NULL);
|
|
||||||
printf("%s\n", reply.buffer.mem);
|
|
||||||
|
|
||||||
} else if (!strcmp(cmd, "vg_lookup_uuid")) {
|
|
||||||
if (argc < 3) {
|
|
||||||
printf("vg_lookup_uuid <uuid>\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
uuid = argv[2];
|
|
||||||
|
|
||||||
reply = daemon_send_simple(h, "vg_lookup",
|
|
||||||
"uuid = %s", uuid,
|
|
||||||
"token = %s", "skip",
|
|
||||||
NULL);
|
|
||||||
printf("%s\n", reply.buffer.mem);
|
|
||||||
|
|
||||||
} else if (!strcmp(cmd, "vg_lock_type")) {
|
|
||||||
struct dm_config_node *metadata;
|
|
||||||
const char *lock_type;
|
|
||||||
|
|
||||||
if (argc < 3) {
|
|
||||||
printf("vg_lock_type <uuid>\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
uuid = argv[2];
|
|
||||||
|
|
||||||
reply = daemon_send_simple(h, "vg_lookup",
|
|
||||||
"uuid = %s", uuid,
|
|
||||||
"token = %s", "skip",
|
|
||||||
NULL);
|
|
||||||
/* printf("%s\n", reply.buffer.mem); */
|
|
||||||
|
|
||||||
metadata = dm_config_find_node(reply.cft->root, "metadata");
|
|
||||||
if (!metadata) {
|
|
||||||
printf("no metadata\n");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
lock_type = dm_config_find_str(metadata, "metadata/lock_type", NULL);
|
|
||||||
if (!lock_type) {
|
|
||||||
printf("no lock_type\n");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
printf("lock_type %s\n", lock_type);
|
|
||||||
|
|
||||||
} else if (!strcmp(cmd, "pv_lookup_uuid")) {
|
|
||||||
if (argc < 3) {
|
|
||||||
printf("pv_lookup_uuid <uuid>\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
uuid = argv[2];
|
|
||||||
|
|
||||||
reply = daemon_send_simple(h, "pv_lookup",
|
|
||||||
"uuid = %s", uuid,
|
|
||||||
"token = %s", "skip",
|
|
||||||
NULL);
|
|
||||||
printf("%s\n", reply.buffer.mem);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
printf("unknown command\n");
|
|
||||||
goto out_close;
|
|
||||||
}
|
|
||||||
out:
|
|
||||||
daemon_reply_destroy(reply);
|
|
||||||
out_close:
|
|
||||||
daemon_close(h);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2011-2012 Red Hat, Inc.
|
|
||||||
*
|
|
||||||
* This file is part of LVM2.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use,
|
|
||||||
* modify, copy, or redistribute it subject to the terms and conditions
|
|
||||||
* of the GNU Lesser General Public License v.2.1.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this program; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _LVM_LVMETAD_CLIENT_H
|
|
||||||
#define _LVM_LVMETAD_CLIENT_H
|
|
||||||
|
|
||||||
#include "daemon-client.h"
|
|
||||||
|
|
||||||
#define LVMETAD_SOCKET DEFAULT_RUN_DIR "/lvmetad.socket"
|
|
||||||
|
|
||||||
struct volume_group;
|
|
||||||
|
|
||||||
/* Different types of replies we may get from lvmetad. */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
daemon_reply r;
|
|
||||||
const char **uuids; /* NULL terminated array */
|
|
||||||
} lvmetad_uuidlist;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
daemon_reply r;
|
|
||||||
struct dm_config_tree *cft;
|
|
||||||
} lvmetad_vg;
|
|
||||||
|
|
||||||
/* Get a list of VG UUIDs that match a given VG name. */
|
|
||||||
lvmetad_uuidlist lvmetad_lookup_vgname(daemon_handle h, const char *name);
|
|
||||||
|
|
||||||
/* Get the metadata of a single VG, identified by UUID. */
|
|
||||||
lvmetad_vg lvmetad_get_vg(daemon_handle h, const char *uuid);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Add and remove PVs on demand. Udev-driven systems will use this interface
|
|
||||||
* instead of scanning.
|
|
||||||
*/
|
|
||||||
daemon_reply lvmetad_add_pv(daemon_handle h, const char *pv_uuid, const char *mda_content);
|
|
||||||
daemon_reply lvmetad_remove_pv(daemon_handle h, const char *pv_uuid);
|
|
||||||
|
|
||||||
/* Trigger a full disk scan, throwing away all caches. XXX do we eventually want
|
|
||||||
* this? Probably not yet, anyway.
|
|
||||||
* daemon_reply lvmetad_rescan(daemon_handle h);
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Update the version of metadata of a volume group. The VG has to be locked for
|
|
||||||
* writing for this, and the VG metadata here has to match whatever has been
|
|
||||||
* written to the disk (under this lock). This initially avoids the requirement
|
|
||||||
* for lvmetad to write to disk (in later revisions, lvmetad_supersede_vg may
|
|
||||||
* also do the writing, or we probably add another function to do that).
|
|
||||||
*/
|
|
||||||
daemon_reply lvmetad_supersede_vg(daemon_handle h, struct volume_group *vg);
|
|
||||||
|
|
||||||
/* Wrappers to open/close connection */
|
|
||||||
|
|
||||||
static inline daemon_handle lvmetad_open(const char *socket)
|
|
||||||
{
|
|
||||||
daemon_info lvmetad_info = {
|
|
||||||
.path = "lvmetad",
|
|
||||||
.socket = socket ?: LVMETAD_SOCKET,
|
|
||||||
.protocol = "lvmetad",
|
|
||||||
.protocol_version = 1,
|
|
||||||
.autostart = 0
|
|
||||||
};
|
|
||||||
|
|
||||||
return daemon_open(lvmetad_info);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void lvmetad_close(daemon_handle h)
|
|
||||||
{
|
|
||||||
return daemon_close(h);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,16 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
export LD_LIBRARY_PATH="$1"
|
|
||||||
|
|
||||||
test -n "$2" && {
|
|
||||||
rm -f /var/run/lvmetad.{socket,pid}
|
|
||||||
chmod +rx lvmetad
|
|
||||||
valgrind ./lvmetad -f &
|
|
||||||
PID=$!
|
|
||||||
sleep 1
|
|
||||||
./testclient
|
|
||||||
kill $PID
|
|
||||||
exit 0
|
|
||||||
}
|
|
||||||
|
|
||||||
sudo ./test.sh "$1" .
|
|
||||||
@@ -1,144 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2011-2014 Red Hat, Inc.
|
|
||||||
*
|
|
||||||
* This file is part of LVM2.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use,
|
|
||||||
* modify, copy, or redistribute it subject to the terms and conditions
|
|
||||||
* of the GNU General Public License v.2.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
#include "tool.h"
|
|
||||||
|
|
||||||
#include "lvmetad-client.h"
|
|
||||||
#include "label.h"
|
|
||||||
#include "lvmcache.h"
|
|
||||||
#include "metadata.h"
|
|
||||||
|
|
||||||
const char *uuid1 = "abcd-efgh";
|
|
||||||
const char *uuid2 = "bbcd-efgh";
|
|
||||||
const char *vgid = "yada-yada";
|
|
||||||
const char *uuid3 = "cbcd-efgh";
|
|
||||||
|
|
||||||
const char *metadata2 = "{\n"
|
|
||||||
"id = \"yada-yada\"\n"
|
|
||||||
"seqno = 15\n"
|
|
||||||
"status = [\"READ\", \"WRITE\"]\n"
|
|
||||||
"flags = []\n"
|
|
||||||
"extent_size = 8192\n"
|
|
||||||
"physical_volumes {\n"
|
|
||||||
" pv0 {\n"
|
|
||||||
" id = \"abcd-efgh\"\n"
|
|
||||||
" }\n"
|
|
||||||
" pv1 {\n"
|
|
||||||
" id = \"bbcd-efgh\"\n"
|
|
||||||
" }\n"
|
|
||||||
" pv2 {\n"
|
|
||||||
" id = \"cbcd-efgh\"\n"
|
|
||||||
" }\n"
|
|
||||||
"}\n"
|
|
||||||
"}\n";
|
|
||||||
|
|
||||||
void _handle_reply(daemon_reply reply) {
|
|
||||||
const char *repl = daemon_reply_str(reply, "response", NULL);
|
|
||||||
const char *status = daemon_reply_str(reply, "status", NULL);
|
|
||||||
const char *vgid = daemon_reply_str(reply, "vgid", NULL);
|
|
||||||
|
|
||||||
fprintf(stderr, "[C] REPLY: %s\n", repl);
|
|
||||||
if (!strcmp(repl, "failed"))
|
|
||||||
fprintf(stderr, "[C] REASON: %s\n", daemon_reply_str(reply, "reason", "unknown"));
|
|
||||||
if (vgid)
|
|
||||||
fprintf(stderr, "[C] VGID: %s\n", vgid);
|
|
||||||
if (status)
|
|
||||||
fprintf(stderr, "[C] STATUS: %s\n", status);
|
|
||||||
daemon_reply_destroy(reply);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _pv_add(daemon_handle h, const char *uuid, const char *metadata)
|
|
||||||
{
|
|
||||||
daemon_reply reply = daemon_send_simple(h, "pv_add", "uuid = %s", uuid,
|
|
||||||
"metadata = %b", metadata,
|
|
||||||
NULL);
|
|
||||||
_handle_reply(reply);
|
|
||||||
}
|
|
||||||
|
|
||||||
int scan(daemon_handle h, char *fn) {
|
|
||||||
struct device *dev = dev_cache_get(fn, NULL);
|
|
||||||
|
|
||||||
struct label *label;
|
|
||||||
if (!label_read(dev, &label, 0)) {
|
|
||||||
fprintf(stderr, "[C] no label found on %s\n", fn);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
char uuid[64];
|
|
||||||
id_write_format(dev->pvid, uuid, 64);
|
|
||||||
fprintf(stderr, "[C] found PV: %s\n", uuid);
|
|
||||||
struct lvmcache_info *info = (struct lvmcache_info *) label->info;
|
|
||||||
struct physical_volume pv = { 0, };
|
|
||||||
|
|
||||||
if (!(info->fmt->ops->pv_read(info->fmt, dev_name(dev), &pv, 0))) {
|
|
||||||
fprintf(stderr, "[C] Failed to read PV %s", dev_name(dev));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct format_instance_ctx fic;
|
|
||||||
struct format_instance *fid = info->fmt->ops->create_instance(info->fmt, &fic);
|
|
||||||
struct metadata_area *mda;
|
|
||||||
struct volume_group *vg = NULL;
|
|
||||||
dm_list_iterate_items(mda, &info->mdas) {
|
|
||||||
struct volume_group *this = mda->ops->vg_read(fid, "", mda);
|
|
||||||
if (this && !vg || this->seqno > vg->seqno)
|
|
||||||
vg = this;
|
|
||||||
}
|
|
||||||
if (vg) {
|
|
||||||
char *buf = NULL;
|
|
||||||
/* TODO. This is not entirely correct, since export_vg_to_buffer
|
|
||||||
* adds trailing garbage to the buffer. We may need to use
|
|
||||||
* export_vg_to_config_tree and format the buffer ourselves. It
|
|
||||||
* does, however, work for now, since the garbage is well
|
|
||||||
* formatted and has no conflicting keys with the rest of the
|
|
||||||
* request. */
|
|
||||||
export_vg_to_buffer(vg, &buf);
|
|
||||||
daemon_reply reply =
|
|
||||||
daemon_send_simple(h, "pv_add", "uuid = %s", uuid,
|
|
||||||
"metadata = %b", strchr(buf, '{'),
|
|
||||||
NULL);
|
|
||||||
_handle_reply(reply);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _dump_vg(daemon_handle h, const char *uuid)
|
|
||||||
{
|
|
||||||
daemon_reply reply = daemon_send_simple(h, "vg_by_uuid", "uuid = %s", uuid, NULL);
|
|
||||||
fprintf(stderr, "[C] reply buffer: %s\n", reply.buffer);
|
|
||||||
daemon_reply_destroy(reply);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
|
||||||
daemon_handle h = lvmetad_open();
|
|
||||||
/* FIXME Missing error path */
|
|
||||||
|
|
||||||
if (argc > 1) {
|
|
||||||
int i;
|
|
||||||
struct cmd_context *cmd = create_toolcontext(0, NULL, 0, 0, 1, 1);
|
|
||||||
for (i = 1; i < argc; ++i) {
|
|
||||||
const char *uuid = NULL;
|
|
||||||
scan(h, argv[i]);
|
|
||||||
}
|
|
||||||
destroy_toolcontext(cmd);
|
|
||||||
/* FIXME Missing lvmetad_close() */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
_pv_add(h, uuid1, NULL);
|
|
||||||
_pv_add(h, uuid2, metadata2);
|
|
||||||
_dump_vg(h, vgid);
|
|
||||||
_pv_add(h, uuid3, NULL);
|
|
||||||
|
|
||||||
daemon_close(h); /* FIXME lvmetad_close? */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
2
daemons/lvmlockd/.gitignore
vendored
2
daemons/lvmlockd/.gitignore
vendored
@@ -1,2 +0,0 @@
|
|||||||
lvmlockctl
|
|
||||||
lvmlockd
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
#
|
|
||||||
# Copyright (C) 2014-2015 Red Hat, Inc.
|
|
||||||
#
|
|
||||||
# This file is part of LVM2.
|
|
||||||
#
|
|
||||||
# This copyrighted material is made available to anyone wishing to use,
|
|
||||||
# modify, copy, or redistribute it subject to the terms and conditions
|
|
||||||
# of the GNU Lesser General Public License v.2.1.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation,
|
|
||||||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
srcdir = @srcdir@
|
|
||||||
top_srcdir = @top_srcdir@
|
|
||||||
top_builddir = @top_builddir@
|
|
||||||
|
|
||||||
SOURCES = lvmlockd-core.c
|
|
||||||
|
|
||||||
ifeq ("@BUILD_LOCKDSANLOCK@", "yes")
|
|
||||||
SOURCES += lvmlockd-sanlock.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ("@BUILD_LOCKDDLM@", "yes")
|
|
||||||
SOURCES += lvmlockd-dlm.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
TARGETS = lvmlockd lvmlockctl
|
|
||||||
|
|
||||||
.PHONY: install_lvmlockd
|
|
||||||
|
|
||||||
include $(top_builddir)/make.tmpl
|
|
||||||
|
|
||||||
INCLUDES += -I$(top_srcdir)/libdaemon/server
|
|
||||||
LVMLIBS = -ldaemonserver $(LVMINTERNAL_LIBS) -ldevmapper
|
|
||||||
|
|
||||||
LIBS += $(PTHREAD_LIBS)
|
|
||||||
|
|
||||||
ifeq ("@BUILD_LOCKDSANLOCK@", "yes")
|
|
||||||
LIBS += -lsanlock_client
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ("@BUILD_LOCKDDLM@", "yes")
|
|
||||||
LIBS += -ldlm_lt
|
|
||||||
endif
|
|
||||||
|
|
||||||
LDFLAGS += -L$(top_builddir)/libdaemon/server
|
|
||||||
CLDFLAGS += -L$(top_builddir)/libdaemon/server
|
|
||||||
|
|
||||||
lvmlockd: $(OBJECTS) $(top_builddir)/libdaemon/client/libdaemonclient.a \
|
|
||||||
$(top_builddir)/libdaemon/server/libdaemonserver.a
|
|
||||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJECTS) $(LVMLIBS) $(LIBS)
|
|
||||||
|
|
||||||
lvmlockctl: lvmlockctl.o $(top_builddir)/libdaemon/client/libdaemonclient.a \
|
|
||||||
$(top_builddir)/libdaemon/server/libdaemonserver.a
|
|
||||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ lvmlockctl.o $(LVMLIBS)
|
|
||||||
|
|
||||||
install_lvmlockd: lvmlockd
|
|
||||||
$(INSTALL_PROGRAM) -D $< $(sbindir)/$(<F)
|
|
||||||
|
|
||||||
install_lvmlockctl: lvmlockctl
|
|
||||||
$(INSTALL_PROGRAM) -D $< $(sbindir)/$(<F)
|
|
||||||
|
|
||||||
install_lvm2: install_lvmlockd install_lvmlockctl
|
|
||||||
|
|
||||||
install: install_lvm2
|
|
||||||
@@ -1,753 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2014-2015 Red Hat, Inc.
|
|
||||||
*
|
|
||||||
* This file is part of LVM2.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use,
|
|
||||||
* modify, copy, or redistribute it subject to the terms and conditions
|
|
||||||
* of the GNU Lesser General Public License v.2.1.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "tool.h"
|
|
||||||
|
|
||||||
#include "lvmlockd-client.h"
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <getopt.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <syslog.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/un.h>
|
|
||||||
|
|
||||||
static int quit = 0;
|
|
||||||
static int info = 0;
|
|
||||||
static int dump = 0;
|
|
||||||
static int wait_opt = 0;
|
|
||||||
static int force_opt = 0;
|
|
||||||
static int kill_vg = 0;
|
|
||||||
static int drop_vg = 0;
|
|
||||||
static int gl_enable = 0;
|
|
||||||
static int gl_disable = 0;
|
|
||||||
static int stop_lockspaces = 0;
|
|
||||||
static char *arg_vg_name = NULL;
|
|
||||||
|
|
||||||
#define DUMP_SOCKET_NAME "lvmlockd-dump.sock"
|
|
||||||
#define DUMP_BUF_SIZE (1024 * 1024)
|
|
||||||
static char dump_buf[DUMP_BUF_SIZE+1];
|
|
||||||
static int dump_len;
|
|
||||||
static struct sockaddr_un dump_addr;
|
|
||||||
static socklen_t dump_addrlen;
|
|
||||||
|
|
||||||
daemon_handle _lvmlockd;
|
|
||||||
|
|
||||||
#define log_error(fmt, args...) \
|
|
||||||
do { \
|
|
||||||
printf(fmt "\n", ##args); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define MAX_LINE 512
|
|
||||||
|
|
||||||
/* copied from lvmlockd-internal.h */
|
|
||||||
#define MAX_NAME 64
|
|
||||||
#define MAX_ARGS 64
|
|
||||||
|
|
||||||
/*
|
|
||||||
* lvmlockd dumps the client info before the lockspaces,
|
|
||||||
* so we can look up client info when printing lockspace info.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define MAX_CLIENTS 100
|
|
||||||
|
|
||||||
struct client_info {
|
|
||||||
uint32_t client_id;
|
|
||||||
int pid;
|
|
||||||
char name[MAX_NAME+1];
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct client_info clients[MAX_CLIENTS];
|
|
||||||
static int num_clients;
|
|
||||||
|
|
||||||
static void save_client_info(char *line)
|
|
||||||
{
|
|
||||||
uint32_t pid = 0;
|
|
||||||
int fd = 0;
|
|
||||||
int pi = 0;
|
|
||||||
uint32_t client_id = 0;
|
|
||||||
char name[MAX_NAME+1] = { 0 };
|
|
||||||
|
|
||||||
sscanf(line, "info=client pid=%u fd=%d pi=%d id=%u name=%s",
|
|
||||||
&pid, &fd, &pi, &client_id, name);
|
|
||||||
|
|
||||||
clients[num_clients].client_id = client_id;
|
|
||||||
clients[num_clients].pid = pid;
|
|
||||||
strcpy(clients[num_clients].name, name);
|
|
||||||
num_clients++;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void find_client_info(uint32_t client_id, uint32_t *pid, char *cl_name)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < num_clients; i++) {
|
|
||||||
if (clients[i].client_id == client_id) {
|
|
||||||
*pid = clients[i].pid;
|
|
||||||
strcpy(cl_name, clients[i].name);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int first_ls = 1;
|
|
||||||
|
|
||||||
static void format_info_ls(char *line)
|
|
||||||
{
|
|
||||||
char ls_name[MAX_NAME+1] = { 0 };
|
|
||||||
char vg_name[MAX_NAME+1] = { 0 };
|
|
||||||
char vg_uuid[MAX_NAME+1] = { 0 };
|
|
||||||
char vg_sysid[MAX_NAME+1] = { 0 };
|
|
||||||
char lock_args[MAX_ARGS+1] = { 0 };
|
|
||||||
char lock_type[MAX_NAME+1] = { 0 };
|
|
||||||
|
|
||||||
sscanf(line, "info=ls ls_name=%s vg_name=%s vg_uuid=%s vg_sysid=%s vg_args=%s lm_type=%s",
|
|
||||||
ls_name, vg_name, vg_uuid, vg_sysid, lock_args, lock_type);
|
|
||||||
|
|
||||||
if (!first_ls)
|
|
||||||
printf("\n");
|
|
||||||
first_ls = 0;
|
|
||||||
|
|
||||||
printf("VG %s lock_type=%s %s\n", vg_name, lock_type, vg_uuid);
|
|
||||||
|
|
||||||
printf("LS %s %s\n", lock_type, ls_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void format_info_ls_action(char *line)
|
|
||||||
{
|
|
||||||
uint32_t client_id = 0;
|
|
||||||
char flags[MAX_NAME+1] = { 0 };
|
|
||||||
char version[MAX_NAME+1] = { 0 };
|
|
||||||
char op[MAX_NAME+1] = { 0 };
|
|
||||||
uint32_t pid = 0;
|
|
||||||
char cl_name[MAX_NAME+1] = { 0 };
|
|
||||||
|
|
||||||
sscanf(line, "info=ls_action client_id=%u %s %s op=%s",
|
|
||||||
&client_id, flags, version, op);
|
|
||||||
|
|
||||||
find_client_info(client_id, &pid, cl_name);
|
|
||||||
|
|
||||||
printf("OP %s pid %u (%s)\n", op, pid, cl_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void format_info_r(char *line, char *r_name_out, char *r_type_out)
|
|
||||||
{
|
|
||||||
char r_name[MAX_NAME+1] = { 0 };
|
|
||||||
char r_type[4] = { 0 };
|
|
||||||
char mode[4] = { 0 };
|
|
||||||
char sh_count[MAX_NAME+1] = { 0 };
|
|
||||||
uint32_t ver = 0;
|
|
||||||
|
|
||||||
sscanf(line, "info=r name=%s type=%s mode=%s %s version=%u",
|
|
||||||
r_name, r_type, mode, sh_count, &ver);
|
|
||||||
|
|
||||||
strcpy(r_name_out, r_name);
|
|
||||||
strcpy(r_type_out, r_type);
|
|
||||||
|
|
||||||
/* when mode is not un, wait and print each lk line */
|
|
||||||
if (strcmp(mode, "un"))
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* when mode is un, there will be no lk lines, so print now */
|
|
||||||
|
|
||||||
if (!strcmp(r_type, "gl")) {
|
|
||||||
printf("LK GL un ver %u\n", ver);
|
|
||||||
|
|
||||||
} else if (!strcmp(r_type, "vg")) {
|
|
||||||
printf("LK VG un ver %u\n", ver);
|
|
||||||
|
|
||||||
} else if (!strcmp(r_type, "lv")) {
|
|
||||||
printf("LK LV un %s\n", r_name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void format_info_lk(char *line, char *r_name, char *r_type)
|
|
||||||
{
|
|
||||||
char mode[4] = { 0 };
|
|
||||||
uint32_t ver = 0;
|
|
||||||
char flags[MAX_NAME+1] = { 0 };
|
|
||||||
uint32_t client_id = 0;
|
|
||||||
uint32_t pid = 0;
|
|
||||||
char cl_name[MAX_NAME+1] = { 0 };
|
|
||||||
|
|
||||||
if (!r_name[0] || !r_type[0]) {
|
|
||||||
printf("format_info_lk error r_name %s r_type %s\n", r_name, r_type);
|
|
||||||
printf("%s\n", line);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
sscanf(line, "info=lk mode=%s version=%u %s client_id=%u",
|
|
||||||
mode, &ver, flags, &client_id);
|
|
||||||
|
|
||||||
find_client_info(client_id, &pid, cl_name);
|
|
||||||
|
|
||||||
if (!strcmp(r_type, "gl")) {
|
|
||||||
printf("LK GL %s ver %u pid %u (%s)\n", mode, ver, pid, cl_name);
|
|
||||||
|
|
||||||
} else if (!strcmp(r_type, "vg")) {
|
|
||||||
printf("LK VG %s ver %u pid %u (%s)\n", mode, ver, pid, cl_name);
|
|
||||||
|
|
||||||
} else if (!strcmp(r_type, "lv")) {
|
|
||||||
printf("LK LV %s %s\n", mode, r_name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void format_info_r_action(char *line, char *r_name, char *r_type)
|
|
||||||
{
|
|
||||||
uint32_t client_id = 0;
|
|
||||||
char flags[MAX_NAME+1] = { 0 };
|
|
||||||
char version[MAX_NAME+1] = { 0 };
|
|
||||||
char op[MAX_NAME+1] = { 0 };
|
|
||||||
char rt[4] = { 0 };
|
|
||||||
char mode[4] = { 0 };
|
|
||||||
char lm[MAX_NAME+1] = { 0 };
|
|
||||||
char result[MAX_NAME+1] = { 0 };
|
|
||||||
char lm_rv[MAX_NAME+1] = { 0 };
|
|
||||||
uint32_t pid = 0;
|
|
||||||
char cl_name[MAX_NAME+1] = { 0 };
|
|
||||||
|
|
||||||
if (!r_name[0] || !r_type[0]) {
|
|
||||||
printf("format_info_r_action error r_name %s r_type %s\n", r_name, r_type);
|
|
||||||
printf("%s\n", line);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
sscanf(line, "info=r_action client_id=%u %s %s op=%s rt=%s mode=%s %s %s %s",
|
|
||||||
&client_id, flags, version, op, rt, mode, lm, result, lm_rv);
|
|
||||||
|
|
||||||
find_client_info(client_id, &pid, cl_name);
|
|
||||||
|
|
||||||
if (strcmp(op, "lock")) {
|
|
||||||
printf("OP %s pid %u (%s)\n", op, pid, cl_name);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!strcmp(r_type, "gl")) {
|
|
||||||
printf("LW GL %s ver %u pid %u (%s)\n", mode, 0, pid, cl_name);
|
|
||||||
|
|
||||||
} else if (!strcmp(r_type, "vg")) {
|
|
||||||
printf("LW VG %s ver %u pid %u (%s)\n", mode, 0, pid, cl_name);
|
|
||||||
|
|
||||||
} else if (!strcmp(r_type, "lv")) {
|
|
||||||
printf("LW LV %s %s\n", mode, r_name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void format_info_line(char *line, char *r_name, char *r_type)
|
|
||||||
{
|
|
||||||
if (!strncmp(line, "info=structs ", strlen("info=structs "))) {
|
|
||||||
/* only print this in the raw info dump */
|
|
||||||
|
|
||||||
} else if (!strncmp(line, "info=client ", strlen("info=client "))) {
|
|
||||||
save_client_info(line);
|
|
||||||
|
|
||||||
} else if (!strncmp(line, "info=ls ", strlen("info=ls "))) {
|
|
||||||
format_info_ls(line);
|
|
||||||
|
|
||||||
} else if (!strncmp(line, "info=ls_action ", strlen("info=ls_action "))) {
|
|
||||||
format_info_ls_action(line);
|
|
||||||
|
|
||||||
} else if (!strncmp(line, "info=r ", strlen("info=r "))) {
|
|
||||||
/*
|
|
||||||
* r_name/r_type are reset when a new resource is found.
|
|
||||||
* They are reused for the lock and action lines that
|
|
||||||
* follow a resource line.
|
|
||||||
*/
|
|
||||||
memset(r_name, 0, MAX_NAME+1);
|
|
||||||
memset(r_type, 0, MAX_NAME+1);
|
|
||||||
format_info_r(line, r_name, r_type);
|
|
||||||
|
|
||||||
} else if (!strncmp(line, "info=lk ", strlen("info=lk "))) {
|
|
||||||
/* will use info from previous r */
|
|
||||||
format_info_lk(line, r_name, r_type);
|
|
||||||
|
|
||||||
} else if (!strncmp(line, "info=r_action ", strlen("info=r_action "))) {
|
|
||||||
/* will use info from previous r */
|
|
||||||
format_info_r_action(line, r_name, r_type);
|
|
||||||
} else {
|
|
||||||
printf("UN %s\n", line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void format_info(void)
|
|
||||||
{
|
|
||||||
char line[MAX_LINE];
|
|
||||||
char r_name[MAX_NAME+1];
|
|
||||||
char r_type[MAX_NAME+1];
|
|
||||||
int i, j;
|
|
||||||
|
|
||||||
j = 0;
|
|
||||||
memset(line, 0, sizeof(line));
|
|
||||||
|
|
||||||
for (i = 0; i < dump_len; i++) {
|
|
||||||
line[j++] = dump_buf[i];
|
|
||||||
|
|
||||||
if ((line[j-1] == '\n') || (line[j-1] == '\0')) {
|
|
||||||
format_info_line(line, r_name, r_type);
|
|
||||||
j = 0;
|
|
||||||
memset(line, 0, sizeof(line));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static daemon_reply _lvmlockd_send(const char *req_name, ...)
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
daemon_reply repl;
|
|
||||||
daemon_request req;
|
|
||||||
|
|
||||||
req = daemon_request_make(req_name);
|
|
||||||
|
|
||||||
va_start(ap, req_name);
|
|
||||||
daemon_request_extend_v(req, ap);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
repl = daemon_send(_lvmlockd, req);
|
|
||||||
|
|
||||||
daemon_request_destroy(req);
|
|
||||||
|
|
||||||
return repl;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* See the same in lib/locking/lvmlockd.c */
|
|
||||||
#define NO_LOCKD_RESULT -1000
|
|
||||||
|
|
||||||
static int _lvmlockd_result(daemon_reply reply, int *result)
|
|
||||||
{
|
|
||||||
int reply_result;
|
|
||||||
|
|
||||||
if (reply.error) {
|
|
||||||
log_error("lvmlockd_result reply error %d", reply.error);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(daemon_reply_str(reply, "response", ""), "OK")) {
|
|
||||||
log_error("lvmlockd_result bad response");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
reply_result = daemon_reply_int(reply, "op_result", NO_LOCKD_RESULT);
|
|
||||||
if (reply_result == -1000) {
|
|
||||||
log_error("lvmlockd_result no op_result");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
*result = reply_result;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int do_quit(void)
|
|
||||||
{
|
|
||||||
daemon_reply reply;
|
|
||||||
int rv = 0;
|
|
||||||
|
|
||||||
reply = daemon_send_simple(_lvmlockd, "quit", NULL);
|
|
||||||
|
|
||||||
if (reply.error) {
|
|
||||||
log_error("reply error %d", reply.error);
|
|
||||||
rv = reply.error;
|
|
||||||
}
|
|
||||||
|
|
||||||
daemon_reply_destroy(reply);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int setup_dump_socket(void)
|
|
||||||
{
|
|
||||||
int s, rv;
|
|
||||||
|
|
||||||
s = socket(AF_LOCAL, SOCK_DGRAM, 0);
|
|
||||||
if (s < 0)
|
|
||||||
return s;
|
|
||||||
|
|
||||||
memset(&dump_addr, 0, sizeof(dump_addr));
|
|
||||||
dump_addr.sun_family = AF_LOCAL;
|
|
||||||
strcpy(&dump_addr.sun_path[1], DUMP_SOCKET_NAME);
|
|
||||||
dump_addrlen = sizeof(sa_family_t) + strlen(dump_addr.sun_path+1) + 1;
|
|
||||||
|
|
||||||
rv = bind(s, (struct sockaddr *) &dump_addr, dump_addrlen);
|
|
||||||
if (rv < 0) {
|
|
||||||
rv = -errno;
|
|
||||||
if (!close(s))
|
|
||||||
log_error("failed to close dump socket");
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int do_dump(const char *req_name)
|
|
||||||
{
|
|
||||||
daemon_reply reply;
|
|
||||||
int result;
|
|
||||||
int fd, rv = 0;
|
|
||||||
int count = 0;
|
|
||||||
|
|
||||||
fd = setup_dump_socket();
|
|
||||||
if (fd < 0) {
|
|
||||||
log_error("socket error %d", fd);
|
|
||||||
return fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
reply = daemon_send_simple(_lvmlockd, req_name, NULL);
|
|
||||||
|
|
||||||
if (reply.error) {
|
|
||||||
log_error("reply error %d", reply.error);
|
|
||||||
rv = reply.error;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = daemon_reply_int(reply, "result", 0);
|
|
||||||
dump_len = daemon_reply_int(reply, "dump_len", 0);
|
|
||||||
|
|
||||||
daemon_reply_destroy(reply);
|
|
||||||
|
|
||||||
if (result < 0) {
|
|
||||||
rv = result;
|
|
||||||
log_error("result %d", result);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!dump_len)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
memset(dump_buf, 0, sizeof(dump_buf));
|
|
||||||
|
|
||||||
retry:
|
|
||||||
rv = recvfrom(fd, dump_buf + count, dump_len - count, MSG_WAITALL,
|
|
||||||
(struct sockaddr *)&dump_addr, &dump_addrlen);
|
|
||||||
if (rv < 0) {
|
|
||||||
log_error("recvfrom error %d %d", rv, errno);
|
|
||||||
rv = -errno;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
count += rv;
|
|
||||||
|
|
||||||
if (count < dump_len)
|
|
||||||
goto retry;
|
|
||||||
|
|
||||||
rv = 0;
|
|
||||||
if ((info && dump) || !strcmp(req_name, "dump"))
|
|
||||||
printf("%s\n", dump_buf);
|
|
||||||
else
|
|
||||||
format_info();
|
|
||||||
out:
|
|
||||||
if (close(fd))
|
|
||||||
log_error("failed to close dump socket %d", fd);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int do_able(const char *req_name)
|
|
||||||
{
|
|
||||||
daemon_reply reply;
|
|
||||||
int result;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
reply = _lvmlockd_send(req_name,
|
|
||||||
"cmd = %s", "lvmlockctl",
|
|
||||||
"pid = %d", getpid(),
|
|
||||||
"vg_name = %s", arg_vg_name,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (!_lvmlockd_result(reply, &result)) {
|
|
||||||
log_error("lvmlockd result %d", result);
|
|
||||||
rv = result;
|
|
||||||
} else {
|
|
||||||
rv = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
daemon_reply_destroy(reply);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int do_stop_lockspaces(void)
|
|
||||||
{
|
|
||||||
daemon_reply reply;
|
|
||||||
char opts[32];
|
|
||||||
int result;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
memset(opts, 0, sizeof(opts));
|
|
||||||
|
|
||||||
if (wait_opt)
|
|
||||||
strcat(opts, "wait ");
|
|
||||||
if (force_opt)
|
|
||||||
strcat(opts, "force ");
|
|
||||||
|
|
||||||
reply = _lvmlockd_send("stop_all",
|
|
||||||
"cmd = %s", "lvmlockctl",
|
|
||||||
"pid = %d", getpid(),
|
|
||||||
"opts = %s", opts[0] ? opts : "none",
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (!_lvmlockd_result(reply, &result)) {
|
|
||||||
log_error("lvmlockd result %d", result);
|
|
||||||
rv = result;
|
|
||||||
} else {
|
|
||||||
rv = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
daemon_reply_destroy(reply);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int do_kill(void)
|
|
||||||
{
|
|
||||||
daemon_reply reply;
|
|
||||||
int result;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
syslog(LOG_EMERG, "Lost access to sanlock lease storage in VG %s.", arg_vg_name);
|
|
||||||
/* These two lines explain the manual alternative to the FIXME below. */
|
|
||||||
syslog(LOG_EMERG, "Immediately deactivate LVs in VG %s.", arg_vg_name);
|
|
||||||
syslog(LOG_EMERG, "Once VG is unused, run lvmlockctl --drop %s.", arg_vg_name);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* It may not be strictly necessary to notify lvmlockd of the kill, but
|
|
||||||
* lvmlockd can use this information to avoid attempting any new lock
|
|
||||||
* requests in the VG (which would fail anyway), and can return an
|
|
||||||
* error indicating that the VG has been killed.
|
|
||||||
*/
|
|
||||||
|
|
||||||
reply = _lvmlockd_send("kill_vg",
|
|
||||||
"cmd = %s", "lvmlockctl",
|
|
||||||
"pid = %d", getpid(),
|
|
||||||
"vg_name = %s", arg_vg_name,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (!_lvmlockd_result(reply, &result)) {
|
|
||||||
log_error("lvmlockd result %d", result);
|
|
||||||
rv = result;
|
|
||||||
} else {
|
|
||||||
rv = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
daemon_reply_destroy(reply);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* FIXME: here is where we should implement a strong form of
|
|
||||||
* blkdeactivate, and if it completes successfully, automatically call
|
|
||||||
* do_drop() afterward. (The drop step may not always be necessary
|
|
||||||
* if the lvm commands run while shutting things down release all the
|
|
||||||
* leases.)
|
|
||||||
*
|
|
||||||
* run_strong_blkdeactivate();
|
|
||||||
* do_drop();
|
|
||||||
*/
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int do_drop(void)
|
|
||||||
{
|
|
||||||
daemon_reply reply;
|
|
||||||
int result;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
syslog(LOG_WARNING, "Dropping locks for VG %s.", arg_vg_name);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check for misuse by looking for any active LVs in the VG
|
|
||||||
* and refusing this operation if found? One possible way
|
|
||||||
* to kill LVs (e.g. if fs cannot be unmounted) is to suspend
|
|
||||||
* them, or replace them with the error target. In that
|
|
||||||
* case the LV will still appear to be active, but it is
|
|
||||||
* safe to release the lock.
|
|
||||||
*/
|
|
||||||
|
|
||||||
reply = _lvmlockd_send("drop_vg",
|
|
||||||
"cmd = %s", "lvmlockctl",
|
|
||||||
"pid = %d", getpid(),
|
|
||||||
"vg_name = %s", arg_vg_name,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (!_lvmlockd_result(reply, &result)) {
|
|
||||||
log_error("lvmlockd result %d", result);
|
|
||||||
rv = result;
|
|
||||||
} else {
|
|
||||||
rv = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
daemon_reply_destroy(reply);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void print_usage(void)
|
|
||||||
{
|
|
||||||
printf("lvmlockctl options\n");
|
|
||||||
printf("Options:\n");
|
|
||||||
printf("--help | -h\n");
|
|
||||||
printf(" Show this help information.\n");
|
|
||||||
printf("--quit | -q\n");
|
|
||||||
printf(" Tell lvmlockd to quit.\n");
|
|
||||||
printf("--info | -i\n");
|
|
||||||
printf(" Print lock state information from lvmlockd.\n");
|
|
||||||
printf("--dump | -d\n");
|
|
||||||
printf(" Print log buffer from lvmlockd.\n");
|
|
||||||
printf("--wait | -w 0|1\n");
|
|
||||||
printf(" Wait option for other commands.\n");
|
|
||||||
printf("--force | -f 0|1>\n");
|
|
||||||
printf(" Force option for other commands.\n");
|
|
||||||
printf("--kill | -k <vgname>\n");
|
|
||||||
printf(" Kill access to the VG when sanlock cannot renew lease.\n");
|
|
||||||
printf("--drop | -r <vgname>\n");
|
|
||||||
printf(" Clear locks for the VG when it is unused after kill (-k).\n");
|
|
||||||
printf("--gl-enable | -E <vgname>\n");
|
|
||||||
printf(" Tell lvmlockd to enable the global lock in a sanlock VG.\n");
|
|
||||||
printf("--gl-disable | -D <vgname>\n");
|
|
||||||
printf(" Tell lvmlockd to disable the global lock in a sanlock VG.\n");
|
|
||||||
printf("--stop-lockspaces | -S\n");
|
|
||||||
printf(" Stop all lockspaces.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static int read_options(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
int option_index = 0;
|
|
||||||
int c;
|
|
||||||
|
|
||||||
static struct option long_options[] = {
|
|
||||||
{"help", no_argument, 0, 'h' },
|
|
||||||
{"quit", no_argument, 0, 'q' },
|
|
||||||
{"info", no_argument, 0, 'i' },
|
|
||||||
{"dump", no_argument, 0, 'd' },
|
|
||||||
{"wait", required_argument, 0, 'w' },
|
|
||||||
{"force", required_argument, 0, 'f' },
|
|
||||||
{"kill", required_argument, 0, 'k' },
|
|
||||||
{"drop", required_argument, 0, 'r' },
|
|
||||||
{"gl-enable", required_argument, 0, 'E' },
|
|
||||||
{"gl-disable", required_argument, 0, 'D' },
|
|
||||||
{"stop-lockspaces", no_argument, 0, 'S' },
|
|
||||||
{0, 0, 0, 0 }
|
|
||||||
};
|
|
||||||
|
|
||||||
if (argc == 1) {
|
|
||||||
print_usage();
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
c = getopt_long(argc, argv, "hqidE:D:w:k:r:S", long_options, &option_index);
|
|
||||||
if (c == -1)
|
|
||||||
break;
|
|
||||||
|
|
||||||
switch (c) {
|
|
||||||
case 'h':
|
|
||||||
/* --help */
|
|
||||||
print_usage();
|
|
||||||
exit(0);
|
|
||||||
case 'q':
|
|
||||||
/* --quit */
|
|
||||||
quit = 1;
|
|
||||||
break;
|
|
||||||
case 'i':
|
|
||||||
/* --info */
|
|
||||||
info = 1;
|
|
||||||
break;
|
|
||||||
case 'd':
|
|
||||||
/* --dump */
|
|
||||||
dump = 1;
|
|
||||||
break;
|
|
||||||
case 'w':
|
|
||||||
wait_opt = atoi(optarg);
|
|
||||||
break;
|
|
||||||
case 'k':
|
|
||||||
kill_vg = 1;
|
|
||||||
arg_vg_name = strdup(optarg);
|
|
||||||
break;
|
|
||||||
case 'r':
|
|
||||||
drop_vg = 1;
|
|
||||||
arg_vg_name = strdup(optarg);
|
|
||||||
break;
|
|
||||||
case 'E':
|
|
||||||
gl_enable = 1;
|
|
||||||
arg_vg_name = strdup(optarg);
|
|
||||||
break;
|
|
||||||
case 'D':
|
|
||||||
gl_disable = 1;
|
|
||||||
arg_vg_name = strdup(optarg);
|
|
||||||
break;
|
|
||||||
case 'S':
|
|
||||||
stop_lockspaces = 1;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
print_usage();
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
int rv = 0;
|
|
||||||
|
|
||||||
rv = read_options(argc, argv);
|
|
||||||
if (rv < 0)
|
|
||||||
return rv;
|
|
||||||
|
|
||||||
_lvmlockd = lvmlockd_open(NULL);
|
|
||||||
|
|
||||||
if (_lvmlockd.socket_fd < 0 || _lvmlockd.error) {
|
|
||||||
log_error("Cannot connect to lvmlockd.");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (quit) {
|
|
||||||
rv = do_quit();
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (info) {
|
|
||||||
rv = do_dump("info");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dump) {
|
|
||||||
rv = do_dump("dump");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (kill_vg) {
|
|
||||||
rv = do_kill();
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (drop_vg) {
|
|
||||||
rv = do_drop();
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gl_enable) {
|
|
||||||
syslog(LOG_INFO, "Enabling global lock in VG %s.", arg_vg_name);
|
|
||||||
rv = do_able("enable_gl");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gl_disable) {
|
|
||||||
syslog(LOG_INFO, "Disabling global lock in VG %s.", arg_vg_name);
|
|
||||||
rv = do_able("disable_gl");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stop_lockspaces) {
|
|
||||||
rv = do_stop_lockspaces();
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
lvmlockd_close(_lvmlockd);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2014-2015 Red Hat, Inc.
|
|
||||||
*
|
|
||||||
* This file is part of LVM2.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use,
|
|
||||||
* modify, copy, or redistribute it subject to the terms and conditions
|
|
||||||
* of the GNU Lesser General Public License v.2.1.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _LVM_LVMLOCKD_CLIENT_H
|
|
||||||
#define _LVM_LVMLOCKD_CLIENT_H
|
|
||||||
|
|
||||||
#include "daemon-client.h"
|
|
||||||
|
|
||||||
#define LVMLOCKD_SOCKET DEFAULT_RUN_DIR "/lvmlockd.socket"
|
|
||||||
|
|
||||||
/* Wrappers to open/close connection */
|
|
||||||
|
|
||||||
static inline daemon_handle lvmlockd_open(const char *sock)
|
|
||||||
{
|
|
||||||
daemon_info lvmlockd_info = {
|
|
||||||
.path = "lvmlockd",
|
|
||||||
.socket = sock ?: LVMLOCKD_SOCKET,
|
|
||||||
.protocol = "lvmlockd",
|
|
||||||
.protocol_version = 1,
|
|
||||||
.autostart = 0
|
|
||||||
};
|
|
||||||
|
|
||||||
return daemon_open(lvmlockd_info);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void lvmlockd_close(daemon_handle h)
|
|
||||||
{
|
|
||||||
return daemon_close(h);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Errors returned as the lvmlockd result value.
|
|
||||||
*/
|
|
||||||
#define ENOLS 210 /* lockspace not found */
|
|
||||||
#define ESTARTING 211 /* lockspace is starting */
|
|
||||||
#define EARGS 212
|
|
||||||
#define EHOSTID 213
|
|
||||||
#define EMANAGER 214
|
|
||||||
#define EPREPARE 215
|
|
||||||
#define ELOCKD 216
|
|
||||||
#define EVGKILLED 217 /* sanlock lost access to leases and VG is killed. */
|
|
||||||
#define ELOCKIO 218 /* sanlock io errors during lock op, may be transient. */
|
|
||||||
#define EREMOVED 219
|
|
||||||
|
|
||||||
#endif /* _LVM_LVMLOCKD_CLIENT_H */
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,767 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2014-2015 Red Hat, Inc.
|
|
||||||
*
|
|
||||||
* This file is part of LVM2.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use,
|
|
||||||
* modify, copy, or redistribute it subject to the terms and conditions
|
|
||||||
* of the GNU Lesser General Public License v.2.1.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define _XOPEN_SOURCE 500 /* pthread */
|
|
||||||
#define _ISOC99_SOURCE
|
|
||||||
|
|
||||||
#include "tool.h"
|
|
||||||
|
|
||||||
#include "daemon-server.h"
|
|
||||||
#include "daemon-log.h"
|
|
||||||
#include "xlate.h"
|
|
||||||
|
|
||||||
#include "lvmlockd-internal.h"
|
|
||||||
#include "lvmlockd-client.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Using synchronous _wait dlm apis so do not define _REENTRANT and
|
|
||||||
* link with non-threaded version of library, libdlm_lt.
|
|
||||||
*/
|
|
||||||
#include "libdlm.h"
|
|
||||||
|
|
||||||
#include <pthread.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <poll.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <endian.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <byteswap.h>
|
|
||||||
#include <syslog.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
|
|
||||||
struct lm_dlm {
|
|
||||||
dlm_lshandle_t *dh;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct rd_dlm {
|
|
||||||
struct dlm_lksb lksb;
|
|
||||||
struct val_blk *vb;
|
|
||||||
};
|
|
||||||
|
|
||||||
int lm_data_size_dlm(void)
|
|
||||||
{
|
|
||||||
return sizeof(struct rd_dlm);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* lock_args format
|
|
||||||
*
|
|
||||||
* vg_lock_args format for dlm is
|
|
||||||
* vg_version_string:undefined:cluster_name
|
|
||||||
*
|
|
||||||
* lv_lock_args are not used for dlm
|
|
||||||
*
|
|
||||||
* version_string is MAJOR.MINOR.PATCH
|
|
||||||
* undefined may contain ":"
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define VG_LOCK_ARGS_MAJOR 1
|
|
||||||
#define VG_LOCK_ARGS_MINOR 0
|
|
||||||
#define VG_LOCK_ARGS_PATCH 0
|
|
||||||
|
|
||||||
static int dlm_has_lvb_bug;
|
|
||||||
|
|
||||||
static int cluster_name_from_args(char *vg_args, char *clustername)
|
|
||||||
{
|
|
||||||
return last_string_from_args(vg_args, clustername);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int check_args_version(char *vg_args)
|
|
||||||
{
|
|
||||||
unsigned int major = 0;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
rv = version_from_args(vg_args, &major, NULL, NULL);
|
|
||||||
if (rv < 0) {
|
|
||||||
log_error("check_args_version %s error %d", vg_args, rv);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (major > VG_LOCK_ARGS_MAJOR) {
|
|
||||||
log_error("check_args_version %s major %d %d", vg_args, major, VG_LOCK_ARGS_MAJOR);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This will be set after dlm_controld is started. */
|
|
||||||
#define DLM_CLUSTER_NAME_PATH "/sys/kernel/config/dlm/cluster/cluster_name"
|
|
||||||
|
|
||||||
static int read_cluster_name(char *clustername)
|
|
||||||
{
|
|
||||||
static const char close_error_msg[] = "read_cluster_name: close_error %d";
|
|
||||||
char *n;
|
|
||||||
int fd;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
if (daemon_test) {
|
|
||||||
sprintf(clustername, "%s", "test");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
fd = open(DLM_CLUSTER_NAME_PATH, O_RDONLY);
|
|
||||||
if (fd < 0) {
|
|
||||||
log_debug("read_cluster_name: open error %d, check dlm_controld", fd);
|
|
||||||
return fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = read(fd, clustername, MAX_ARGS);
|
|
||||||
if (rv < 0) {
|
|
||||||
log_error("read_cluster_name: cluster name read error %d, check dlm_controld", fd);
|
|
||||||
if (close(fd))
|
|
||||||
log_error(close_error_msg, fd);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
n = strstr(clustername, "\n");
|
|
||||||
if (n)
|
|
||||||
*n = '\0';
|
|
||||||
if (close(fd))
|
|
||||||
log_error(close_error_msg, fd);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lm_init_vg_dlm(char *ls_name, char *vg_name, uint32_t flags, char *vg_args)
|
|
||||||
{
|
|
||||||
char clustername[MAX_ARGS+1];
|
|
||||||
char lock_args_version[MAX_ARGS+1];
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
memset(clustername, 0, sizeof(clustername));
|
|
||||||
memset(lock_args_version, 0, sizeof(lock_args_version));
|
|
||||||
|
|
||||||
snprintf(lock_args_version, MAX_ARGS, "%u.%u.%u",
|
|
||||||
VG_LOCK_ARGS_MAJOR, VG_LOCK_ARGS_MINOR, VG_LOCK_ARGS_PATCH);
|
|
||||||
|
|
||||||
rv = read_cluster_name(clustername);
|
|
||||||
if (rv < 0)
|
|
||||||
return -EMANAGER;
|
|
||||||
|
|
||||||
if (strlen(clustername) + strlen(lock_args_version) + 2 > MAX_ARGS) {
|
|
||||||
log_error("init_vg_dlm args too long");
|
|
||||||
return -EARGS;
|
|
||||||
}
|
|
||||||
|
|
||||||
snprintf(vg_args, MAX_ARGS, "%s:%s", lock_args_version, clustername);
|
|
||||||
rv = 0;
|
|
||||||
|
|
||||||
log_debug("init_vg_dlm done %s vg_args %s", ls_name, vg_args);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lm_prepare_lockspace_dlm(struct lockspace *ls)
|
|
||||||
{
|
|
||||||
char sys_clustername[MAX_ARGS+1];
|
|
||||||
char arg_clustername[MAX_ARGS+1];
|
|
||||||
uint32_t major = 0, minor = 0, patch = 0;
|
|
||||||
struct lm_dlm *lmd;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
memset(sys_clustername, 0, sizeof(sys_clustername));
|
|
||||||
memset(arg_clustername, 0, sizeof(arg_clustername));
|
|
||||||
|
|
||||||
rv = read_cluster_name(sys_clustername);
|
|
||||||
if (rv < 0)
|
|
||||||
return -EMANAGER;
|
|
||||||
|
|
||||||
rv = dlm_kernel_version(&major, &minor, &patch);
|
|
||||||
if (rv < 0) {
|
|
||||||
log_error("prepare_lockspace_dlm kernel_version not detected %d", rv);
|
|
||||||
dlm_has_lvb_bug = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((major == 6) && (minor == 0) && (patch == 1)) {
|
|
||||||
log_debug("dlm kernel version %u.%u.%u has lvb bug", major, minor, patch);
|
|
||||||
dlm_has_lvb_bug = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ls->vg_args[0]) {
|
|
||||||
/* global lockspace has no vg args */
|
|
||||||
goto skip_args;
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = check_args_version(ls->vg_args);
|
|
||||||
if (rv < 0)
|
|
||||||
return -EARGS;
|
|
||||||
|
|
||||||
rv = cluster_name_from_args(ls->vg_args, arg_clustername);
|
|
||||||
if (rv < 0) {
|
|
||||||
log_error("prepare_lockspace_dlm %s no cluster name from args %s", ls->name, ls->vg_args);
|
|
||||||
return -EARGS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(sys_clustername, arg_clustername)) {
|
|
||||||
log_error("prepare_lockspace_dlm %s mismatching cluster names sys %s arg %s",
|
|
||||||
ls->name, sys_clustername, arg_clustername);
|
|
||||||
return -EARGS;
|
|
||||||
}
|
|
||||||
|
|
||||||
skip_args:
|
|
||||||
lmd = malloc(sizeof(struct lm_dlm));
|
|
||||||
if (!lmd)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
ls->lm_data = lmd;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lm_add_lockspace_dlm(struct lockspace *ls, int adopt)
|
|
||||||
{
|
|
||||||
struct lm_dlm *lmd = (struct lm_dlm *)ls->lm_data;
|
|
||||||
|
|
||||||
if (daemon_test)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (adopt)
|
|
||||||
lmd->dh = dlm_open_lockspace(ls->name);
|
|
||||||
else
|
|
||||||
lmd->dh = dlm_new_lockspace(ls->name, 0600, DLM_LSFL_NEWEXCL);
|
|
||||||
|
|
||||||
if (!lmd->dh) {
|
|
||||||
log_error("add_lockspace_dlm %s adopt %d error", ls->name, adopt);
|
|
||||||
free(lmd);
|
|
||||||
ls->lm_data = NULL;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lm_rem_lockspace_dlm(struct lockspace *ls, int free_vg)
|
|
||||||
{
|
|
||||||
struct lm_dlm *lmd = (struct lm_dlm *)ls->lm_data;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
if (daemon_test)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If free_vg is set, it means we are doing vgremove, and we may want
|
|
||||||
* to tell any other nodes to leave the lockspace. This is not really
|
|
||||||
* necessary since there should be no harm in having an unused
|
|
||||||
* lockspace sitting around. A new "notification lock" would need to
|
|
||||||
* be added with a callback to signal this.
|
|
||||||
*/
|
|
||||||
|
|
||||||
rv = dlm_release_lockspace(ls->name, lmd->dh, 1);
|
|
||||||
if (rv < 0) {
|
|
||||||
log_error("rem_lockspace_dlm error %d", rv);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
out:
|
|
||||||
free(lmd);
|
|
||||||
ls->lm_data = NULL;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int lm_add_resource_dlm(struct lockspace *ls, struct resource *r, int with_lock_nl)
|
|
||||||
{
|
|
||||||
struct lm_dlm *lmd = (struct lm_dlm *)ls->lm_data;
|
|
||||||
struct rd_dlm *rdd = (struct rd_dlm *)r->lm_data;
|
|
||||||
uint32_t flags = 0;
|
|
||||||
char *buf;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
if (r->type == LD_RT_GL || r->type == LD_RT_VG) {
|
|
||||||
buf = malloc(sizeof(struct val_blk) + DLM_LVB_LEN);
|
|
||||||
if (!buf)
|
|
||||||
return -ENOMEM;
|
|
||||||
memset(buf, 0, sizeof(struct val_blk) + DLM_LVB_LEN);
|
|
||||||
|
|
||||||
rdd->vb = (struct val_blk *)buf;
|
|
||||||
rdd->lksb.sb_lvbptr = buf + sizeof(struct val_blk);
|
|
||||||
|
|
||||||
flags |= LKF_VALBLK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!with_lock_nl)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
/* because this is a new NL lock request */
|
|
||||||
flags |= LKF_EXPEDITE;
|
|
||||||
|
|
||||||
if (daemon_test)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
rv = dlm_ls_lock_wait(lmd->dh, LKM_NLMODE, &rdd->lksb, flags,
|
|
||||||
r->name, strlen(r->name),
|
|
||||||
0, NULL, NULL, NULL);
|
|
||||||
if (rv < 0) {
|
|
||||||
log_error("S %s R %s add_resource_dlm lock error %d", ls->name, r->name, rv);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
out:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lm_rem_resource_dlm(struct lockspace *ls, struct resource *r)
|
|
||||||
{
|
|
||||||
struct lm_dlm *lmd = (struct lm_dlm *)ls->lm_data;
|
|
||||||
struct rd_dlm *rdd = (struct rd_dlm *)r->lm_data;
|
|
||||||
struct dlm_lksb *lksb;
|
|
||||||
int rv = 0;
|
|
||||||
|
|
||||||
if (daemon_test)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
lksb = &rdd->lksb;
|
|
||||||
|
|
||||||
if (!lksb->sb_lkid)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
rv = dlm_ls_unlock_wait(lmd->dh, lksb->sb_lkid, 0, lksb);
|
|
||||||
if (rv < 0) {
|
|
||||||
log_error("S %s R %s rem_resource_dlm unlock error %d", ls->name, r->name, rv);
|
|
||||||
}
|
|
||||||
out:
|
|
||||||
if (rdd->vb)
|
|
||||||
free(rdd->vb);
|
|
||||||
|
|
||||||
memset(rdd, 0, sizeof(struct rd_dlm));
|
|
||||||
r->lm_init = 0;
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int to_dlm_mode(int ld_mode)
|
|
||||||
{
|
|
||||||
switch (ld_mode) {
|
|
||||||
case LD_LK_EX:
|
|
||||||
return LKM_EXMODE;
|
|
||||||
case LD_LK_SH:
|
|
||||||
return LKM_PRMODE;
|
|
||||||
};
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int lm_adopt_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
|
|
||||||
struct val_blk *vb_out)
|
|
||||||
{
|
|
||||||
struct lm_dlm *lmd = (struct lm_dlm *)ls->lm_data;
|
|
||||||
struct rd_dlm *rdd = (struct rd_dlm *)r->lm_data;
|
|
||||||
struct dlm_lksb *lksb;
|
|
||||||
uint32_t flags = 0;
|
|
||||||
int mode;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
memset(vb_out, 0, sizeof(struct val_blk));
|
|
||||||
|
|
||||||
if (!r->lm_init) {
|
|
||||||
rv = lm_add_resource_dlm(ls, r, 0);
|
|
||||||
if (rv < 0)
|
|
||||||
return rv;
|
|
||||||
r->lm_init = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
lksb = &rdd->lksb;
|
|
||||||
|
|
||||||
flags |= LKF_PERSISTENT;
|
|
||||||
flags |= LKF_ORPHAN;
|
|
||||||
|
|
||||||
if (rdd->vb)
|
|
||||||
flags |= LKF_VALBLK;
|
|
||||||
|
|
||||||
mode = to_dlm_mode(ld_mode);
|
|
||||||
if (mode < 0) {
|
|
||||||
log_error("adopt_dlm invalid mode %d", ld_mode);
|
|
||||||
rv = -EINVAL;
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
log_debug("S %s R %s adopt_dlm", ls->name, r->name);
|
|
||||||
|
|
||||||
if (daemon_test)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* dlm returns 0 for success, -EAGAIN if an orphan is
|
|
||||||
* found with another mode, and -ENOENT if no orphan.
|
|
||||||
*
|
|
||||||
* cast/bast/param are (void *)1 because the kernel
|
|
||||||
* returns errors if some are null.
|
|
||||||
*/
|
|
||||||
|
|
||||||
rv = dlm_ls_lockx(lmd->dh, mode, lksb, flags,
|
|
||||||
r->name, strlen(r->name), 0,
|
|
||||||
(void *)1, (void *)1, (void *)1,
|
|
||||||
NULL, NULL);
|
|
||||||
|
|
||||||
if (rv == -1 && errno == -EAGAIN) {
|
|
||||||
log_debug("S %s R %s adopt_dlm adopt mode %d try other mode",
|
|
||||||
ls->name, r->name, ld_mode);
|
|
||||||
rv = -EUCLEAN;
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
if (rv < 0) {
|
|
||||||
log_debug("S %s R %s adopt_dlm mode %d flags %x error %d errno %d",
|
|
||||||
ls->name, r->name, mode, flags, rv, errno);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* FIXME: For GL/VG locks we probably want to read the lvb,
|
|
||||||
* especially if adopting an ex lock, because when we
|
|
||||||
* release this adopted ex lock we may want to write new
|
|
||||||
* lvb values based on the current lvb values (at lease
|
|
||||||
* in the GL case where we increment the current values.)
|
|
||||||
*
|
|
||||||
* It should be possible to read the lvb by requesting
|
|
||||||
* this lock in the same mode it's already in.
|
|
||||||
*/
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
|
|
||||||
fail:
|
|
||||||
lm_rem_resource_dlm(ls, r);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Use PERSISTENT so that if lvmlockd exits while holding locks,
|
|
||||||
* the locks will remain orphaned in the dlm, still protecting what
|
|
||||||
* they were acquired to protect.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int lm_lock_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
|
|
||||||
struct val_blk *vb_out, int adopt)
|
|
||||||
{
|
|
||||||
struct lm_dlm *lmd = (struct lm_dlm *)ls->lm_data;
|
|
||||||
struct rd_dlm *rdd = (struct rd_dlm *)r->lm_data;
|
|
||||||
struct dlm_lksb *lksb;
|
|
||||||
struct val_blk vb;
|
|
||||||
uint32_t flags = 0;
|
|
||||||
int mode;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
if (adopt) {
|
|
||||||
/* When adopting, we don't follow the normal method
|
|
||||||
of acquiring a NL lock then converting it to the
|
|
||||||
desired mode. */
|
|
||||||
return lm_adopt_dlm(ls, r, ld_mode, vb_out);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!r->lm_init) {
|
|
||||||
rv = lm_add_resource_dlm(ls, r, 1);
|
|
||||||
if (rv < 0)
|
|
||||||
return rv;
|
|
||||||
r->lm_init = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
lksb = &rdd->lksb;
|
|
||||||
|
|
||||||
flags |= LKF_CONVERT;
|
|
||||||
flags |= LKF_NOQUEUE;
|
|
||||||
flags |= LKF_PERSISTENT;
|
|
||||||
|
|
||||||
if (rdd->vb)
|
|
||||||
flags |= LKF_VALBLK;
|
|
||||||
|
|
||||||
mode = to_dlm_mode(ld_mode);
|
|
||||||
if (mode < 0) {
|
|
||||||
log_error("lock_dlm invalid mode %d", ld_mode);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
log_debug("S %s R %s lock_dlm", ls->name, r->name);
|
|
||||||
|
|
||||||
if (daemon_test) {
|
|
||||||
memset(vb_out, 0, sizeof(struct val_blk));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The dlm lvb bug means that converting NL->EX will not return
|
|
||||||
* the latest lvb, so we have to convert NL->PR->EX to reread it.
|
|
||||||
*/
|
|
||||||
if (dlm_has_lvb_bug && (ld_mode == LD_LK_EX)) {
|
|
||||||
rv = dlm_ls_lock_wait(lmd->dh, LKM_PRMODE, lksb, flags,
|
|
||||||
r->name, strlen(r->name),
|
|
||||||
0, NULL, NULL, NULL);
|
|
||||||
if (rv == -1) {
|
|
||||||
log_debug("S %s R %s lock_dlm acquire mode PR for %d rv %d",
|
|
||||||
ls->name, r->name, mode, rv);
|
|
||||||
goto lockrv;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fall through to request EX. */
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = dlm_ls_lock_wait(lmd->dh, mode, lksb, flags,
|
|
||||||
r->name, strlen(r->name),
|
|
||||||
0, NULL, NULL, NULL);
|
|
||||||
lockrv:
|
|
||||||
if (rv == -1 && errno == EAGAIN) {
|
|
||||||
log_debug("S %s R %s lock_dlm acquire mode %d rv EAGAIN", ls->name, r->name, mode);
|
|
||||||
return -EAGAIN;
|
|
||||||
}
|
|
||||||
if (rv < 0) {
|
|
||||||
log_error("S %s R %s lock_dlm acquire error %d errno %d", ls->name, r->name, rv, errno);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rdd->vb) {
|
|
||||||
if (lksb->sb_flags & DLM_SBF_VALNOTVALID) {
|
|
||||||
log_debug("S %s R %s lock_dlm VALNOTVALID", ls->name, r->name);
|
|
||||||
memset(rdd->vb, 0, sizeof(struct val_blk));
|
|
||||||
memset(vb_out, 0, sizeof(struct val_blk));
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 'vb' contains disk endian values, not host endian.
|
|
||||||
* It is copied directly to rdd->vb which is also kept
|
|
||||||
* in disk endian form.
|
|
||||||
* vb_out is returned to the caller in host endian form.
|
|
||||||
*/
|
|
||||||
memcpy(&vb, lksb->sb_lvbptr, sizeof(struct val_blk));
|
|
||||||
memcpy(rdd->vb, &vb, sizeof(vb));
|
|
||||||
|
|
||||||
vb_out->version = le16_to_cpu(vb.version);
|
|
||||||
vb_out->flags = le16_to_cpu(vb.flags);
|
|
||||||
vb_out->r_version = le32_to_cpu(vb.r_version);
|
|
||||||
}
|
|
||||||
out:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lm_convert_dlm(struct lockspace *ls, struct resource *r,
|
|
||||||
int ld_mode, uint32_t r_version)
|
|
||||||
{
|
|
||||||
struct lm_dlm *lmd = (struct lm_dlm *)ls->lm_data;
|
|
||||||
struct rd_dlm *rdd = (struct rd_dlm *)r->lm_data;
|
|
||||||
struct dlm_lksb *lksb = &rdd->lksb;
|
|
||||||
uint32_t mode;
|
|
||||||
uint32_t flags = 0;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
log_debug("S %s R %s convert_dlm", ls->name, r->name);
|
|
||||||
|
|
||||||
flags |= LKF_CONVERT;
|
|
||||||
flags |= LKF_NOQUEUE;
|
|
||||||
flags |= LKF_PERSISTENT;
|
|
||||||
|
|
||||||
if (rdd->vb && r_version && (r->mode == LD_LK_EX)) {
|
|
||||||
if (!rdd->vb->version) {
|
|
||||||
/* first time vb has been written */
|
|
||||||
rdd->vb->version = cpu_to_le16(VAL_BLK_VERSION);
|
|
||||||
}
|
|
||||||
rdd->vb->r_version = cpu_to_le32(r_version);
|
|
||||||
memcpy(lksb->sb_lvbptr, rdd->vb, sizeof(struct val_blk));
|
|
||||||
|
|
||||||
log_debug("S %s R %s convert_dlm set r_version %u",
|
|
||||||
ls->name, r->name, r_version);
|
|
||||||
|
|
||||||
flags |= LKF_VALBLK;
|
|
||||||
}
|
|
||||||
|
|
||||||
mode = to_dlm_mode(ld_mode);
|
|
||||||
|
|
||||||
if (daemon_test)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
rv = dlm_ls_lock_wait(lmd->dh, mode, lksb, flags,
|
|
||||||
r->name, strlen(r->name),
|
|
||||||
0, NULL, NULL, NULL);
|
|
||||||
if (rv == -1 && errno == EAGAIN) {
|
|
||||||
/* FIXME: When does this happen? Should something different be done? */
|
|
||||||
log_error("S %s R %s convert_dlm mode %d rv EAGAIN", ls->name, r->name, mode);
|
|
||||||
return -EAGAIN;
|
|
||||||
}
|
|
||||||
if (rv < 0) {
|
|
||||||
log_error("S %s R %s convert_dlm error %d", ls->name, r->name, rv);
|
|
||||||
}
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lm_unlock_dlm(struct lockspace *ls, struct resource *r,
|
|
||||||
uint32_t r_version, uint32_t lmu_flags)
|
|
||||||
{
|
|
||||||
struct lm_dlm *lmd = (struct lm_dlm *)ls->lm_data;
|
|
||||||
struct rd_dlm *rdd = (struct rd_dlm *)r->lm_data;
|
|
||||||
struct dlm_lksb *lksb = &rdd->lksb;
|
|
||||||
struct val_blk vb_prev;
|
|
||||||
struct val_blk vb_next;
|
|
||||||
uint32_t flags = 0;
|
|
||||||
int new_vb = 0;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Do not set PERSISTENT, because we don't need an orphan
|
|
||||||
* NL lock to protect anything.
|
|
||||||
*/
|
|
||||||
|
|
||||||
flags |= LKF_CONVERT;
|
|
||||||
|
|
||||||
if (rdd->vb && (r->mode == LD_LK_EX)) {
|
|
||||||
|
|
||||||
/* vb_prev and vb_next are in disk endian form */
|
|
||||||
memcpy(&vb_prev, rdd->vb, sizeof(struct val_blk));
|
|
||||||
memcpy(&vb_next, rdd->vb, sizeof(struct val_blk));
|
|
||||||
|
|
||||||
if (!vb_prev.version) {
|
|
||||||
vb_next.version = cpu_to_le16(VAL_BLK_VERSION);
|
|
||||||
new_vb = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((lmu_flags & LMUF_FREE_VG) && (r->type == LD_RT_VG)) {
|
|
||||||
vb_next.flags = cpu_to_le16(VBF_REMOVED);
|
|
||||||
new_vb = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (r_version) {
|
|
||||||
vb_next.r_version = cpu_to_le32(r_version);
|
|
||||||
new_vb = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (new_vb) {
|
|
||||||
memcpy(rdd->vb, &vb_next, sizeof(struct val_blk));
|
|
||||||
memcpy(lksb->sb_lvbptr, &vb_next, sizeof(struct val_blk));
|
|
||||||
|
|
||||||
log_debug("S %s R %s unlock_dlm vb old %x %x %u new %x %x %u",
|
|
||||||
ls->name, r->name,
|
|
||||||
le16_to_cpu(vb_prev.version),
|
|
||||||
le16_to_cpu(vb_prev.flags),
|
|
||||||
le32_to_cpu(vb_prev.r_version),
|
|
||||||
le16_to_cpu(vb_next.version),
|
|
||||||
le16_to_cpu(vb_next.flags),
|
|
||||||
le32_to_cpu(vb_next.r_version));
|
|
||||||
} else {
|
|
||||||
log_debug("S %s R %s unlock_dlm vb unchanged", ls->name, r->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
flags |= LKF_VALBLK;
|
|
||||||
} else {
|
|
||||||
log_debug("S %s R %s unlock_dlm", ls->name, r->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (daemon_test)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
rv = dlm_ls_lock_wait(lmd->dh, LKM_NLMODE, lksb, flags,
|
|
||||||
r->name, strlen(r->name),
|
|
||||||
0, NULL, NULL, NULL);
|
|
||||||
if (rv < 0) {
|
|
||||||
log_error("S %s R %s unlock_dlm error %d", ls->name, r->name, rv);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This list could be read from dlm_controld via libdlmcontrol,
|
|
||||||
* but it's simpler to get it from sysfs.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define DLM_LOCKSPACES_PATH "/sys/kernel/config/dlm/cluster/spaces"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* FIXME: this should be implemented differently.
|
|
||||||
* It's not nice to use an aspect of the dlm clustering
|
|
||||||
* implementation, which could change. It would be
|
|
||||||
* better to do something like use a special lock in the
|
|
||||||
* lockspace that was held PR by all nodes, and then an
|
|
||||||
* EX request on it could check if it's started (and
|
|
||||||
* possibly also notify others to stop it automatically).
|
|
||||||
* Or, possibly an enhancement to libdlm that would give
|
|
||||||
* info about lockspace members.
|
|
||||||
*
|
|
||||||
* (We could let the VG be removed while others still
|
|
||||||
* have the lockspace running, which largely works, but
|
|
||||||
* introduces problems if another VG with the same name is
|
|
||||||
* recreated while others still have the lockspace running
|
|
||||||
* for the previous VG. We'd also want a way to clean up
|
|
||||||
* the stale lockspaces on the others eventually.)
|
|
||||||
*/
|
|
||||||
|
|
||||||
int lm_hosts_dlm(struct lockspace *ls, int notify)
|
|
||||||
{
|
|
||||||
static const char closedir_err_msg[] = "lm_hosts_dlm: closedir failed";
|
|
||||||
char ls_nodes_path[PATH_MAX];
|
|
||||||
struct dirent *de;
|
|
||||||
DIR *ls_dir;
|
|
||||||
int count = 0;
|
|
||||||
|
|
||||||
memset(ls_nodes_path, 0, sizeof(ls_nodes_path));
|
|
||||||
snprintf(ls_nodes_path, PATH_MAX-1, "%s/%s/nodes",
|
|
||||||
DLM_LOCKSPACES_PATH, ls->name);
|
|
||||||
|
|
||||||
if (!(ls_dir = opendir(ls_nodes_path)))
|
|
||||||
return -ECONNREFUSED;
|
|
||||||
|
|
||||||
while ((de = readdir(ls_dir))) {
|
|
||||||
if (de->d_name[0] == '.')
|
|
||||||
continue;
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (closedir(ls_dir))
|
|
||||||
log_error(closedir_err_msg);
|
|
||||||
|
|
||||||
if (!count) {
|
|
||||||
log_error("lm_hosts_dlm found no nodes in %s", ls_nodes_path);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Assume that a count of one node represents ourself,
|
|
||||||
* and any value over one represents other nodes.
|
|
||||||
*/
|
|
||||||
|
|
||||||
return count - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lm_get_lockspaces_dlm(struct list_head *ls_rejoin)
|
|
||||||
{
|
|
||||||
static const char closedir_err_msg[] = "lm_get_lockspace_dlm: closedir failed";
|
|
||||||
struct lockspace *ls;
|
|
||||||
struct dirent *de;
|
|
||||||
DIR *ls_dir;
|
|
||||||
|
|
||||||
if (!(ls_dir = opendir(DLM_LOCKSPACES_PATH)))
|
|
||||||
return -ECONNREFUSED;
|
|
||||||
|
|
||||||
while ((de = readdir(ls_dir))) {
|
|
||||||
if (de->d_name[0] == '.')
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (strncmp(de->d_name, LVM_LS_PREFIX, strlen(LVM_LS_PREFIX)))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!(ls = alloc_lockspace())) {
|
|
||||||
if (closedir(ls_dir))
|
|
||||||
log_error(closedir_err_msg);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
ls->lm_type = LD_LM_DLM;
|
|
||||||
strncpy(ls->name, de->d_name, MAX_NAME);
|
|
||||||
strncpy(ls->vg_name, ls->name + strlen(LVM_LS_PREFIX), MAX_NAME);
|
|
||||||
list_add_tail(&ls->list, ls_rejoin);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (closedir(ls_dir))
|
|
||||||
log_error(closedir_err_msg);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lm_is_running_dlm(void)
|
|
||||||
{
|
|
||||||
char sys_clustername[MAX_ARGS+1];
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
memset(sys_clustername, 0, sizeof(sys_clustername));
|
|
||||||
|
|
||||||
rv = read_cluster_name(sys_clustername);
|
|
||||||
if (rv < 0)
|
|
||||||
return 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,587 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2014-2015 Red Hat, Inc.
|
|
||||||
*
|
|
||||||
* This file is part of LVM2.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use,
|
|
||||||
* modify, copy, or redistribute it subject to the terms and conditions
|
|
||||||
* of the GNU Lesser General Public License v.2.1.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _LVM_LVMLOCKD_INTERNAL_H
|
|
||||||
#define _LVM_LVMLOCKD_INTERNAL_H
|
|
||||||
|
|
||||||
#define MAX_NAME 64
|
|
||||||
#define MAX_ARGS 64
|
|
||||||
|
|
||||||
#define R_NAME_GL_DISABLED "_GLLK_disabled"
|
|
||||||
#define R_NAME_GL "GLLK"
|
|
||||||
#define R_NAME_VG "VGLK"
|
|
||||||
#define S_NAME_GL_DLM "lvm_global"
|
|
||||||
#define LVM_LS_PREFIX "lvm_" /* ls name is prefix + vg_name */
|
|
||||||
/* global lockspace name for sanlock is a vg name */
|
|
||||||
|
|
||||||
/* lock manager types */
|
|
||||||
enum {
|
|
||||||
LD_LM_NONE = 0,
|
|
||||||
LD_LM_UNUSED = 1, /* place holder so values match lib/locking/lvmlockd.h */
|
|
||||||
LD_LM_DLM = 2,
|
|
||||||
LD_LM_SANLOCK = 3,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* operation types */
|
|
||||||
enum {
|
|
||||||
LD_OP_HELLO = 1,
|
|
||||||
LD_OP_QUIT,
|
|
||||||
LD_OP_INIT,
|
|
||||||
LD_OP_FREE,
|
|
||||||
LD_OP_START,
|
|
||||||
LD_OP_STOP,
|
|
||||||
LD_OP_LOCK,
|
|
||||||
LD_OP_UPDATE,
|
|
||||||
LD_OP_CLOSE,
|
|
||||||
LD_OP_ENABLE,
|
|
||||||
LD_OP_DISABLE,
|
|
||||||
LD_OP_START_WAIT,
|
|
||||||
LD_OP_STOP_ALL,
|
|
||||||
LD_OP_DUMP_INFO,
|
|
||||||
LD_OP_DUMP_LOG,
|
|
||||||
LD_OP_RENAME_BEFORE,
|
|
||||||
LD_OP_RENAME_FINAL,
|
|
||||||
LD_OP_RUNNING_LM,
|
|
||||||
LD_OP_FIND_FREE_LOCK,
|
|
||||||
LD_OP_KILL_VG,
|
|
||||||
LD_OP_DROP_VG,
|
|
||||||
LD_OP_BUSY,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* resource types */
|
|
||||||
enum {
|
|
||||||
LD_RT_GL = 1,
|
|
||||||
LD_RT_VG,
|
|
||||||
LD_RT_LV,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* lock modes, more restrictive must be larger value */
|
|
||||||
enum {
|
|
||||||
LD_LK_IV = -1,
|
|
||||||
LD_LK_UN = 0,
|
|
||||||
LD_LK_NL = 1,
|
|
||||||
LD_LK_SH = 2,
|
|
||||||
LD_LK_EX = 3,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct list_head {
|
|
||||||
struct list_head *next, *prev;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct client {
|
|
||||||
struct list_head list;
|
|
||||||
pthread_mutex_t mutex;
|
|
||||||
int pid;
|
|
||||||
int fd;
|
|
||||||
int pi;
|
|
||||||
uint32_t id;
|
|
||||||
unsigned int recv : 1;
|
|
||||||
unsigned int dead : 1;
|
|
||||||
unsigned int poll_ignore : 1;
|
|
||||||
unsigned int lock_ops : 1;
|
|
||||||
char name[MAX_NAME+1];
|
|
||||||
};
|
|
||||||
|
|
||||||
#define LD_AF_PERSISTENT 0x00000001
|
|
||||||
#define LD_AF_NO_CLIENT 0x00000002
|
|
||||||
#define LD_AF_UNLOCK_CANCEL 0x00000004
|
|
||||||
#define LD_AF_NEXT_VERSION 0x00000008
|
|
||||||
#define LD_AF_WAIT 0x00000010
|
|
||||||
#define LD_AF_FORCE 0x00000020
|
|
||||||
#define LD_AF_EX_DISABLE 0x00000040
|
|
||||||
#define LD_AF_ENABLE 0x00000080
|
|
||||||
#define LD_AF_DISABLE 0x00000100
|
|
||||||
#define LD_AF_SEARCH_LS 0x00000200
|
|
||||||
#define LD_AF_WAIT_STARTING 0x00001000
|
|
||||||
#define LD_AF_DUP_GL_LS 0x00002000
|
|
||||||
#define LD_AF_ADOPT 0x00010000
|
|
||||||
#define LD_AF_WARN_GL_REMOVED 0x00020000
|
|
||||||
#define LD_AF_LV_LOCK 0x00040000
|
|
||||||
#define LD_AF_LV_UNLOCK 0x00080000
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Number of times to repeat a lock request after
|
|
||||||
* a lock conflict (-EAGAIN) if unspecified in the
|
|
||||||
* request.
|
|
||||||
*/
|
|
||||||
#define DEFAULT_MAX_RETRIES 4
|
|
||||||
|
|
||||||
struct action {
|
|
||||||
struct list_head list;
|
|
||||||
uint32_t client_id;
|
|
||||||
uint32_t flags; /* LD_AF_ */
|
|
||||||
uint32_t version;
|
|
||||||
uint64_t host_id;
|
|
||||||
int8_t op; /* operation type LD_OP_ */
|
|
||||||
int8_t rt; /* resource type LD_RT_ */
|
|
||||||
int8_t mode; /* lock mode LD_LK_ */
|
|
||||||
int8_t lm_type; /* lock manager: LM_DLM, LM_SANLOCK */
|
|
||||||
int retries;
|
|
||||||
int max_retries;
|
|
||||||
int result;
|
|
||||||
int lm_rv; /* return value from lm_ function */
|
|
||||||
char vg_uuid[64];
|
|
||||||
char vg_name[MAX_NAME+1];
|
|
||||||
char lv_name[MAX_NAME+1];
|
|
||||||
char lv_uuid[MAX_NAME+1];
|
|
||||||
char vg_args[MAX_ARGS+1];
|
|
||||||
char lv_args[MAX_ARGS+1];
|
|
||||||
char vg_sysid[MAX_NAME+1];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct resource {
|
|
||||||
struct list_head list; /* lockspace.resources */
|
|
||||||
char name[MAX_NAME+1]; /* vg name or lv name */
|
|
||||||
int8_t type; /* resource type LD_RT_ */
|
|
||||||
int8_t mode;
|
|
||||||
unsigned int sh_count; /* number of sh locks on locks list */
|
|
||||||
uint32_t version;
|
|
||||||
uint32_t last_client_id; /* last client_id to lock or unlock resource */
|
|
||||||
unsigned int lm_init : 1; /* lm_data is initialized */
|
|
||||||
unsigned int adopt : 1; /* temp flag in remove_inactive_lvs */
|
|
||||||
unsigned int version_zero_valid : 1;
|
|
||||||
unsigned int use_vb : 1;
|
|
||||||
struct list_head locks;
|
|
||||||
struct list_head actions;
|
|
||||||
char lv_args[MAX_ARGS+1];
|
|
||||||
char lm_data[0]; /* lock manager specific data */
|
|
||||||
};
|
|
||||||
|
|
||||||
#define LD_LF_PERSISTENT 0x00000001
|
|
||||||
|
|
||||||
struct lock {
|
|
||||||
struct list_head list; /* resource.locks */
|
|
||||||
int8_t mode; /* lock mode LD_LK_ */
|
|
||||||
uint32_t version;
|
|
||||||
uint32_t flags; /* LD_LF_ */
|
|
||||||
uint32_t client_id; /* may be 0 for persistent or internal locks */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct lockspace {
|
|
||||||
struct list_head list; /* lockspaces */
|
|
||||||
char name[MAX_NAME+1];
|
|
||||||
char vg_name[MAX_NAME+1];
|
|
||||||
char vg_uuid[64];
|
|
||||||
char vg_args[MAX_ARGS+1]; /* lock manager specific args */
|
|
||||||
char vg_sysid[MAX_NAME+1];
|
|
||||||
int8_t lm_type; /* lock manager: LM_DLM, LM_SANLOCK */
|
|
||||||
void *lm_data;
|
|
||||||
uint64_t host_id;
|
|
||||||
uint64_t free_lock_offset; /* start search for free lock here */
|
|
||||||
|
|
||||||
uint32_t start_client_id; /* client_id that started the lockspace */
|
|
||||||
pthread_t thread; /* makes synchronous lock requests */
|
|
||||||
pthread_cond_t cond;
|
|
||||||
pthread_mutex_t mutex;
|
|
||||||
unsigned int create_fail : 1;
|
|
||||||
unsigned int create_done : 1;
|
|
||||||
unsigned int thread_work : 1;
|
|
||||||
unsigned int thread_stop : 1;
|
|
||||||
unsigned int thread_done : 1;
|
|
||||||
unsigned int sanlock_gl_enabled: 1;
|
|
||||||
unsigned int sanlock_gl_dup: 1;
|
|
||||||
unsigned int free_vg: 1;
|
|
||||||
unsigned int kill_vg: 1;
|
|
||||||
unsigned int drop_vg: 1;
|
|
||||||
|
|
||||||
struct list_head actions; /* new client actions */
|
|
||||||
struct list_head resources; /* resource/lock state for gl/vg/lv */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* val_blk version */
|
|
||||||
#define VAL_BLK_VERSION 0x0101
|
|
||||||
|
|
||||||
/* val_blk flags */
|
|
||||||
#define VBF_REMOVED 0x0001
|
|
||||||
|
|
||||||
struct val_blk {
|
|
||||||
uint16_t version;
|
|
||||||
uint16_t flags;
|
|
||||||
uint32_t r_version;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* lm_unlock flags */
|
|
||||||
#define LMUF_FREE_VG 0x00000001
|
|
||||||
|
|
||||||
#define container_of(ptr, type, member) ({ \
|
|
||||||
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
|
|
||||||
(type *)( (char *)__mptr - offsetof(type,member) );})
|
|
||||||
|
|
||||||
static inline void INIT_LIST_HEAD(struct list_head *list)
|
|
||||||
{
|
|
||||||
list->next = list;
|
|
||||||
list->prev = list;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void __list_add(struct list_head *new,
|
|
||||||
struct list_head *prev,
|
|
||||||
struct list_head *next)
|
|
||||||
{
|
|
||||||
next->prev = new;
|
|
||||||
new->next = next;
|
|
||||||
new->prev = prev;
|
|
||||||
prev->next = new;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void __list_del(struct list_head *prev, struct list_head *next)
|
|
||||||
{
|
|
||||||
next->prev = prev;
|
|
||||||
prev->next = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void list_add(struct list_head *new, struct list_head *head)
|
|
||||||
{
|
|
||||||
__list_add(new, head, head->next);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void list_add_tail(struct list_head *new, struct list_head *head)
|
|
||||||
{
|
|
||||||
__list_add(new, head->prev, head);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void list_del(struct list_head *entry)
|
|
||||||
{
|
|
||||||
__list_del(entry->prev, entry->next);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int list_empty(const struct list_head *head)
|
|
||||||
{
|
|
||||||
return head->next == head;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define list_entry(ptr, type, member) \
|
|
||||||
container_of(ptr, type, member)
|
|
||||||
|
|
||||||
#define list_first_entry(ptr, type, member) \
|
|
||||||
list_entry((ptr)->next, type, member)
|
|
||||||
|
|
||||||
#define list_for_each_entry(pos, head, member) \
|
|
||||||
for (pos = list_entry((head)->next, typeof(*pos), member); \
|
|
||||||
&pos->member != (head); \
|
|
||||||
pos = list_entry(pos->member.next, typeof(*pos), member))
|
|
||||||
|
|
||||||
#define list_for_each_entry_safe(pos, n, head, member) \
|
|
||||||
for (pos = list_entry((head)->next, typeof(*pos), member), \
|
|
||||||
n = list_entry(pos->member.next, typeof(*pos), member); \
|
|
||||||
&pos->member != (head); \
|
|
||||||
pos = n, n = list_entry(n->member.next, typeof(*n), member))
|
|
||||||
|
|
||||||
|
|
||||||
/* to improve readability */
|
|
||||||
#define WAIT 1
|
|
||||||
#define NO_WAIT 0
|
|
||||||
#define FORCE 1
|
|
||||||
#define NO_FORCE 0
|
|
||||||
|
|
||||||
/*
|
|
||||||
* global variables
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef EXTERN
|
|
||||||
#define EXTERN extern
|
|
||||||
#define INIT(X)
|
|
||||||
#else
|
|
||||||
#undef EXTERN
|
|
||||||
#define EXTERN
|
|
||||||
#define INIT(X) =X
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* gl_type_static and gl_use_ are set by command line or config file
|
|
||||||
* to specify whether the global lock comes from dlm or sanlock.
|
|
||||||
* Without a static setting, lvmlockd will figure out where the
|
|
||||||
* global lock should be (but it could get mixed up in cases where
|
|
||||||
* both sanlock and dlm vgs exist.)
|
|
||||||
*
|
|
||||||
* gl_use_dlm means that the gl should come from lockspace gl_lsname_dlm
|
|
||||||
* gl_use_sanlock means that the gl should come from lockspace gl_lsname_sanlock
|
|
||||||
*
|
|
||||||
* gl_use_dlm has precedence over gl_use_sanlock, so if a node sees both
|
|
||||||
* dlm and sanlock vgs, it will use the dlm gl.
|
|
||||||
*
|
|
||||||
* gl_use_ is set when the first evidence of that lm_type is seen
|
|
||||||
* in any command.
|
|
||||||
*
|
|
||||||
* gl_lsname_sanlock is set when the first vg is seen in which an
|
|
||||||
* enabled gl is exists, or when init_vg creates a vg with gl enabled,
|
|
||||||
* or when enable_gl is used.
|
|
||||||
*
|
|
||||||
* gl_lsname_sanlock is cleared when free_vg deletes a vg with gl enabled
|
|
||||||
* or when disable_gl matches.
|
|
||||||
*/
|
|
||||||
|
|
||||||
EXTERN int gl_type_static;
|
|
||||||
EXTERN int gl_use_dlm;
|
|
||||||
EXTERN int gl_use_sanlock;
|
|
||||||
EXTERN char gl_lsname_dlm[MAX_NAME+1];
|
|
||||||
EXTERN char gl_lsname_sanlock[MAX_NAME+1];
|
|
||||||
EXTERN int global_dlm_lockspace_exists;
|
|
||||||
|
|
||||||
EXTERN int daemon_test; /* run as much as possible without a live lock manager */
|
|
||||||
EXTERN int daemon_debug;
|
|
||||||
EXTERN int daemon_host_id;
|
|
||||||
EXTERN const char *daemon_host_id_file;
|
|
||||||
EXTERN int sanlock_io_timeout;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This flag is set to 1 if we see multiple vgs with the global
|
|
||||||
* lock enabled. While this is set, we return a special flag
|
|
||||||
* with the vg lock result indicating to the lvm command that
|
|
||||||
* there is a duplicate gl in the vg which should be resolved.
|
|
||||||
* While this is set, find_lockspace_name has the side job of
|
|
||||||
* counting the number of lockspaces with enabled gl's so that
|
|
||||||
* this can be set back to zero when the duplicates are disabled.
|
|
||||||
*/
|
|
||||||
EXTERN int sanlock_gl_dup;
|
|
||||||
|
|
||||||
void log_level(int level, const char *fmt, ...) __attribute__((format(printf, 2, 3)));
|
|
||||||
#define log_debug(fmt, args...) log_level(LOG_DEBUG, fmt, ##args)
|
|
||||||
#define log_error(fmt, args...) log_level(LOG_ERR, fmt, ##args)
|
|
||||||
#define log_warn(fmt, args...) log_level(LOG_WARNING, fmt, ##args)
|
|
||||||
|
|
||||||
struct lockspace *alloc_lockspace(void);
|
|
||||||
int lockspaces_empty(void);
|
|
||||||
int last_string_from_args(char *args_in, char *last);
|
|
||||||
int version_from_args(char *args, unsigned int *major, unsigned int *minor, unsigned int *patch);
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef LOCKDDLM_SUPPORT
|
|
||||||
|
|
||||||
int lm_init_vg_dlm(char *ls_name, char *vg_name, uint32_t flags, char *vg_args);
|
|
||||||
int lm_prepare_lockspace_dlm(struct lockspace *ls);
|
|
||||||
int lm_add_lockspace_dlm(struct lockspace *ls, int adopt);
|
|
||||||
int lm_rem_lockspace_dlm(struct lockspace *ls, int free_vg);
|
|
||||||
int lm_lock_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
|
|
||||||
struct val_blk *vb_out, int adopt);
|
|
||||||
int lm_convert_dlm(struct lockspace *ls, struct resource *r,
|
|
||||||
int ld_mode, uint32_t r_version);
|
|
||||||
int lm_unlock_dlm(struct lockspace *ls, struct resource *r,
|
|
||||||
uint32_t r_version, uint32_t lmu_flags);
|
|
||||||
int lm_rem_resource_dlm(struct lockspace *ls, struct resource *r);
|
|
||||||
int lm_get_lockspaces_dlm(struct list_head *ls_rejoin);
|
|
||||||
int lm_data_size_dlm(void);
|
|
||||||
int lm_is_running_dlm(void);
|
|
||||||
int lm_hosts_dlm(struct lockspace *ls, int notify);
|
|
||||||
|
|
||||||
static inline int lm_support_dlm(void)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
static inline int lm_init_vg_dlm(char *ls_name, char *vg_name, uint32_t flags, char *vg_args)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int lm_prepare_lockspace_dlm(struct lockspace *ls)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int lm_add_lockspace_dlm(struct lockspace *ls, int adopt)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int lm_rem_lockspace_dlm(struct lockspace *ls, int free_vg)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int lm_lock_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
|
|
||||||
struct val_blk *vb_out, int adopt)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int lm_convert_dlm(struct lockspace *ls, struct resource *r,
|
|
||||||
int ld_mode, uint32_t r_version)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int lm_unlock_dlm(struct lockspace *ls, struct resource *r,
|
|
||||||
uint32_t r_version, uint32_t lmu_flags)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int lm_rem_resource_dlm(struct lockspace *ls, struct resource *r)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int lm_get_lockspaces_dlm(struct list_head *ls_rejoin)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int lm_data_size_dlm(void)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int lm_is_running_dlm(void)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int lm_support_dlm(void)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int lm_hosts_dlm(struct lockspace *ls, int notify)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* dlm support */
|
|
||||||
|
|
||||||
#ifdef LOCKDSANLOCK_SUPPORT
|
|
||||||
|
|
||||||
int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_args);
|
|
||||||
int lm_init_lv_sanlock(char *ls_name, char *vg_name, char *lv_name, char *vg_args, char *lv_args, uint64_t free_offset);
|
|
||||||
int lm_free_lv_sanlock(struct lockspace *ls, struct resource *r);
|
|
||||||
int lm_rename_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_args);
|
|
||||||
int lm_prepare_lockspace_sanlock(struct lockspace *ls);
|
|
||||||
int lm_add_lockspace_sanlock(struct lockspace *ls, int adopt);
|
|
||||||
int lm_rem_lockspace_sanlock(struct lockspace *ls, int free_vg);
|
|
||||||
int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
|
|
||||||
struct val_blk *vb_out, int *retry, int adopt);
|
|
||||||
int lm_convert_sanlock(struct lockspace *ls, struct resource *r,
|
|
||||||
int ld_mode, uint32_t r_version);
|
|
||||||
int lm_unlock_sanlock(struct lockspace *ls, struct resource *r,
|
|
||||||
uint32_t r_version, uint32_t lmu_flags);
|
|
||||||
int lm_able_gl_sanlock(struct lockspace *ls, int enable);
|
|
||||||
int lm_ex_disable_gl_sanlock(struct lockspace *ls);
|
|
||||||
int lm_hosts_sanlock(struct lockspace *ls, int notify);
|
|
||||||
int lm_rem_resource_sanlock(struct lockspace *ls, struct resource *r);
|
|
||||||
int lm_gl_is_enabled(struct lockspace *ls);
|
|
||||||
int lm_get_lockspaces_sanlock(struct list_head *ls_rejoin);
|
|
||||||
int lm_data_size_sanlock(void);
|
|
||||||
int lm_is_running_sanlock(void);
|
|
||||||
int lm_find_free_lock_sanlock(struct lockspace *ls, uint64_t *free_offset);
|
|
||||||
|
|
||||||
static inline int lm_support_sanlock(void)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
static inline int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_args)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int lm_init_lv_sanlock(char *ls_name, char *vg_name, char *lv_name, char *vg_args, char *lv_args, uint64_t free_offset)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int lm_free_lv_sanlock(struct lockspace *ls, struct resource *r)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int lm_rename_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_args)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int lm_prepare_lockspace_sanlock(struct lockspace *ls)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int lm_add_lockspace_sanlock(struct lockspace *ls, int adopt)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int lm_rem_lockspace_sanlock(struct lockspace *ls, int free_vg)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
|
|
||||||
struct val_blk *vb_out, int *retry, int adopt)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int lm_convert_sanlock(struct lockspace *ls, struct resource *r,
|
|
||||||
int ld_mode, uint32_t r_version)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int lm_unlock_sanlock(struct lockspace *ls, struct resource *r,
|
|
||||||
uint32_t r_version, uint32_t lmu_flags)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int lm_able_gl_sanlock(struct lockspace *ls, int enable)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int lm_ex_disable_gl_sanlock(struct lockspace *ls)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int lm_hosts_sanlock(struct lockspace *ls, int notify)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int lm_rem_resource_sanlock(struct lockspace *ls, struct resource *r)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int lm_gl_is_enabled(struct lockspace *ls)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int lm_get_lockspaces_sanlock(struct list_head *ls_rejoin)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int lm_data_size_sanlock(void)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int lm_is_running_sanlock(void)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int lm_find_free_lock_sanlock(struct lockspace *ls, uint64_t *free_offset)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int lm_support_sanlock(void)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* sanlock support */
|
|
||||||
|
|
||||||
#endif /* _LVM_LVMLOCKD_INTERNAL_H */
|
|
||||||
File diff suppressed because it is too large
Load Diff
1
daemons/lvmpolld/.gitignore
vendored
1
daemons/lvmpolld/.gitignore
vendored
@@ -1 +0,0 @@
|
|||||||
lvmpolld
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user