mirror of
git://sourceware.org/git/lvm2.git
synced 2025-10-23 23:33:15 +03:00
Compare commits
1537 Commits
dev-dct-de
...
v2_01_10
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 |
147
.gitignore
vendored
147
.gitignore
vendored
@@ -1,147 +0,0 @@
|
|||||||
*.5
|
|
||||||
*.7
|
|
||||||
*.8
|
|
||||||
*.8_gen
|
|
||||||
*.a
|
|
||||||
*.d
|
|
||||||
*.o
|
|
||||||
*.orig
|
|
||||||
*.pc
|
|
||||||
*.pot
|
|
||||||
*.pyc
|
|
||||||
*.pyo
|
|
||||||
*.rej
|
|
||||||
*.so
|
|
||||||
*.so.*
|
|
||||||
*.sw*
|
|
||||||
*~
|
|
||||||
|
|
||||||
.export.sym
|
|
||||||
.exported_symbols_generated
|
|
||||||
.gdb_history
|
|
||||||
|
|
||||||
Makefile
|
|
||||||
make.tmpl
|
|
||||||
|
|
||||||
/autom4te.cache/
|
|
||||||
/autoscan.log
|
|
||||||
/build/
|
|
||||||
/config.cache
|
|
||||||
/config.log
|
|
||||||
/config.status
|
|
||||||
/configure.scan
|
|
||||||
/cscope.*
|
|
||||||
/html/
|
|
||||||
/python/
|
|
||||||
/reports/
|
|
||||||
/tags
|
|
||||||
/tmp/
|
|
||||||
|
|
||||||
coverity/coverity_model.xml
|
|
||||||
|
|
||||||
# gcov files:
|
|
||||||
*.gcda
|
|
||||||
*.gcno
|
|
||||||
|
|
||||||
tools/man-generator
|
|
||||||
tools/man-generator.c
|
|
||||||
|
|
||||||
test/.lib-dir-stamp
|
|
||||||
test/.tests-stamp
|
|
||||||
test/lib/dmsecuretest
|
|
||||||
test/lib/lvchange
|
|
||||||
test/lib/lvconvert
|
|
||||||
test/lib/lvcreate
|
|
||||||
test/lib/lvdisplay
|
|
||||||
test/lib/lvextend
|
|
||||||
test/lib/lvmconfig
|
|
||||||
test/lib/lvmdiskscan
|
|
||||||
test/lib/lvmsadc
|
|
||||||
test/lib/lvmsar
|
|
||||||
test/lib/lvreduce
|
|
||||||
test/lib/lvremove
|
|
||||||
test/lib/lvrename
|
|
||||||
test/lib/lvresize
|
|
||||||
test/lib/lvs
|
|
||||||
test/lib/lvscan
|
|
||||||
test/lib/pvchange
|
|
||||||
test/lib/pvck
|
|
||||||
test/lib/pvcreate
|
|
||||||
test/lib/pvdisplay
|
|
||||||
test/lib/pvmove
|
|
||||||
test/lib/pvremove
|
|
||||||
test/lib/pvresize
|
|
||||||
test/lib/pvs
|
|
||||||
test/lib/pvscan
|
|
||||||
test/lib/securetest
|
|
||||||
test/lib/vgcfgbackup
|
|
||||||
test/lib/vgcfgrestore
|
|
||||||
test/lib/vgchange
|
|
||||||
test/lib/vgck
|
|
||||||
test/lib/vgconvert
|
|
||||||
test/lib/vgcreate
|
|
||||||
test/lib/vgdisplay
|
|
||||||
test/lib/vgexport
|
|
||||||
test/lib/vgextend
|
|
||||||
test/lib/vgimport
|
|
||||||
test/lib/vgimportclone
|
|
||||||
test/lib/vgmerge
|
|
||||||
test/lib/vgmknodes
|
|
||||||
test/lib/vgreduce
|
|
||||||
test/lib/vgremove
|
|
||||||
test/lib/vgrename
|
|
||||||
test/lib/vgs
|
|
||||||
test/lib/vgscan
|
|
||||||
test/lib/vgsplit
|
|
||||||
test/api/lvtest.t
|
|
||||||
test/api/pe_start.t
|
|
||||||
test/api/percent.t
|
|
||||||
test/api/python_lvm_unit.py
|
|
||||||
test/api/test
|
|
||||||
test/api/thin_percent.t
|
|
||||||
test/api/vglist.t
|
|
||||||
test/api/vgtest.t
|
|
||||||
test/lib/aux
|
|
||||||
test/lib/check
|
|
||||||
test/lib/clvmd
|
|
||||||
test/lib/dm-version-expected
|
|
||||||
test/lib/dmeventd
|
|
||||||
test/lib/dmsetup
|
|
||||||
test/lib/dmstats
|
|
||||||
test/lib/fail
|
|
||||||
test/lib/flavour-ndev-cluster
|
|
||||||
test/lib/flavour-ndev-cluster-lvmpolld
|
|
||||||
test/lib/flavour-ndev-lvmetad
|
|
||||||
test/lib/flavour-ndev-lvmetad-lvmpolld
|
|
||||||
test/lib/flavour-ndev-lvmpolld
|
|
||||||
test/lib/flavour-ndev-vanilla
|
|
||||||
test/lib/flavour-udev-cluster
|
|
||||||
test/lib/flavour-udev-cluster-lvmpolld
|
|
||||||
test/lib/flavour-udev-lvmetad
|
|
||||||
test/lib/flavour-udev-lvmetad-lvmpolld
|
|
||||||
test/lib/flavour-udev-lvmlockd-dlm
|
|
||||||
test/lib/flavour-udev-lvmlockd-sanlock
|
|
||||||
test/lib/flavour-udev-lvmlockd-test
|
|
||||||
test/lib/flavour-udev-lvmpolld
|
|
||||||
test/lib/flavour-udev-vanilla
|
|
||||||
test/lib/fsadm
|
|
||||||
test/lib/get
|
|
||||||
test/lib/inittest
|
|
||||||
test/lib/invalid
|
|
||||||
test/lib/lvm
|
|
||||||
test/lib/lvm-wrapper
|
|
||||||
test/lib/lvmchange
|
|
||||||
test/lib/lvmdbusd.profile
|
|
||||||
test/lib/lvmetad
|
|
||||||
test/lib/lvmpolld
|
|
||||||
test/lib/not
|
|
||||||
test/lib/paths
|
|
||||||
test/lib/paths-common
|
|
||||||
test/lib/runner
|
|
||||||
test/lib/should
|
|
||||||
test/lib/test
|
|
||||||
test/lib/thin-performance.profile
|
|
||||||
test/lib/utils
|
|
||||||
test/lib/version-expected
|
|
||||||
test/unit/dmraid_t.c
|
|
||||||
test/unit/unit-test
|
|
||||||
4
COPYING
4
COPYING
@@ -2,7 +2,7 @@
|
|||||||
Version 2, June 1991
|
Version 2, June 1991
|
||||||
|
|
||||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
of this license document, but changing it is not allowed.
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
@@ -305,7 +305,7 @@ the "copyright" line and a pointer to where the full notice is found.
|
|||||||
|
|
||||||
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, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|||||||
25
COPYING.BSD
25
COPYING.BSD
@@ -1,25 +0,0 @@
|
|||||||
BSD 2-Clause License
|
|
||||||
|
|
||||||
Copyright (c) 2014, Red Hat, Inc.
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice, this
|
|
||||||
list of conditions and the following disclaimer.
|
|
||||||
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
this list of conditions and the following disclaimer in the documentation
|
|
||||||
and/or other materials provided with the distribution.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
||||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
||||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
||||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
||||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
203
COPYING.LIB
203
COPYING.LIB
@@ -1,14 +1,14 @@
|
|||||||
GNU LESSER GENERAL PUBLIC LICENSE
|
|
||||||
Version 2.1, February 1999
|
|
||||||
|
|
||||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1991 Free Software Foundation, Inc.
|
||||||
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
of this license document, but changing it is not allowed.
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
[This is the first released version of the Lesser GPL. It also counts
|
[This is the first released version of the library GPL. It is
|
||||||
as the successor of the GNU Library Public License, version 2, hence
|
numbered 2 because it goes with version 2 of the ordinary GPL.]
|
||||||
the version number 2.1.]
|
|
||||||
|
|
||||||
Preamble
|
Preamble
|
||||||
|
|
||||||
@@ -17,109 +17,97 @@ freedom to share and change it. By contrast, the GNU General Public
|
|||||||
Licenses are intended to guarantee your freedom to share and change
|
Licenses are intended to guarantee your freedom to share and change
|
||||||
free software--to make sure the software is free for all its users.
|
free software--to make sure the software is free for all its users.
|
||||||
|
|
||||||
This license, the Lesser General Public License, applies to some
|
This license, the Library General Public License, applies to some
|
||||||
specially designated software packages--typically libraries--of the
|
specially designated Free Software Foundation software, and to any
|
||||||
Free Software Foundation and other authors who decide to use it. You
|
other libraries whose authors decide to use it. You can use it for
|
||||||
can use it too, but we suggest you first think carefully about whether
|
your libraries, too.
|
||||||
this license or the ordinary General Public License is the better
|
|
||||||
strategy to use in any particular case, based on the explanations below.
|
|
||||||
|
|
||||||
When we speak of free software, we are referring to freedom of use,
|
When we speak of free software, we are referring to freedom, not
|
||||||
not price. Our General Public Licenses are designed to make sure that
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
you have the freedom to distribute copies of free software (and charge
|
have the freedom to distribute copies of free software (and charge for
|
||||||
for this service if you wish); that you receive source code or can get
|
this service if you wish), that you receive source code or can get it
|
||||||
it if you want it; that you can change the software and use pieces of
|
if you want it, that you can change the software or use pieces of it
|
||||||
it in new free programs; and that you are informed that you can do
|
in new free programs; and that you know you can do these things.
|
||||||
these things.
|
|
||||||
|
|
||||||
To protect your rights, we need to make restrictions that forbid
|
To protect your rights, we need to make restrictions that forbid
|
||||||
distributors to deny you these rights or to ask you to surrender these
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
rights. These restrictions translate to certain responsibilities for
|
These restrictions translate to certain responsibilities for you if
|
||||||
you if you distribute copies of the library or if you modify it.
|
you distribute copies of the library, or if you modify it.
|
||||||
|
|
||||||
For example, if you distribute copies of the library, whether gratis
|
For example, if you distribute copies of the library, whether gratis
|
||||||
or for a fee, you must give the recipients all the rights that we gave
|
or for a fee, you must give the recipients all the rights that we gave
|
||||||
you. You must make sure that they, too, receive or can get the source
|
you. You must make sure that they, too, receive or can get the source
|
||||||
code. If you link other code with the library, you must provide
|
code. If you link a program with the library, you must provide
|
||||||
complete object files to the recipients, so that they can relink them
|
complete object files to the recipients so that they can relink them
|
||||||
with the library after making changes to the library and recompiling
|
with the library, after making changes to the library and recompiling
|
||||||
it. And you must show them these terms so they know their rights.
|
it. And you must show them these terms so they know their rights.
|
||||||
|
|
||||||
We protect your rights with a two-step method: (1) we copyright the
|
Our method of protecting your rights has two steps: (1) copyright
|
||||||
library, and (2) we offer you this license, which gives you legal
|
the library, and (2) offer you this license which gives you legal
|
||||||
permission to copy, distribute and/or modify the library.
|
permission to copy, distribute and/or modify the library.
|
||||||
|
|
||||||
To protect each distributor, we want to make it very clear that
|
Also, for each distributor's protection, we want to make certain
|
||||||
there is no warranty for the free library. Also, if the library is
|
that everyone understands that there is no warranty for this free
|
||||||
modified by someone else and passed on, the recipients should know
|
library. If the library is modified by someone else and passed on, we
|
||||||
that what they have is not the original version, so that the original
|
want its recipients to know that what they have is not the original
|
||||||
author's reputation will not be affected by problems that might be
|
version, so that any problems introduced by others will not reflect on
|
||||||
introduced by others.
|
the original authors' reputations.
|
||||||
|
|
||||||
Finally, software patents pose a constant threat to the existence of
|
Finally, any free program is threatened constantly by software
|
||||||
any free program. We wish to make sure that a company cannot
|
patents. We wish to avoid the danger that companies distributing free
|
||||||
effectively restrict the users of a free program by obtaining a
|
software will individually obtain patent licenses, thus in effect
|
||||||
restrictive license from a patent holder. Therefore, we insist that
|
transforming the program into proprietary software. To prevent this,
|
||||||
any patent license obtained for a version of the library must be
|
we have made it clear that any patent must be licensed for everyone's
|
||||||
consistent with the full freedom of use specified in this license.
|
free use or not licensed at all.
|
||||||
|
|
||||||
Most GNU software, including some libraries, is covered by the
|
Most GNU software, including some libraries, is covered by the ordinary
|
||||||
ordinary GNU General Public License. This license, the GNU Lesser
|
GNU General Public License, which was designed for utility programs. This
|
||||||
General Public License, applies to certain designated libraries, and
|
license, the GNU Library General Public License, applies to certain
|
||||||
is quite different from the ordinary General Public License. We use
|
designated libraries. This license is quite different from the ordinary
|
||||||
this license for certain libraries in order to permit linking those
|
one; be sure to read it in full, and don't assume that anything in it is
|
||||||
libraries into non-free programs.
|
the same as in the ordinary license.
|
||||||
|
|
||||||
When a program is linked with a library, whether statically or using
|
The reason we have a separate public license for some libraries is that
|
||||||
a shared library, the combination of the two is legally speaking a
|
they blur the distinction we usually make between modifying or adding to a
|
||||||
combined work, a derivative of the original library. The ordinary
|
program and simply using it. Linking a program with a library, without
|
||||||
General Public License therefore permits such linking only if the
|
changing the library, is in some sense simply using the library, and is
|
||||||
entire combination fits its criteria of freedom. The Lesser General
|
analogous to running a utility program or application program. However, in
|
||||||
Public License permits more lax criteria for linking other code with
|
a textual and legal sense, the linked executable is a combined work, a
|
||||||
the library.
|
derivative of the original library, and the ordinary General Public License
|
||||||
|
treats it as such.
|
||||||
|
|
||||||
We call this license the "Lesser" General Public License because it
|
Because of this blurred distinction, using the ordinary General
|
||||||
does Less to protect the user's freedom than the ordinary General
|
Public License for libraries did not effectively promote software
|
||||||
Public License. It also provides other free software developers Less
|
sharing, because most developers did not use the libraries. We
|
||||||
of an advantage over competing non-free programs. These disadvantages
|
concluded that weaker conditions might promote sharing better.
|
||||||
are the reason we use the ordinary General Public License for many
|
|
||||||
libraries. However, the Lesser license provides advantages in certain
|
|
||||||
special circumstances.
|
|
||||||
|
|
||||||
For example, on rare occasions, there may be a special need to
|
However, unrestricted linking of non-free programs would deprive the
|
||||||
encourage the widest possible use of a certain library, so that it becomes
|
users of those programs of all benefit from the free status of the
|
||||||
a de-facto standard. To achieve this, non-free programs must be
|
libraries themselves. This Library General Public License is intended to
|
||||||
allowed to use the library. A more frequent case is that a free
|
permit developers of non-free programs to use free libraries, while
|
||||||
library does the same job as widely used non-free libraries. In this
|
preserving your freedom as a user of such programs to change the free
|
||||||
case, there is little to gain by limiting the free library to free
|
libraries that are incorporated in them. (We have not seen how to achieve
|
||||||
software only, so we use the Lesser General Public License.
|
this as regards changes in header files, but we have achieved it as regards
|
||||||
|
changes in the actual functions of the Library.) The hope is that this
|
||||||
In other cases, permission to use a particular library in non-free
|
will lead to faster development of free libraries.
|
||||||
programs enables a greater number of people to use a large body of
|
|
||||||
free software. For example, permission to use the GNU C Library in
|
|
||||||
non-free programs enables many more people to use the whole GNU
|
|
||||||
operating system, as well as its variant, the GNU/Linux operating
|
|
||||||
system.
|
|
||||||
|
|
||||||
Although the Lesser General Public License is Less protective of the
|
|
||||||
users' freedom, it does ensure that the user of a program that is
|
|
||||||
linked with the Library has the freedom and the wherewithal to run
|
|
||||||
that program using a modified version of the Library.
|
|
||||||
|
|
||||||
The precise terms and conditions for copying, distribution and
|
The precise terms and conditions for copying, distribution and
|
||||||
modification follow. Pay close attention to the difference between a
|
modification follow. Pay close attention to the difference between a
|
||||||
"work based on the library" and a "work that uses the library". The
|
"work based on the library" and a "work that uses the library". The
|
||||||
former contains code derived from the library, whereas the latter must
|
former contains code derived from the library, while the latter only
|
||||||
be combined with the library in order to run.
|
works together with the library.
|
||||||
|
|
||||||
|
Note that it is possible for a library to be covered by the ordinary
|
||||||
|
General Public License rather than by this special one.
|
||||||
|
|
||||||
GNU LESSER GENERAL PUBLIC LICENSE
|
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
0. This License Agreement applies to any software library or other
|
0. This License Agreement applies to any software library which
|
||||||
program which contains a notice placed by the copyright holder or
|
contains a notice placed by the copyright holder or other authorized
|
||||||
other authorized party saying it may be distributed under the terms of
|
party saying it may be distributed under the terms of this Library
|
||||||
this Lesser General Public License (also called "this License").
|
General Public License (also called "this License"). Each licensee is
|
||||||
Each licensee is addressed as "you".
|
addressed as "you".
|
||||||
|
|
||||||
A "library" means a collection of software functions and/or data
|
A "library" means a collection of software functions and/or data
|
||||||
prepared so as to be conveniently linked with application programs
|
prepared so as to be conveniently linked with application programs
|
||||||
@@ -268,7 +256,7 @@ distribute the object code for the work under the terms of Section 6.
|
|||||||
Any executables containing that work also fall under Section 6,
|
Any executables containing that work also fall under Section 6,
|
||||||
whether or not they are linked directly with the Library itself.
|
whether or not they are linked directly with the Library itself.
|
||||||
|
|
||||||
6. As an exception to the Sections above, you may also combine or
|
6. As an exception to the Sections above, you may also compile or
|
||||||
link a "work that uses the Library" with the Library to produce a
|
link a "work that uses the Library" with the Library to produce a
|
||||||
work containing portions of the Library, and distribute that work
|
work containing portions of the Library, and distribute that work
|
||||||
under terms of your choice, provided that the terms permit
|
under terms of your choice, provided that the terms permit
|
||||||
@@ -295,31 +283,23 @@ of these things:
|
|||||||
Library will not necessarily be able to recompile the application
|
Library will not necessarily be able to recompile the application
|
||||||
to use the modified definitions.)
|
to use the modified definitions.)
|
||||||
|
|
||||||
b) Use a suitable shared library mechanism for linking with the
|
b) Accompany the work with a written offer, valid for at
|
||||||
Library. A suitable mechanism is one that (1) uses at run time a
|
|
||||||
copy of the library already present on the user's computer system,
|
|
||||||
rather than copying library functions into the executable, and (2)
|
|
||||||
will operate properly with a modified version of the library, if
|
|
||||||
the user installs one, as long as the modified version is
|
|
||||||
interface-compatible with the version that the work was made with.
|
|
||||||
|
|
||||||
c) Accompany the work with a written offer, valid for at
|
|
||||||
least three years, to give the same user the materials
|
least three years, to give the same user the materials
|
||||||
specified in Subsection 6a, above, for a charge no more
|
specified in Subsection 6a, above, for a charge no more
|
||||||
than the cost of performing this distribution.
|
than the cost of performing this distribution.
|
||||||
|
|
||||||
d) If distribution of the work is made by offering access to copy
|
c) If distribution of the work is made by offering access to copy
|
||||||
from a designated place, offer equivalent access to copy the above
|
from a designated place, offer equivalent access to copy the above
|
||||||
specified materials from the same place.
|
specified materials from the same place.
|
||||||
|
|
||||||
e) Verify that the user has already received a copy of these
|
d) Verify that the user has already received a copy of these
|
||||||
materials or that you have already sent this user a copy.
|
materials or that you have already sent this user a copy.
|
||||||
|
|
||||||
For an executable, the required form of the "work that uses the
|
For an executable, the required form of the "work that uses the
|
||||||
Library" must include any data and utility programs needed for
|
Library" must include any data and utility programs needed for
|
||||||
reproducing the executable from it. However, as a special exception,
|
reproducing the executable from it. However, as a special exception,
|
||||||
the materials to be distributed need not include anything that is
|
the source code distributed need not include anything that is normally
|
||||||
normally distributed (in either source or binary form) with the major
|
distributed (in either source or binary form) with the major
|
||||||
components (compiler, kernel, and so on) of the operating system on
|
components (compiler, kernel, and so on) of the operating system on
|
||||||
which the executable runs, unless that component itself accompanies
|
which the executable runs, unless that component itself accompanies
|
||||||
the executable.
|
the executable.
|
||||||
@@ -368,7 +348,7 @@ Library), the recipient automatically receives a license from the
|
|||||||
original licensor to copy, distribute, link with or modify the Library
|
original licensor to copy, distribute, link with or modify the Library
|
||||||
subject to these terms and conditions. You may not impose any further
|
subject to these terms and conditions. You may not impose any further
|
||||||
restrictions on the recipients' exercise of the rights granted herein.
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
You are not responsible for enforcing compliance by third parties with
|
You are not responsible for enforcing compliance by third parties to
|
||||||
this License.
|
this License.
|
||||||
|
|
||||||
11. If, as a consequence of a court judgment or allegation of patent
|
11. If, as a consequence of a court judgment or allegation of patent
|
||||||
@@ -411,7 +391,7 @@ excluded. In such case, this License incorporates the limitation as if
|
|||||||
written in the body of this License.
|
written in the body of this License.
|
||||||
|
|
||||||
13. The Free Software Foundation may publish revised and/or new
|
13. The Free Software Foundation may publish revised and/or new
|
||||||
versions of the Lesser General Public License from time to time.
|
versions of the Library General Public License from time to time.
|
||||||
Such new versions will be similar in spirit to the present version,
|
Such new versions will be similar in spirit to the present version,
|
||||||
but may differ in detail to address new problems or concerns.
|
but may differ in detail to address new problems or concerns.
|
||||||
|
|
||||||
@@ -457,7 +437,7 @@ DAMAGES.
|
|||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
How to Apply These Terms to Your New Libraries
|
Appendix: How to Apply These Terms to Your New Libraries
|
||||||
|
|
||||||
If you develop a new library, and you want it to be of the greatest
|
If you develop a new library, and you want it to be of the greatest
|
||||||
possible use to the public, we recommend making it free software that
|
possible use to the public, we recommend making it free software that
|
||||||
@@ -474,18 +454,19 @@ convey the exclusion of warranty; and each file should have at least the
|
|||||||
Copyright (C) <year> <name of author>
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
This library is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU Lesser General Public
|
modify it under the terms of the GNU Library General Public
|
||||||
License as published by the Free Software Foundation; either
|
License as published by the Free Software Foundation; either
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
version 2 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
This library is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
Lesser General Public License for more details.
|
Library General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
You should have received a copy of the GNU Library General Public
|
||||||
License along with this library; if not, write to the Free Software
|
License along with this library; if not, write to the Free
|
||||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||||
|
MA 02111-1307, USA
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
@@ -500,5 +481,3 @@ necessary. Here is a sample; alter the names:
|
|||||||
Ty Coon, President of Vice
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
That's all there is to it!
|
That's all there is to it!
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
34
INSTALL
34
INSTALL
@@ -1,30 +1,44 @@
|
|||||||
Installation
|
LVM2 installation
|
||||||
============
|
=================
|
||||||
|
|
||||||
1) Generate custom makefiles.
|
1) Install device-mapper
|
||||||
|
|
||||||
|
Ensure the device-mapper has been installed on the machine.
|
||||||
|
|
||||||
|
The device-mapper should be in the kernel (look for 'device-mapper'
|
||||||
|
messages in the kernel logs) and /usr/include/libdevmapper.h
|
||||||
|
and libdevmapper.so should be present.
|
||||||
|
|
||||||
|
The device-mapper is available from:
|
||||||
|
ftp://ftp.sistina.com/pub/LVM2/device-mapper/
|
||||||
|
|
||||||
|
|
||||||
|
2) Generate custom makefiles.
|
||||||
|
|
||||||
Run the 'configure' script from the top directory.
|
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.
|
||||||
|
|||||||
195
Makefile.in
195
Makefile.in
@@ -1,8 +1,8 @@
|
|||||||
#
|
#
|
||||||
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||||
# Copyright (C) 2004-2018 Red Hat, Inc. All rights reserved.
|
# Copyright (C) 2004 Red Hat, Inc. All rights reserved.
|
||||||
#
|
#
|
||||||
# This file is part of LVM2.
|
# This file is part of the LVM2.
|
||||||
#
|
#
|
||||||
# This copyrighted material is made available to anyone wishing to use,
|
# This copyrighted material is made available to anyone wishing to use,
|
||||||
# modify, copy, or redistribute it subject to the terms and conditions
|
# modify, copy, or redistribute it subject to the terms and conditions
|
||||||
@@ -10,57 +10,37 @@
|
|||||||
#
|
#
|
||||||
# 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, write to the Free Software Foundation,
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
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 = libdm conf daemons include lib libdaemon man scripts tools
|
SUBDIRS = doc include man
|
||||||
|
|
||||||
ifeq ("@UDEV_RULES@", "yes")
|
|
||||||
SUBDIRS += udev
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ("@INTL@", "yes")
|
ifeq ("@INTL@", "yes")
|
||||||
SUBDIRS += po
|
SUBDIRS += po
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(MAKECMDGOALS),clean)
|
SUBDIRS += lib tools daemons
|
||||||
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 \
|
lib/format1 \
|
||||||
udev po
|
lib/format_pool \
|
||||||
tools.distclean: test.distclean
|
lib/locking \
|
||||||
|
lib/mirror \
|
||||||
|
lib/snapshot \
|
||||||
|
po \
|
||||||
|
test/mm test/device test/format1 test/regex test/filters
|
||||||
endif
|
endif
|
||||||
DISTCLEAN_DIRS += lcov_reports*
|
|
||||||
DISTCLEAN_TARGETS += config.cache config.log config.status make.tmpl
|
|
||||||
|
|
||||||
include make.tmpl
|
include make.tmpl
|
||||||
|
|
||||||
include $(top_srcdir)/base/Makefile
|
daemons: lib
|
||||||
include $(top_srcdir)/device_mapper/Makefile
|
lib: include
|
||||||
include $(top_srcdir)/test/unit/Makefile
|
tools: lib
|
||||||
|
|
||||||
lib: libdaemon $(BASE_TARGET) $(DEVICE_MAPPER_TARGET)
|
|
||||||
daemons: lib libdaemon tools
|
|
||||||
scripts: lib
|
|
||||||
tools: lib libdaemon
|
|
||||||
po: tools daemons
|
po: tools daemons
|
||||||
man: tools
|
|
||||||
all_man: tools
|
|
||||||
test: tools daemons
|
|
||||||
unit-test run-unit-test: test
|
|
||||||
|
|
||||||
daemons.device-mapper: libdm.device-mapper
|
|
||||||
tools.device-mapper: libdm.device-mapper
|
|
||||||
device-mapper: tools.device-mapper daemons.device-mapper man.device-mapper
|
|
||||||
device_mapper: device-mapper
|
|
||||||
|
|
||||||
ifeq ("@INTL@", "yes")
|
ifeq ("@INTL@", "yes")
|
||||||
lib.pofile: include.pofile
|
lib.pofile: include.pofile
|
||||||
@@ -70,142 +50,3 @@ po.pofile: tools.pofile daemons.pofile
|
|||||||
pofile: po.pofile
|
pofile: po.pofile
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ("$(CFLOW_CMD)", "")
|
|
||||||
tools.cflow: libdm.cflow lib.cflow
|
|
||||||
daemons.cflow: tools.cflow
|
|
||||||
cflow: include.cflow
|
|
||||||
endif
|
|
||||||
|
|
||||||
CSCOPE_DIRS = base daemons device_mapper include lib libdaemon scripts tools libdm test
|
|
||||||
ifneq ("@CSCOPE_CMD@", "")
|
|
||||||
cscope.out:
|
|
||||||
@CSCOPE_CMD@ -b -R $(patsubst %,-s%,$(addprefix $(srcdir)/,$(CSCOPE_DIRS)))
|
|
||||||
all: cscope.out
|
|
||||||
endif
|
|
||||||
DISTCLEAN_TARGETS += cscope.out
|
|
||||||
CLEAN_DIRS += autom4te.cache
|
|
||||||
|
|
||||||
check check_system check_cluster check_local check_lvmpolld check_lvmlockd_test check_lvmlockd_dlm check_lvmlockd_sanlock: test
|
|
||||||
$(MAKE) -C test $(@)
|
|
||||||
|
|
||||||
conf.generate man.generate: tools
|
|
||||||
|
|
||||||
# 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
|
|
||||||
V=$(V) rpmbuild -v --define "_topdir $(rpmbuilddir)" -ba $(top_srcdir)/spec/lvm2.spec
|
|
||||||
|
|
||||||
generate: conf.generate man.generate
|
|
||||||
$(MAKE) -C conf generate
|
|
||||||
$(MAKE) -C man 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
|
|
||||||
|
|
||||||
install_tmpfiles_configuration:
|
|
||||||
$(MAKE) -C scripts install_tmpfiles_configuration
|
|
||||||
|
|
||||||
help:
|
|
||||||
@echo -e "\nAvailable targets:"
|
|
||||||
@echo " all Default target."
|
|
||||||
@echo " all_man Build all man pages with generators."
|
|
||||||
@echo " clean Remove all compile files."
|
|
||||||
@echo " device-mapper Device mapper part of lvm2."
|
|
||||||
@echo " dist Generate distributable file."
|
|
||||||
@echo " distclean Remove all build files."
|
|
||||||
@echo " generate Generate man pages for sources."
|
|
||||||
@echo " help Display callable targets."
|
|
||||||
@echo " install Install all files."
|
|
||||||
@echo " install_all_man Install all man pages."
|
|
||||||
@echo " install_cluster Install cmirrord."
|
|
||||||
@echo " install_device-mapper Install device mapper files."
|
|
||||||
@echo " install_initscripts Install initialization scripts."
|
|
||||||
@echo " install_lvm2 Install lvm2 files."
|
|
||||||
@echo " install_systemd_units Install systemd units."
|
|
||||||
@echo " lcov Generate lcov output."
|
|
||||||
@echo " lcov-dated Generate lcov with timedate suffix."
|
|
||||||
@echo " lcov-reset Reset lcov counters"
|
|
||||||
@echo " man Build man pages."
|
|
||||||
@echo " rpm Build rpm."
|
|
||||||
@echo " run-unit-test Run unit tests."
|
|
||||||
@echo " tags Generate c/etags."
|
|
||||||
|
|
||||||
ifneq ("$(LCOV)", "")
|
|
||||||
.PHONY: lcov-reset lcov lcov-dated
|
|
||||||
|
|
||||||
ifeq ($(MAKECMDGOALS),lcov-dated)
|
|
||||||
LCOV_REPORTS_DIR := lcov_reports-$(shell date +%Y%m%d%k%M%S)
|
|
||||||
lcov-dated: lcov
|
|
||||||
else
|
|
||||||
LCOV_REPORTS_DIR := lcov_reports
|
|
||||||
endif
|
|
||||||
|
|
||||||
lcov-reset:
|
|
||||||
$(LCOV) --zerocounters --directory $(top_builddir)
|
|
||||||
|
|
||||||
ifneq ("$(GENHTML)", "")
|
|
||||||
lcov:
|
|
||||||
$(RM) -rf $(LCOV_REPORTS_DIR)
|
|
||||||
$(MKDIR_P) $(LCOV_REPORTS_DIR)
|
|
||||||
$(LCOV) --capture --directory $(top_builddir) --ignore-errors source \
|
|
||||||
--output-file $(LCOV_REPORTS_DIR)/out.info
|
|
||||||
-test ! -s $(LCOV_REPORTS_DIR)/out.info || \
|
|
||||||
$(GENHTML) -o $(LCOV_REPORTS_DIR) --ignore-errors source \
|
|
||||||
$(LCOV_REPORTS_DIR)/out.info
|
|
||||||
endif
|
|
||||||
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifneq ($(shell which ctags 2>/dev/null),)
|
|
||||||
.PHONY: tags
|
|
||||||
tags:
|
|
||||||
test -z "$(shell find $(addprefix $(top_srcdir)/,$(CSCOPE_DIRS)) -type f -name '*.[ch]' -newer tags 2>/dev/null | head -1)" || $(RM) tags
|
|
||||||
test -f tags || find $(addprefix $(top_srcdir)/,$(CSCOPE_DIRS)) -maxdepth 5 -type f -name '*.[ch]' -exec ctags -a '{}' +
|
|
||||||
|
|
||||||
CLEAN_TARGETS += tags
|
|
||||||
endif
|
|
||||||
|
|||||||
50
README
50
README
@@ -1,51 +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.
|
||||||
|
|
||||||
This is development branch, for stable 2.02 release see stable-2.02 branch.
|
The device-mapper needs to be installed before compiling these LVM2 tools.
|
||||||
|
|
||||||
For more information about LVM2 read the changelog in the WHATS_NEW file.
|
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://sourceware.org/pub/lvm2/
|
ftp://sources.redhat.com/pub/lvm2/
|
||||||
https://github.com/lvmteam/lvm2/releases
|
ftp://sources.redhat.com/pub/dm/
|
||||||
|
|
||||||
The source code is stored in git:
|
To access the CVS tree use:
|
||||||
https://sourceware.org/git/?p=lvm2.git
|
cvs -d :pserver:cvs@sources.redhat.com:/cvs/lvm2 login
|
||||||
git clone git://sourceware.org/git/lvm2.git
|
CVS password: cvs
|
||||||
mirrored to:
|
cvs -d :pserver:cvs@sources.redhat.com:/cvs/lvm2 co LVM2
|
||||||
https://github.com/lvmteam/lvm2
|
|
||||||
git clone https://github.com/lvmteam/lvm2.git
|
|
||||||
git clone git@github.com:lvmteam/lvm2.git
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
Website:
|
|
||||||
https://sourceware.org/lvm2/
|
|
||||||
|
|
||||||
Report upstream bugs at:
|
|
||||||
https://bugzilla.redhat.com/enter_bug.cgi?product=LVM%20and%20device-mapper
|
|
||||||
or open issues at:
|
|
||||||
https://github.com/lvmteam/lvm2/issues
|
|
||||||
|
|
||||||
The source code repository used until 7th June 2012 is accessible using CVS:
|
|
||||||
|
|
||||||
cvs -d :pserver:cvs@sourceware.org:/cvs/lvm2 login cvs
|
|
||||||
cvs -d :pserver:cvs@sourceware.org:/cvs/lvm2 checkout LVM2
|
|
||||||
|
|
||||||
The password is cvs.
|
|
||||||
|
|||||||
62
TESTING
62
TESTING
@@ -1,62 +0,0 @@
|
|||||||
LVM2 Test Suite
|
|
||||||
===============
|
|
||||||
|
|
||||||
The codebase contains many tests in the test subdirectory.
|
|
||||||
|
|
||||||
Before running tests
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
Keep in mind the testsuite MUST run under root user.
|
|
||||||
|
|
||||||
It is recommended not to use LVM on the test machine, especially when running
|
|
||||||
tests with udev (`make check_system`.)
|
|
||||||
|
|
||||||
You MUST disable (or mask) any LVM daemons:
|
|
||||||
|
|
||||||
- lvmetad
|
|
||||||
- dmeventd
|
|
||||||
- lvmpolld
|
|
||||||
- lvmdbusd
|
|
||||||
- lvmlockd
|
|
||||||
- clvmd
|
|
||||||
- cmirrord
|
|
||||||
|
|
||||||
For running cluster tests, we are using singlenode locking. Pass
|
|
||||||
`--with-clvmd=singlenode` to configure.
|
|
||||||
|
|
||||||
NOTE: This is useful only for testing, and should not be used in produciton
|
|
||||||
code.
|
|
||||||
|
|
||||||
To run D-Bus daemon tests, existing D-Bus session is required.
|
|
||||||
|
|
||||||
Running tests
|
|
||||||
-------------
|
|
||||||
|
|
||||||
As root run:
|
|
||||||
|
|
||||||
make check
|
|
||||||
|
|
||||||
To run only tests matching a string:
|
|
||||||
|
|
||||||
make check T=test
|
|
||||||
|
|
||||||
To skip tests matching a string:
|
|
||||||
|
|
||||||
make check S=test
|
|
||||||
|
|
||||||
There are other targets and many environment variables can be used to tweak the
|
|
||||||
testsuite - for full list and description run `make -C test help`.
|
|
||||||
|
|
||||||
Installing testsuite
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
It is possible to install and run a testsuite against installed LVM. Run the
|
|
||||||
following:
|
|
||||||
|
|
||||||
make -C test install
|
|
||||||
|
|
||||||
Then lvm2-testsuite binary can be executed to test installed binaries.
|
|
||||||
|
|
||||||
See `lvm2-testsuite --help` for options. The same environment variables can be
|
|
||||||
used as with `make check`.
|
|
||||||
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
1.02.185-git (2022-02-07)
|
|
||||||
1408
WHATS_NEW_DM
1408
WHATS_NEW_DM
File diff suppressed because it is too large
Load Diff
234
acinclude.m4
234
acinclude.m4
@@ -1,234 +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
|
|
||||||
])
|
|
||||||
|
|
||||||
# ===========================================================================
|
|
||||||
# http://www.gnu.org/software/autoconf-archive/ax_gcc_builtin.html
|
|
||||||
# ===========================================================================
|
|
||||||
#
|
|
||||||
# SYNOPSIS
|
|
||||||
#
|
|
||||||
# AX_GCC_BUILTIN(BUILTIN)
|
|
||||||
#
|
|
||||||
# DESCRIPTION
|
|
||||||
#
|
|
||||||
# This macro checks if the compiler supports one of GCC's built-in
|
|
||||||
# functions; many other compilers also provide those same built-ins.
|
|
||||||
#
|
|
||||||
# The BUILTIN parameter is the name of the built-in function.
|
|
||||||
#
|
|
||||||
# If BUILTIN is supported define HAVE_<BUILTIN>. Keep in mind that since
|
|
||||||
# builtins usually start with two underscores they will be copied over
|
|
||||||
# into the HAVE_<BUILTIN> definition (e.g. HAVE___BUILTIN_EXPECT for
|
|
||||||
# __builtin_expect()).
|
|
||||||
#
|
|
||||||
# The macro caches its result in the ax_cv_have_<BUILTIN> variable (e.g.
|
|
||||||
# ax_cv_have___builtin_expect).
|
|
||||||
#
|
|
||||||
# The macro currently supports the following built-in functions:
|
|
||||||
#
|
|
||||||
# __builtin_assume_aligned
|
|
||||||
# __builtin_bswap16
|
|
||||||
# __builtin_bswap32
|
|
||||||
# __builtin_bswap64
|
|
||||||
# __builtin_choose_expr
|
|
||||||
# __builtin___clear_cache
|
|
||||||
# __builtin_clrsb
|
|
||||||
# __builtin_clrsbl
|
|
||||||
# __builtin_clrsbll
|
|
||||||
# __builtin_clz
|
|
||||||
# __builtin_clzl
|
|
||||||
# __builtin_clzll
|
|
||||||
# __builtin_complex
|
|
||||||
# __builtin_constant_p
|
|
||||||
# __builtin_ctz
|
|
||||||
# __builtin_ctzl
|
|
||||||
# __builtin_ctzll
|
|
||||||
# __builtin_expect
|
|
||||||
# __builtin_ffs
|
|
||||||
# __builtin_ffsl
|
|
||||||
# __builtin_ffsll
|
|
||||||
# __builtin_fpclassify
|
|
||||||
# __builtin_huge_val
|
|
||||||
# __builtin_huge_valf
|
|
||||||
# __builtin_huge_vall
|
|
||||||
# __builtin_inf
|
|
||||||
# __builtin_infd128
|
|
||||||
# __builtin_infd32
|
|
||||||
# __builtin_infd64
|
|
||||||
# __builtin_inff
|
|
||||||
# __builtin_infl
|
|
||||||
# __builtin_isinf_sign
|
|
||||||
# __builtin_nan
|
|
||||||
# __builtin_nand128
|
|
||||||
# __builtin_nand32
|
|
||||||
# __builtin_nand64
|
|
||||||
# __builtin_nanf
|
|
||||||
# __builtin_nanl
|
|
||||||
# __builtin_nans
|
|
||||||
# __builtin_nansf
|
|
||||||
# __builtin_nansl
|
|
||||||
# __builtin_object_size
|
|
||||||
# __builtin_parity
|
|
||||||
# __builtin_parityl
|
|
||||||
# __builtin_parityll
|
|
||||||
# __builtin_popcount
|
|
||||||
# __builtin_popcountl
|
|
||||||
# __builtin_popcountll
|
|
||||||
# __builtin_powi
|
|
||||||
# __builtin_powif
|
|
||||||
# __builtin_powil
|
|
||||||
# __builtin_prefetch
|
|
||||||
# __builtin_trap
|
|
||||||
# __builtin_types_compatible_p
|
|
||||||
# __builtin_unreachable
|
|
||||||
#
|
|
||||||
# Unsuppored built-ins will be tested with an empty parameter set and the
|
|
||||||
# result of the check might be wrong or meaningless so use with care.
|
|
||||||
#
|
|
||||||
# LICENSE
|
|
||||||
#
|
|
||||||
# Copyright (c) 2013 Gabriele Svelto <gabriele.svelto@gmail.com>
|
|
||||||
#
|
|
||||||
# Copying and distribution of this file, with or without modification, are
|
|
||||||
# permitted in any medium without royalty provided the copyright notice
|
|
||||||
# and this notice are preserved. This file is offered as-is, without any
|
|
||||||
# warranty.
|
|
||||||
|
|
||||||
serial 3
|
|
||||||
|
|
||||||
AC_DEFUN([AX_GCC_BUILTIN], [
|
|
||||||
AS_VAR_PUSHDEF([ac_var], [ax_cv_have_$1])
|
|
||||||
|
|
||||||
AC_CACHE_CHECK([for $1], [ac_var], [
|
|
||||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([], [
|
|
||||||
m4_case([$1],
|
|
||||||
[__builtin_assume_aligned], [$1("", 0)],
|
|
||||||
[__builtin_bswap16], [$1(0)],
|
|
||||||
[__builtin_bswap32], [$1(0)],
|
|
||||||
[__builtin_bswap64], [$1(0)],
|
|
||||||
[__builtin_choose_expr], [$1(0, 0, 0)],
|
|
||||||
[__builtin___clear_cache], [$1("", "")],
|
|
||||||
[__builtin_clrsb], [$1(0)],
|
|
||||||
[__builtin_clrsbl], [$1(0)],
|
|
||||||
[__builtin_clrsbll], [$1(0)],
|
|
||||||
[__builtin_clz], [$1(0)],
|
|
||||||
[__builtin_clzl], [$1(0)],
|
|
||||||
[__builtin_clzll], [$1(0)],
|
|
||||||
[__builtin_complex], [$1(0.0, 0.0)],
|
|
||||||
[__builtin_constant_p], [$1(0)],
|
|
||||||
[__builtin_ctz], [$1(0)],
|
|
||||||
[__builtin_ctzl], [$1(0)],
|
|
||||||
[__builtin_ctzll], [$1(0)],
|
|
||||||
[__builtin_expect], [$1(0, 0)],
|
|
||||||
[__builtin_ffs], [$1(0)],
|
|
||||||
[__builtin_ffsl], [$1(0)],
|
|
||||||
[__builtin_ffsll], [$1(0)],
|
|
||||||
[__builtin_fpclassify], [$1(0, 1, 2, 3, 4, 0.0)],
|
|
||||||
[__builtin_huge_val], [$1()],
|
|
||||||
[__builtin_huge_valf], [$1()],
|
|
||||||
[__builtin_huge_vall], [$1()],
|
|
||||||
[__builtin_inf], [$1()],
|
|
||||||
[__builtin_infd128], [$1()],
|
|
||||||
[__builtin_infd32], [$1()],
|
|
||||||
[__builtin_infd64], [$1()],
|
|
||||||
[__builtin_inff], [$1()],
|
|
||||||
[__builtin_infl], [$1()],
|
|
||||||
[__builtin_isinf_sign], [$1(0.0)],
|
|
||||||
[__builtin_nan], [$1("")],
|
|
||||||
[__builtin_nand128], [$1("")],
|
|
||||||
[__builtin_nand32], [$1("")],
|
|
||||||
[__builtin_nand64], [$1("")],
|
|
||||||
[__builtin_nanf], [$1("")],
|
|
||||||
[__builtin_nanl], [$1("")],
|
|
||||||
[__builtin_nans], [$1("")],
|
|
||||||
[__builtin_nansf], [$1("")],
|
|
||||||
[__builtin_nansl], [$1("")],
|
|
||||||
[__builtin_object_size], [$1("", 0)],
|
|
||||||
[__builtin_parity], [$1(0)],
|
|
||||||
[__builtin_parityl], [$1(0)],
|
|
||||||
[__builtin_parityll], [$1(0)],
|
|
||||||
[__builtin_popcount], [$1(0)],
|
|
||||||
[__builtin_popcountl], [$1(0)],
|
|
||||||
[__builtin_popcountll], [$1(0)],
|
|
||||||
[__builtin_powi], [$1(0, 0)],
|
|
||||||
[__builtin_powif], [$1(0, 0)],
|
|
||||||
[__builtin_powil], [$1(0, 0)],
|
|
||||||
[__builtin_prefetch], [$1("")],
|
|
||||||
[__builtin_trap], [$1()],
|
|
||||||
[__builtin_types_compatible_p], [$1(int, int)],
|
|
||||||
[__builtin_unreachable], [$1()],
|
|
||||||
[m4_warn([syntax], [Unsupported built-in $1, the test may fail])
|
|
||||||
$1()]
|
|
||||||
)
|
|
||||||
])],
|
|
||||||
[AS_VAR_SET([ac_var], [yes])],
|
|
||||||
[AS_VAR_SET([ac_var], [no])])
|
|
||||||
])
|
|
||||||
|
|
||||||
AS_IF([test yes = AS_VAR_GET([ac_var])],
|
|
||||||
[AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_$1), 1,
|
|
||||||
[Define to 1 if the system has the `$1' built-in function])], [])
|
|
||||||
|
|
||||||
AS_VAR_POPDEF([ac_var])
|
|
||||||
])
|
|
||||||
673
aclocal.m4
vendored
673
aclocal.m4
vendored
@@ -1,673 +0,0 @@
|
|||||||
# generated automatically by aclocal 1.16.2 -*- Autoconf -*-
|
|
||||||
|
|
||||||
# Copyright (C) 1996-2020 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($@)])])
|
|
||||||
# ===========================================================================
|
|
||||||
# https://www.gnu.org/software/autoconf-archive/ax_python_module.html
|
|
||||||
# ===========================================================================
|
|
||||||
#
|
|
||||||
# SYNOPSIS
|
|
||||||
#
|
|
||||||
# AX_PYTHON_MODULE(modname[, fatal, python])
|
|
||||||
#
|
|
||||||
# DESCRIPTION
|
|
||||||
#
|
|
||||||
# Checks for Python module.
|
|
||||||
#
|
|
||||||
# If fatal is non-empty then absence of a module will trigger an error.
|
|
||||||
# The third parameter can either be "python" for Python 2 or "python3" for
|
|
||||||
# Python 3; defaults to Python 3.
|
|
||||||
#
|
|
||||||
# LICENSE
|
|
||||||
#
|
|
||||||
# Copyright (c) 2008 Andrew Collier
|
|
||||||
#
|
|
||||||
# Copying and distribution of this file, with or without modification, are
|
|
||||||
# permitted in any medium without royalty provided the copyright notice
|
|
||||||
# and this notice are preserved. This file is offered as-is, without any
|
|
||||||
# warranty.
|
|
||||||
|
|
||||||
#serial 9
|
|
||||||
|
|
||||||
AU_ALIAS([AC_PYTHON_MODULE], [AX_PYTHON_MODULE])
|
|
||||||
AC_DEFUN([AX_PYTHON_MODULE],[
|
|
||||||
if test -z $PYTHON;
|
|
||||||
then
|
|
||||||
if test -z "$3";
|
|
||||||
then
|
|
||||||
PYTHON="python3"
|
|
||||||
else
|
|
||||||
PYTHON="$3"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
PYTHON_NAME=`basename $PYTHON`
|
|
||||||
AC_MSG_CHECKING($PYTHON_NAME module: $1)
|
|
||||||
$PYTHON -c "import $1" 2>/dev/null
|
|
||||||
if test $? -eq 0;
|
|
||||||
then
|
|
||||||
AC_MSG_RESULT(yes)
|
|
||||||
eval AS_TR_CPP(HAVE_PYMOD_$1)=yes
|
|
||||||
else
|
|
||||||
AC_MSG_RESULT(no)
|
|
||||||
eval AS_TR_CPP(HAVE_PYMOD_$1)=no
|
|
||||||
#
|
|
||||||
if test -n "$2"
|
|
||||||
then
|
|
||||||
AC_MSG_ERROR(failed to find required module $1)
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
])
|
|
||||||
|
|
||||||
# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
|
|
||||||
# serial 11 (pkg-config-0.29.1)
|
|
||||||
|
|
||||||
dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
|
|
||||||
dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
|
|
||||||
dnl
|
|
||||||
dnl This program is free software; you can redistribute it and/or modify
|
|
||||||
dnl it under the terms of the GNU General Public License as published by
|
|
||||||
dnl the Free Software Foundation; either version 2 of the License, or
|
|
||||||
dnl (at your option) any later version.
|
|
||||||
dnl
|
|
||||||
dnl This program is distributed in the hope that it will be useful, but
|
|
||||||
dnl WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
dnl General Public License for more details.
|
|
||||||
dnl
|
|
||||||
dnl You should have received a copy of the GNU General Public License
|
|
||||||
dnl along with this program; if not, write to the Free Software
|
|
||||||
dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
||||||
dnl 02111-1307, USA.
|
|
||||||
dnl
|
|
||||||
dnl As a special exception to the GNU General Public License, if you
|
|
||||||
dnl distribute this file as part of a program that contains a
|
|
||||||
dnl configuration script generated by Autoconf, you may include it under
|
|
||||||
dnl the same distribution terms that you use for the rest of that
|
|
||||||
dnl program.
|
|
||||||
|
|
||||||
dnl PKG_PREREQ(MIN-VERSION)
|
|
||||||
dnl -----------------------
|
|
||||||
dnl Since: 0.29
|
|
||||||
dnl
|
|
||||||
dnl Verify that the version of the pkg-config macros are at least
|
|
||||||
dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's
|
|
||||||
dnl installed version of pkg-config, this checks the developer's version
|
|
||||||
dnl of pkg.m4 when generating configure.
|
|
||||||
dnl
|
|
||||||
dnl To ensure that this macro is defined, also add:
|
|
||||||
dnl m4_ifndef([PKG_PREREQ],
|
|
||||||
dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])])
|
|
||||||
dnl
|
|
||||||
dnl See the "Since" comment for each macro you use to see what version
|
|
||||||
dnl of the macros you require.
|
|
||||||
m4_defun([PKG_PREREQ],
|
|
||||||
[m4_define([PKG_MACROS_VERSION], [0.29.1])
|
|
||||||
m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
|
|
||||||
[m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
|
|
||||||
])dnl PKG_PREREQ
|
|
||||||
|
|
||||||
dnl PKG_PROG_PKG_CONFIG([MIN-VERSION])
|
|
||||||
dnl ----------------------------------
|
|
||||||
dnl Since: 0.16
|
|
||||||
dnl
|
|
||||||
dnl Search for the pkg-config tool and set the PKG_CONFIG variable to
|
|
||||||
dnl first found in the path. Checks that the version of pkg-config found
|
|
||||||
dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is
|
|
||||||
dnl used since that's the first version where most current features of
|
|
||||||
dnl pkg-config existed.
|
|
||||||
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
|
|
||||||
])dnl PKG_PROG_PKG_CONFIG
|
|
||||||
|
|
||||||
dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
|
|
||||||
dnl -------------------------------------------------------------------
|
|
||||||
dnl Since: 0.18
|
|
||||||
dnl
|
|
||||||
dnl Check to see whether a particular set of modules exists. Similar to
|
|
||||||
dnl PKG_CHECK_MODULES(), but does not set variables or print errors.
|
|
||||||
dnl
|
|
||||||
dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
|
|
||||||
dnl only at the first occurence in configure.ac, so if the first place
|
|
||||||
dnl it's called might be skipped (such as if it is within an "if", you
|
|
||||||
dnl 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])
|
|
||||||
|
|
||||||
dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
|
|
||||||
dnl ---------------------------------------------
|
|
||||||
dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting
|
|
||||||
dnl pkg_failed based on the result.
|
|
||||||
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
|
|
||||||
])dnl _PKG_CONFIG
|
|
||||||
|
|
||||||
dnl _PKG_SHORT_ERRORS_SUPPORTED
|
|
||||||
dnl ---------------------------
|
|
||||||
dnl Internal check to see if pkg-config supports short errors.
|
|
||||||
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
|
|
||||||
])dnl _PKG_SHORT_ERRORS_SUPPORTED
|
|
||||||
|
|
||||||
|
|
||||||
dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
|
|
||||||
dnl [ACTION-IF-NOT-FOUND])
|
|
||||||
dnl --------------------------------------------------------------
|
|
||||||
dnl Since: 0.4.0
|
|
||||||
dnl
|
|
||||||
dnl Note that if there is a possibility the first call to
|
|
||||||
dnl PKG_CHECK_MODULES might not happen, you should be sure to include an
|
|
||||||
dnl 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
|
|
||||||
])dnl PKG_CHECK_MODULES
|
|
||||||
|
|
||||||
|
|
||||||
dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
|
|
||||||
dnl [ACTION-IF-NOT-FOUND])
|
|
||||||
dnl ---------------------------------------------------------------------
|
|
||||||
dnl Since: 0.29
|
|
||||||
dnl
|
|
||||||
dnl Checks for existence of MODULES and gathers its build flags with
|
|
||||||
dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags
|
|
||||||
dnl and VARIABLE-PREFIX_LIBS from --libs.
|
|
||||||
dnl
|
|
||||||
dnl Note that if there is a possibility the first call to
|
|
||||||
dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to
|
|
||||||
dnl include an explicit call to PKG_PROG_PKG_CONFIG in your
|
|
||||||
dnl configure.ac.
|
|
||||||
AC_DEFUN([PKG_CHECK_MODULES_STATIC],
|
|
||||||
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
|
|
||||||
_save_PKG_CONFIG=$PKG_CONFIG
|
|
||||||
PKG_CONFIG="$PKG_CONFIG --static"
|
|
||||||
PKG_CHECK_MODULES($@)
|
|
||||||
PKG_CONFIG=$_save_PKG_CONFIG[]dnl
|
|
||||||
])dnl PKG_CHECK_MODULES_STATIC
|
|
||||||
|
|
||||||
|
|
||||||
dnl PKG_INSTALLDIR([DIRECTORY])
|
|
||||||
dnl -------------------------
|
|
||||||
dnl Since: 0.27
|
|
||||||
dnl
|
|
||||||
dnl Substitutes the variable pkgconfigdir as the location where a module
|
|
||||||
dnl should install pkg-config .pc files. By default the directory is
|
|
||||||
dnl $libdir/pkgconfig, but the default can be changed by passing
|
|
||||||
dnl DIRECTORY. The user can override through the --with-pkgconfigdir
|
|
||||||
dnl 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
|
|
||||||
|
|
||||||
|
|
||||||
dnl PKG_NOARCH_INSTALLDIR([DIRECTORY])
|
|
||||||
dnl --------------------------------
|
|
||||||
dnl Since: 0.27
|
|
||||||
dnl
|
|
||||||
dnl Substitutes the variable noarch_pkgconfigdir as the location where a
|
|
||||||
dnl module should install arch-independent pkg-config .pc files. By
|
|
||||||
dnl default the directory is $datadir/pkgconfig, but the default can be
|
|
||||||
dnl changed by passing DIRECTORY. The user can override through the
|
|
||||||
dnl --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
|
|
||||||
|
|
||||||
|
|
||||||
dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
|
|
||||||
dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
|
|
||||||
dnl -------------------------------------------
|
|
||||||
dnl Since: 0.28
|
|
||||||
dnl
|
|
||||||
dnl 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
|
|
||||||
])dnl PKG_CHECK_VAR
|
|
||||||
|
|
||||||
dnl PKG_WITH_MODULES(VARIABLE-PREFIX, MODULES,
|
|
||||||
dnl [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND],
|
|
||||||
dnl [DESCRIPTION], [DEFAULT])
|
|
||||||
dnl ------------------------------------------
|
|
||||||
dnl
|
|
||||||
dnl Prepare a "--with-" configure option using the lowercase
|
|
||||||
dnl [VARIABLE-PREFIX] name, merging the behaviour of AC_ARG_WITH and
|
|
||||||
dnl PKG_CHECK_MODULES in a single macro.
|
|
||||||
AC_DEFUN([PKG_WITH_MODULES],
|
|
||||||
[
|
|
||||||
m4_pushdef([with_arg], m4_tolower([$1]))
|
|
||||||
|
|
||||||
m4_pushdef([description],
|
|
||||||
[m4_default([$5], [build with ]with_arg[ support])])
|
|
||||||
|
|
||||||
m4_pushdef([def_arg], [m4_default([$6], [auto])])
|
|
||||||
m4_pushdef([def_action_if_found], [AS_TR_SH([with_]with_arg)=yes])
|
|
||||||
m4_pushdef([def_action_if_not_found], [AS_TR_SH([with_]with_arg)=no])
|
|
||||||
|
|
||||||
m4_case(def_arg,
|
|
||||||
[yes],[m4_pushdef([with_without], [--without-]with_arg)],
|
|
||||||
[m4_pushdef([with_without],[--with-]with_arg)])
|
|
||||||
|
|
||||||
AC_ARG_WITH(with_arg,
|
|
||||||
AS_HELP_STRING(with_without, description[ @<:@default=]def_arg[@:>@]),,
|
|
||||||
[AS_TR_SH([with_]with_arg)=def_arg])
|
|
||||||
|
|
||||||
AS_CASE([$AS_TR_SH([with_]with_arg)],
|
|
||||||
[yes],[PKG_CHECK_MODULES([$1],[$2],$3,$4)],
|
|
||||||
[auto],[PKG_CHECK_MODULES([$1],[$2],
|
|
||||||
[m4_n([def_action_if_found]) $3],
|
|
||||||
[m4_n([def_action_if_not_found]) $4])])
|
|
||||||
|
|
||||||
m4_popdef([with_arg])
|
|
||||||
m4_popdef([description])
|
|
||||||
m4_popdef([def_arg])
|
|
||||||
|
|
||||||
])dnl PKG_WITH_MODULES
|
|
||||||
|
|
||||||
dnl PKG_HAVE_WITH_MODULES(VARIABLE-PREFIX, MODULES,
|
|
||||||
dnl [DESCRIPTION], [DEFAULT])
|
|
||||||
dnl -----------------------------------------------
|
|
||||||
dnl
|
|
||||||
dnl Convenience macro to trigger AM_CONDITIONAL after PKG_WITH_MODULES
|
|
||||||
dnl check._[VARIABLE-PREFIX] is exported as make variable.
|
|
||||||
AC_DEFUN([PKG_HAVE_WITH_MODULES],
|
|
||||||
[
|
|
||||||
PKG_WITH_MODULES([$1],[$2],,,[$3],[$4])
|
|
||||||
|
|
||||||
AM_CONDITIONAL([HAVE_][$1],
|
|
||||||
[test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"])
|
|
||||||
])dnl PKG_HAVE_WITH_MODULES
|
|
||||||
|
|
||||||
dnl PKG_HAVE_DEFINE_WITH_MODULES(VARIABLE-PREFIX, MODULES,
|
|
||||||
dnl [DESCRIPTION], [DEFAULT])
|
|
||||||
dnl ------------------------------------------------------
|
|
||||||
dnl
|
|
||||||
dnl Convenience macro to run AM_CONDITIONAL and AC_DEFINE after
|
|
||||||
dnl PKG_WITH_MODULES check. HAVE_[VARIABLE-PREFIX] is exported as make
|
|
||||||
dnl and preprocessor variable.
|
|
||||||
AC_DEFUN([PKG_HAVE_DEFINE_WITH_MODULES],
|
|
||||||
[
|
|
||||||
PKG_HAVE_WITH_MODULES([$1],[$2],[$3],[$4])
|
|
||||||
|
|
||||||
AS_IF([test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"],
|
|
||||||
[AC_DEFINE([HAVE_][$1], 1, [Enable ]m4_tolower([$1])[ support])])
|
|
||||||
])dnl PKG_HAVE_DEFINE_WITH_MODULES
|
|
||||||
|
|
||||||
# Copyright (C) 1999-2020 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.
|
|
||||||
|
|
||||||
|
|
||||||
# AM_PATH_PYTHON([MINIMUM-VERSION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
# Adds support for distributing Python modules and packages. To
|
|
||||||
# install modules, copy them to $(pythondir), using the python_PYTHON
|
|
||||||
# automake variable. To install a package with the same name as the
|
|
||||||
# automake package, install to $(pkgpythondir), or use the
|
|
||||||
# pkgpython_PYTHON automake variable.
|
|
||||||
#
|
|
||||||
# The variables $(pyexecdir) and $(pkgpyexecdir) are provided as
|
|
||||||
# locations to install python extension modules (shared libraries).
|
|
||||||
# Another macro is required to find the appropriate flags to compile
|
|
||||||
# extension modules.
|
|
||||||
#
|
|
||||||
# If your package is configured with a different prefix to python,
|
|
||||||
# users will have to add the install directory to the PYTHONPATH
|
|
||||||
# environment variable, or create a .pth file (see the python
|
|
||||||
# documentation for details).
|
|
||||||
#
|
|
||||||
# If the MINIMUM-VERSION argument is passed, AM_PATH_PYTHON will
|
|
||||||
# cause an error if the version of python installed on the system
|
|
||||||
# doesn't meet the requirement. MINIMUM-VERSION should consist of
|
|
||||||
# numbers and dots only.
|
|
||||||
AC_DEFUN([AM_PATH_PYTHON],
|
|
||||||
[
|
|
||||||
dnl Find a Python interpreter. Python versions prior to 2.0 are not
|
|
||||||
dnl supported. (2.0 was released on October 16, 2000).
|
|
||||||
m4_define_default([_AM_PYTHON_INTERPRETER_LIST],
|
|
||||||
[python python2 python3 dnl
|
|
||||||
python3.9 python3.8 python3.7 python3.6 python3.5 python3.4 python3.3 dnl
|
|
||||||
python3.2 python3.1 python3.0 dnl
|
|
||||||
python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 dnl
|
|
||||||
python2.0])
|
|
||||||
|
|
||||||
AC_ARG_VAR([PYTHON], [the Python interpreter])
|
|
||||||
|
|
||||||
m4_if([$1],[],[
|
|
||||||
dnl No version check is needed.
|
|
||||||
# Find any Python interpreter.
|
|
||||||
if test -z "$PYTHON"; then
|
|
||||||
AC_PATH_PROGS([PYTHON], _AM_PYTHON_INTERPRETER_LIST, :)
|
|
||||||
fi
|
|
||||||
am_display_PYTHON=python
|
|
||||||
], [
|
|
||||||
dnl A version check is needed.
|
|
||||||
if test -n "$PYTHON"; then
|
|
||||||
# If the user set $PYTHON, use it and don't search something else.
|
|
||||||
AC_MSG_CHECKING([whether $PYTHON version is >= $1])
|
|
||||||
AM_PYTHON_CHECK_VERSION([$PYTHON], [$1],
|
|
||||||
[AC_MSG_RESULT([yes])],
|
|
||||||
[AC_MSG_RESULT([no])
|
|
||||||
AC_MSG_ERROR([Python interpreter is too old])])
|
|
||||||
am_display_PYTHON=$PYTHON
|
|
||||||
else
|
|
||||||
# Otherwise, try each interpreter until we find one that satisfies
|
|
||||||
# VERSION.
|
|
||||||
AC_CACHE_CHECK([for a Python interpreter with version >= $1],
|
|
||||||
[am_cv_pathless_PYTHON],[
|
|
||||||
for am_cv_pathless_PYTHON in _AM_PYTHON_INTERPRETER_LIST none; do
|
|
||||||
test "$am_cv_pathless_PYTHON" = none && break
|
|
||||||
AM_PYTHON_CHECK_VERSION([$am_cv_pathless_PYTHON], [$1], [break])
|
|
||||||
done])
|
|
||||||
# Set $PYTHON to the absolute path of $am_cv_pathless_PYTHON.
|
|
||||||
if test "$am_cv_pathless_PYTHON" = none; then
|
|
||||||
PYTHON=:
|
|
||||||
else
|
|
||||||
AC_PATH_PROG([PYTHON], [$am_cv_pathless_PYTHON])
|
|
||||||
fi
|
|
||||||
am_display_PYTHON=$am_cv_pathless_PYTHON
|
|
||||||
fi
|
|
||||||
])
|
|
||||||
|
|
||||||
if test "$PYTHON" = :; then
|
|
||||||
dnl Run any user-specified action, or abort.
|
|
||||||
m4_default([$3], [AC_MSG_ERROR([no suitable Python interpreter found])])
|
|
||||||
else
|
|
||||||
|
|
||||||
dnl Query Python for its version number. Although site.py simply uses
|
|
||||||
dnl sys.version[:3], printing that failed with Python 3.10, since the
|
|
||||||
dnl trailing zero was eliminated. So now we output just the major
|
|
||||||
dnl and minor version numbers, as numbers. Apparently the tertiary
|
|
||||||
dnl version is not of interest.
|
|
||||||
|
|
||||||
AC_CACHE_CHECK([for $am_display_PYTHON version], [am_cv_python_version],
|
|
||||||
[am_cv_python_version=`$PYTHON -c "import sys; print('%u.%u' % sys.version_info[[:2]])"`])
|
|
||||||
AC_SUBST([PYTHON_VERSION], [$am_cv_python_version])
|
|
||||||
|
|
||||||
dnl Use the values of $prefix and $exec_prefix for the corresponding
|
|
||||||
dnl values of PYTHON_PREFIX and PYTHON_EXEC_PREFIX. These are made
|
|
||||||
dnl distinct variables so they can be overridden if need be. However,
|
|
||||||
dnl general consensus is that you shouldn't need this ability.
|
|
||||||
|
|
||||||
AC_SUBST([PYTHON_PREFIX], ['${prefix}'])
|
|
||||||
AC_SUBST([PYTHON_EXEC_PREFIX], ['${exec_prefix}'])
|
|
||||||
|
|
||||||
dnl At times (like when building shared libraries) you may want
|
|
||||||
dnl to know which OS platform Python thinks this is.
|
|
||||||
|
|
||||||
AC_CACHE_CHECK([for $am_display_PYTHON platform], [am_cv_python_platform],
|
|
||||||
[am_cv_python_platform=`$PYTHON -c "import sys; sys.stdout.write(sys.platform)"`])
|
|
||||||
AC_SUBST([PYTHON_PLATFORM], [$am_cv_python_platform])
|
|
||||||
|
|
||||||
# Just factor out some code duplication.
|
|
||||||
am_python_setup_sysconfig="\
|
|
||||||
import sys
|
|
||||||
# Prefer sysconfig over distutils.sysconfig, for better compatibility
|
|
||||||
# with python 3.x. See automake bug#10227.
|
|
||||||
try:
|
|
||||||
import sysconfig
|
|
||||||
except ImportError:
|
|
||||||
can_use_sysconfig = 0
|
|
||||||
else:
|
|
||||||
can_use_sysconfig = 1
|
|
||||||
# Can't use sysconfig in CPython 2.7, since it's broken in virtualenvs:
|
|
||||||
# <https://github.com/pypa/virtualenv/issues/118>
|
|
||||||
try:
|
|
||||||
from platform import python_implementation
|
|
||||||
if python_implementation() == 'CPython' and sys.version[[:3]] == '2.7':
|
|
||||||
can_use_sysconfig = 0
|
|
||||||
except ImportError:
|
|
||||||
pass"
|
|
||||||
|
|
||||||
dnl Set up 4 directories:
|
|
||||||
|
|
||||||
dnl pythondir -- where to install python scripts. This is the
|
|
||||||
dnl site-packages directory, not the python standard library
|
|
||||||
dnl directory like in previous automake betas. This behavior
|
|
||||||
dnl is more consistent with lispdir.m4 for example.
|
|
||||||
dnl Query distutils for this directory.
|
|
||||||
AC_CACHE_CHECK([for $am_display_PYTHON script directory],
|
|
||||||
[am_cv_python_pythondir],
|
|
||||||
[if test "x$prefix" = xNONE
|
|
||||||
then
|
|
||||||
am_py_prefix=$ac_default_prefix
|
|
||||||
else
|
|
||||||
am_py_prefix=$prefix
|
|
||||||
fi
|
|
||||||
am_cv_python_pythondir=`$PYTHON -c "
|
|
||||||
$am_python_setup_sysconfig
|
|
||||||
if can_use_sysconfig:
|
|
||||||
sitedir = sysconfig.get_path('purelib', vars={'base':'$am_py_prefix'})
|
|
||||||
else:
|
|
||||||
from distutils import sysconfig
|
|
||||||
sitedir = sysconfig.get_python_lib(0, 0, prefix='$am_py_prefix')
|
|
||||||
sys.stdout.write(sitedir)"`
|
|
||||||
case $am_cv_python_pythondir in
|
|
||||||
$am_py_prefix*)
|
|
||||||
am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'`
|
|
||||||
am_cv_python_pythondir=`echo "$am_cv_python_pythondir" | sed "s,^$am__strip_prefix,$PYTHON_PREFIX,"`
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
case $am_py_prefix in
|
|
||||||
/usr|/System*) ;;
|
|
||||||
*)
|
|
||||||
am_cv_python_pythondir=$PYTHON_PREFIX/lib/python$PYTHON_VERSION/site-packages
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
])
|
|
||||||
AC_SUBST([pythondir], [$am_cv_python_pythondir])
|
|
||||||
|
|
||||||
dnl pkgpythondir -- $PACKAGE directory under pythondir. Was
|
|
||||||
dnl PYTHON_SITE_PACKAGE in previous betas, but this naming is
|
|
||||||
dnl more consistent with the rest of automake.
|
|
||||||
|
|
||||||
AC_SUBST([pkgpythondir], [\${pythondir}/$PACKAGE])
|
|
||||||
|
|
||||||
dnl pyexecdir -- directory for installing python extension modules
|
|
||||||
dnl (shared libraries)
|
|
||||||
dnl Query distutils for this directory.
|
|
||||||
AC_CACHE_CHECK([for $am_display_PYTHON extension module directory],
|
|
||||||
[am_cv_python_pyexecdir],
|
|
||||||
[if test "x$exec_prefix" = xNONE
|
|
||||||
then
|
|
||||||
am_py_exec_prefix=$am_py_prefix
|
|
||||||
else
|
|
||||||
am_py_exec_prefix=$exec_prefix
|
|
||||||
fi
|
|
||||||
am_cv_python_pyexecdir=`$PYTHON -c "
|
|
||||||
$am_python_setup_sysconfig
|
|
||||||
if can_use_sysconfig:
|
|
||||||
sitedir = sysconfig.get_path('platlib', vars={'platbase':'$am_py_prefix'})
|
|
||||||
else:
|
|
||||||
from distutils import sysconfig
|
|
||||||
sitedir = sysconfig.get_python_lib(1, 0, prefix='$am_py_prefix')
|
|
||||||
sys.stdout.write(sitedir)"`
|
|
||||||
case $am_cv_python_pyexecdir in
|
|
||||||
$am_py_exec_prefix*)
|
|
||||||
am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'`
|
|
||||||
am_cv_python_pyexecdir=`echo "$am_cv_python_pyexecdir" | sed "s,^$am__strip_prefix,$PYTHON_EXEC_PREFIX,"`
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
case $am_py_exec_prefix in
|
|
||||||
/usr|/System*) ;;
|
|
||||||
*)
|
|
||||||
am_cv_python_pyexecdir=$PYTHON_EXEC_PREFIX/lib/python$PYTHON_VERSION/site-packages
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
])
|
|
||||||
AC_SUBST([pyexecdir], [$am_cv_python_pyexecdir])
|
|
||||||
|
|
||||||
dnl pkgpyexecdir -- $(pyexecdir)/$(PACKAGE)
|
|
||||||
|
|
||||||
AC_SUBST([pkgpyexecdir], [\${pyexecdir}/$PACKAGE])
|
|
||||||
|
|
||||||
dnl Run any user-specified action.
|
|
||||||
$2
|
|
||||||
fi
|
|
||||||
|
|
||||||
])
|
|
||||||
|
|
||||||
|
|
||||||
# AM_PYTHON_CHECK_VERSION(PROG, VERSION, [ACTION-IF-TRUE], [ACTION-IF-FALSE])
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
# Run ACTION-IF-TRUE if the Python interpreter PROG has version >= VERSION.
|
|
||||||
# Run ACTION-IF-FALSE otherwise.
|
|
||||||
# This test uses sys.hexversion instead of the string equivalent (first
|
|
||||||
# word of sys.version), in order to cope with versions such as 2.2c1.
|
|
||||||
# This supports Python 2.0 or higher. (2.0 was released on October 16, 2000).
|
|
||||||
AC_DEFUN([AM_PYTHON_CHECK_VERSION],
|
|
||||||
[prog="import sys
|
|
||||||
# split strings by '.' and convert to numeric. Append some zeros
|
|
||||||
# because we need at least 4 digits for the hex conversion.
|
|
||||||
# map returns an iterator in Python 3.0 and a list in 2.x
|
|
||||||
minver = list(map(int, '$2'.split('.'))) + [[0, 0, 0]]
|
|
||||||
minverhex = 0
|
|
||||||
# xrange is not present in Python 3.0 and range returns an iterator
|
|
||||||
for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[[i]]
|
|
||||||
sys.exit(sys.hexversion < minverhex)"
|
|
||||||
AS_IF([AM_RUN_LOG([$1 -c "$prog"])], [$3], [$4])])
|
|
||||||
|
|
||||||
# Copyright (C) 2001-2020 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.
|
|
||||||
|
|
||||||
# AM_RUN_LOG(COMMAND)
|
|
||||||
# -------------------
|
|
||||||
# Run COMMAND, save the exit status in ac_status, and log it.
|
|
||||||
# (This has been adapted from Autoconf's _AC_RUN_LOG macro.)
|
|
||||||
AC_DEFUN([AM_RUN_LOG],
|
|
||||||
[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD
|
|
||||||
($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD
|
|
||||||
ac_status=$?
|
|
||||||
echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
|
|
||||||
(exit $ac_status); }])
|
|
||||||
|
|
||||||
m4_include([acinclude.m4])
|
|
||||||
982
autoconf/config.guess
vendored
982
autoconf/config.guess
vendored
File diff suppressed because it is too large
Load Diff
515
autoconf/config.sub
vendored
515
autoconf/config.sub
vendored
@@ -1,40 +1,42 @@
|
|||||||
#! /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 Free Software Foundation, Inc.
|
||||||
|
|
||||||
timestamp='2014-01-01'
|
timestamp='2003-06-17'
|
||||||
|
|
||||||
# This file is free software; you can redistribute it and/or modify it
|
# 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., 59 Temple Place - Suite 330,
|
||||||
|
# Boston, MA 02111-1307, 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 to <config-patches@gnu.org>. Submit a context
|
||||||
# Please send patches with a ChangeLog entry to config-patches@gnu.org.
|
# 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 +70,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
|
||||||
|
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."
|
||||||
@@ -80,11 +83,11 @@ Try \`$me --help' for more information."
|
|||||||
while test $# -gt 0 ; do
|
while test $# -gt 0 ; do
|
||||||
case $1 in
|
case $1 in
|
||||||
--time-stamp | --time* | -t )
|
--time-stamp | --time* | -t )
|
||||||
echo "$timestamp" ; exit ;;
|
echo "$timestamp" ; exit 0 ;;
|
||||||
--version | -v )
|
--version | -v )
|
||||||
echo "$version" ; exit ;;
|
echo "$version" ; exit 0 ;;
|
||||||
--help | --h* | -h )
|
--help | --h* | -h )
|
||||||
echo "$usage"; exit ;;
|
echo "$usage"; exit 0 ;;
|
||||||
-- ) # Stop option processing
|
-- ) # Stop option processing
|
||||||
shift; break ;;
|
shift; break ;;
|
||||||
- ) # Use stdin as input.
|
- ) # Use stdin as input.
|
||||||
@@ -96,7 +99,7 @@ while test $# -gt 0 ; do
|
|||||||
*local*)
|
*local*)
|
||||||
# First pass through any local machine types.
|
# First pass through any local machine types.
|
||||||
echo $1
|
echo $1
|
||||||
exit ;;
|
exit 0;;
|
||||||
|
|
||||||
* )
|
* )
|
||||||
break ;;
|
break ;;
|
||||||
@@ -115,18 +118,10 @@ 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* | freebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
|
||||||
linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
|
|
||||||
knetbsd*-gnu* | netbsd*-gnu* | \
|
|
||||||
kopensolaris*-gnu* | \
|
|
||||||
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 +144,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)
|
||||||
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
|
||||||
@@ -177,10 +169,6 @@ case $os in
|
|||||||
-hiux*)
|
-hiux*)
|
||||||
os=-hiuxwe2
|
os=-hiuxwe2
|
||||||
;;
|
;;
|
||||||
-sco6)
|
|
||||||
os=-sco5v6
|
|
||||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
|
||||||
;;
|
|
||||||
-sco5)
|
-sco5)
|
||||||
os=-sco3.2v5
|
os=-sco3.2v5
|
||||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||||
@@ -197,10 +185,6 @@ case $os in
|
|||||||
# Don't forget version if it is 3.2v4 or newer.
|
# Don't forget version if it is 3.2v4 or newer.
|
||||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||||
;;
|
;;
|
||||||
-sco5v6*)
|
|
||||||
# Don't forget version if it is 3.2v4 or newer.
|
|
||||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
|
||||||
;;
|
|
||||||
-sco*)
|
-sco*)
|
||||||
os=-sco3.2v2
|
os=-sco3.2v2
|
||||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||||
@@ -218,12 +202,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,107 +226,55 @@ 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 \
|
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
|
||||||
| arc | arceb \
|
| c4x | clipper \
|
||||||
| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
|
|
||||||
| avr | avr32 \
|
|
||||||
| be32 | be64 \
|
|
||||||
| bfin \
|
|
||||||
| c4x | c8051 | clipper \
|
|
||||||
| d10v | d30v | dlx | dsp16xx \
|
| d10v | d30v | dlx | dsp16xx \
|
||||||
| epiphany \
|
| 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 \
|
||||||
| k1om \
|
| m32r | m68000 | m68k | m88k | mcore \
|
||||||
| le32 | le64 \
|
|
||||||
| lm32 \
|
|
||||||
| m32c | m32r | m32rle | m68000 | m68k | m88k \
|
|
||||||
| maxq | mb | microblaze | microblazeel | mcore | mep | metag \
|
|
||||||
| 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 \
|
||||||
| mips64vr5900 | mips64vr5900el \
|
|
||||||
| mipsisa32 | mipsisa32el \
|
| mipsisa32 | mipsisa32el \
|
||||||
| mipsisa32r2 | mipsisa32r2el \
|
| mipsisa32r2 | mipsisa32r2el \
|
||||||
| mipsisa64 | mipsisa64el \
|
| mipsisa64 | mipsisa64el \
|
||||||
| mipsisa64r2 | mipsisa64r2el \
|
|
||||||
| mipsisa64sb1 | mipsisa64sb1el \
|
| mipsisa64sb1 | mipsisa64sb1el \
|
||||||
| mipsisa64sr71k | mipsisa64sr71kel \
|
| mipsisa64sr71k | mipsisa64sr71kel \
|
||||||
| mipsr5900 | mipsr5900el \
|
|
||||||
| mipstx39 | mipstx39el \
|
| mipstx39 | mipstx39el \
|
||||||
| mn10200 | mn10300 \
|
| mn10200 | mn10300 \
|
||||||
| moxie \
|
|
||||||
| mt \
|
|
||||||
| msp430 \
|
| msp430 \
|
||||||
| nds32 | nds32le | nds32be \
|
|
||||||
| nios | nios2 | nios2eb | nios2el \
|
|
||||||
| ns16k | ns32k \
|
| ns16k | ns32k \
|
||||||
| open8 \
|
| openrisc | or32 \
|
||||||
| or1k | or32 \
|
|
||||||
| pdp10 | pdp11 | pj | pjl \
|
| pdp10 | pdp11 | pj | pjl \
|
||||||
| powerpc | powerpc64 | powerpc64le | powerpcle \
|
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
|
||||||
| pyramid \
|
| pyramid \
|
||||||
| rl78 | rx \
|
| sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
|
||||||
| score \
|
|
||||||
| sh | sh[1234] | sh[24]a | sh[24]aeb | 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 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
|
||||||
| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
|
| strongarm \
|
||||||
| spu \
|
| tahoe | thumb | tic4x | tic80 | tron \
|
||||||
| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
|
| v850 | v850e \
|
||||||
| ubicom32 \
|
|
||||||
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
|
|
||||||
| we32k \
|
| we32k \
|
||||||
| x86 | xc16x | xstormy16 | xtensa \
|
| x86 | xscale | 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
|
||||||
;;
|
;;
|
||||||
m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
|
m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
|
||||||
;;
|
;;
|
||||||
ms1)
|
|
||||||
basic_machine=mt-unknown
|
|
||||||
;;
|
|
||||||
|
|
||||||
strongarm | thumb | xscale)
|
|
||||||
basic_machine=arm-unknown
|
|
||||||
;;
|
|
||||||
xgate)
|
|
||||||
basic_machine=$basic_machine-unknown
|
|
||||||
os=-none
|
|
||||||
;;
|
|
||||||
xscaleeb)
|
|
||||||
basic_machine=armeb-unknown
|
|
||||||
;;
|
|
||||||
|
|
||||||
xscaleel)
|
|
||||||
basic_machine=armel-unknown
|
|
||||||
;;
|
|
||||||
|
|
||||||
# We use `pc' rather than `unknown'
|
# We use `pc' rather than `unknown'
|
||||||
# because (1) that's what they normally are, and
|
# because (1) that's what they normally are, and
|
||||||
@@ -364,83 +290,58 @@ case $basic_machine in
|
|||||||
# Recognize the basic CPU types with company name.
|
# 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-* \
|
||||||
| be32-* | be64-* \
|
| bs2000-* \
|
||||||
| bfin-* | bs2000-* \
|
| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
|
||||||
| c[123]* | c30-* | [cjt]90-* | c4x-* \
|
| clipper-* | cydra-* \
|
||||||
| c8051-* | clipper-* | craynv-* | cydra-* \
|
|
||||||
| d10v-* | d30v-* | dlx-* \
|
| d10v-* | d30v-* | dlx-* \
|
||||||
| elxsi-* \
|
| elxsi-* \
|
||||||
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
|
| f30[01]-* | f700-* | 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-* \
|
||||||
| k1om-* \
|
| m32r-* \
|
||||||
| le32-* | le64-* \
|
|
||||||
| lm32-* \
|
|
||||||
| 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-* | 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-* \
|
||||||
| mips64vr5900-* | mips64vr5900el-* \
|
|
||||||
| mipsisa32-* | mipsisa32el-* \
|
| mipsisa32-* | mipsisa32el-* \
|
||||||
| mipsisa32r2-* | mipsisa32r2el-* \
|
| mipsisa32r2-* | mipsisa32r2el-* \
|
||||||
| mipsisa64-* | mipsisa64el-* \
|
| mipsisa64-* | mipsisa64el-* \
|
||||||
| mipsisa64r2-* | mipsisa64r2el-* \
|
|
||||||
| mipsisa64sb1-* | mipsisa64sb1el-* \
|
| mipsisa64sb1-* | mipsisa64sb1el-* \
|
||||||
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
|
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
|
||||||
| mipsr5900-* | mipsr5900el-* \
|
|
||||||
| mipstx39-* | mipstx39el-* \
|
| mipstx39-* | mipstx39el-* \
|
||||||
| mmix-* \
|
|
||||||
| mt-* \
|
|
||||||
| msp430-* \
|
| msp430-* \
|
||||||
| nds32-* | nds32le-* | nds32be-* \
|
| none-* | np1-* | nv1-* | ns16k-* | ns32k-* \
|
||||||
| nios-* | nios2-* | nios2eb-* | nios2el-* \
|
|
||||||
| 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[23]e-* | sh[34]eb-* | shbe-* \
|
||||||
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
|
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
|
||||||
| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
|
| sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
|
||||||
| sparclite-* \
|
| sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
|
||||||
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
|
| tahoe-* | thumb-* \
|
||||||
| tahoe-* \
|
|
||||||
| 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-* | xps100-* | xscale-* | xstormy16-* \
|
||||||
| xstormy16-* | xtensa*-* \
|
| xtensa-* \
|
||||||
| ymp-* \
|
| ymp-* \
|
||||||
| z8k-* | z80-*)
|
| z8k-*)
|
||||||
;;
|
|
||||||
# Recognize the basic CPU types without company name, with glob match.
|
|
||||||
xtensa*)
|
|
||||||
basic_machine=$basic_machine-unknown
|
|
||||||
;;
|
;;
|
||||||
# Recognize the various machine names and aliases which stand
|
# Recognize the various machine names and aliases which stand
|
||||||
# for a CPU type and a company and sometimes even an OS.
|
# for a CPU type and a company and sometimes even an OS.
|
||||||
@@ -458,9 +359,6 @@ case $basic_machine in
|
|||||||
basic_machine=a29k-amd
|
basic_machine=a29k-amd
|
||||||
os=-udi
|
os=-udi
|
||||||
;;
|
;;
|
||||||
abacus)
|
|
||||||
basic_machine=abacus-unknown
|
|
||||||
;;
|
|
||||||
adobe68k)
|
adobe68k)
|
||||||
basic_machine=m68010-adobe
|
basic_machine=m68010-adobe
|
||||||
os=-scout
|
os=-scout
|
||||||
@@ -478,9 +376,6 @@ case $basic_machine in
|
|||||||
amd64)
|
amd64)
|
||||||
basic_machine=x86_64-pc
|
basic_machine=x86_64-pc
|
||||||
;;
|
;;
|
||||||
amd64-*)
|
|
||||||
basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
|
|
||||||
;;
|
|
||||||
amdahl)
|
amdahl)
|
||||||
basic_machine=580-amdahl
|
basic_machine=580-amdahl
|
||||||
os=-sysv
|
os=-sysv
|
||||||
@@ -504,10 +399,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
|
||||||
@@ -516,35 +407,10 @@ case $basic_machine in
|
|||||||
basic_machine=ns32k-sequent
|
basic_machine=ns32k-sequent
|
||||||
os=-dynix
|
os=-dynix
|
||||||
;;
|
;;
|
||||||
blackfin)
|
|
||||||
basic_machine=bfin-unknown
|
|
||||||
os=-linux
|
|
||||||
;;
|
|
||||||
blackfin-*)
|
|
||||||
basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
|
|
||||||
os=-linux
|
|
||||||
;;
|
|
||||||
bluegene*)
|
|
||||||
basic_machine=powerpc-ibm
|
|
||||||
os=-cnk
|
|
||||||
;;
|
|
||||||
c54x-*)
|
|
||||||
basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
|
|
||||||
;;
|
|
||||||
c55x-*)
|
|
||||||
basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
|
|
||||||
;;
|
|
||||||
c6x-*)
|
|
||||||
basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
|
|
||||||
;;
|
|
||||||
c90)
|
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
|
||||||
@@ -569,27 +435,12 @@ case $basic_machine in
|
|||||||
basic_machine=j90-cray
|
basic_machine=j90-cray
|
||||||
os=-unicos
|
os=-unicos
|
||||||
;;
|
;;
|
||||||
craynv)
|
|
||||||
basic_machine=craynv-cray
|
|
||||||
os=-unicosmp
|
|
||||||
;;
|
|
||||||
cr16 | cr16-*)
|
|
||||||
basic_machine=cr16-unknown
|
|
||||||
os=-elf
|
|
||||||
;;
|
|
||||||
crds | unos)
|
crds | unos)
|
||||||
basic_machine=m68k-crds
|
basic_machine=m68k-crds
|
||||||
;;
|
;;
|
||||||
crisv32 | crisv32-* | etraxfs*)
|
|
||||||
basic_machine=crisv32-axis
|
|
||||||
;;
|
|
||||||
cris | cris-* | etrax*)
|
cris | cris-* | etrax*)
|
||||||
basic_machine=cris-axis
|
basic_machine=cris-axis
|
||||||
;;
|
;;
|
||||||
crx)
|
|
||||||
basic_machine=crx-unknown
|
|
||||||
os=-elf
|
|
||||||
;;
|
|
||||||
da30 | da30-*)
|
da30 | da30-*)
|
||||||
basic_machine=m68k-da30
|
basic_machine=m68k-da30
|
||||||
;;
|
;;
|
||||||
@@ -612,14 +463,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)
|
|
||||||
basic_machine=i586-pc
|
|
||||||
os=-msdosdjgpp
|
|
||||||
;;
|
|
||||||
dpx20 | dpx20-*)
|
dpx20 | dpx20-*)
|
||||||
basic_machine=rs6000-bull
|
basic_machine=rs6000-bull
|
||||||
os=-bosx
|
os=-bosx
|
||||||
@@ -731,6 +574,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
|
||||||
@@ -769,14 +613,6 @@ case $basic_machine in
|
|||||||
basic_machine=m68k-isi
|
basic_machine=m68k-isi
|
||||||
os=-sysv
|
os=-sysv
|
||||||
;;
|
;;
|
||||||
m68knommu)
|
|
||||||
basic_machine=m68k-unknown
|
|
||||||
os=-linux
|
|
||||||
;;
|
|
||||||
m68knommu-*)
|
|
||||||
basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
|
|
||||||
os=-linux
|
|
||||||
;;
|
|
||||||
m88k-omron*)
|
m88k-omron*)
|
||||||
basic_machine=m88k-omron
|
basic_machine=m88k-omron
|
||||||
;;
|
;;
|
||||||
@@ -788,21 +624,10 @@ 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)
|
|
||||||
basic_machine=arm-unknown
|
|
||||||
os=-mingw32ce
|
|
||||||
;;
|
|
||||||
miniframe)
|
miniframe)
|
||||||
basic_machine=m68000-convergent
|
basic_machine=m68000-convergent
|
||||||
;;
|
;;
|
||||||
@@ -816,6 +641,10 @@ case $basic_machine in
|
|||||||
mips3*)
|
mips3*)
|
||||||
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
|
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
|
||||||
;;
|
;;
|
||||||
|
mmix*)
|
||||||
|
basic_machine=mmix-knuth
|
||||||
|
os=-mmixware
|
||||||
|
;;
|
||||||
monitor)
|
monitor)
|
||||||
basic_machine=m68k-rom68k
|
basic_machine=m68k-rom68k
|
||||||
os=-coff
|
os=-coff
|
||||||
@@ -828,21 +657,10 @@ case $basic_machine in
|
|||||||
basic_machine=i386-pc
|
basic_machine=i386-pc
|
||||||
os=-msdos
|
os=-msdos
|
||||||
;;
|
;;
|
||||||
ms1-*)
|
|
||||||
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,11 +725,9 @@ case $basic_machine in
|
|||||||
np1)
|
np1)
|
||||||
basic_machine=np1-gould
|
basic_machine=np1-gould
|
||||||
;;
|
;;
|
||||||
neo-tandem)
|
nv1)
|
||||||
basic_machine=neo-tandem
|
basic_machine=nv1-cray
|
||||||
;;
|
os=-unicosmp
|
||||||
nse-tandem)
|
|
||||||
basic_machine=nse-tandem
|
|
||||||
;;
|
;;
|
||||||
nsr-tandem)
|
nsr-tandem)
|
||||||
basic_machine=nsr-tandem
|
basic_machine=nsr-tandem
|
||||||
@@ -920,12 +736,9 @@ case $basic_machine in
|
|||||||
basic_machine=hppa1.1-oki
|
basic_machine=hppa1.1-oki
|
||||||
os=-proelf
|
os=-proelf
|
||||||
;;
|
;;
|
||||||
openrisc | openrisc-*)
|
or32 | or32-*)
|
||||||
basic_machine=or32-unknown
|
basic_machine=or32-unknown
|
||||||
;;
|
os=-coff
|
||||||
os400)
|
|
||||||
basic_machine=powerpc-ibm
|
|
||||||
os=-os400
|
|
||||||
;;
|
;;
|
||||||
OSE68000 | ose68000)
|
OSE68000 | ose68000)
|
||||||
basic_machine=m68000-ericsson
|
basic_machine=m68000-ericsson
|
||||||
@@ -943,14 +756,6 @@ case $basic_machine in
|
|||||||
basic_machine=i860-intel
|
basic_machine=i860-intel
|
||||||
os=-osf
|
os=-osf
|
||||||
;;
|
;;
|
||||||
parisc)
|
|
||||||
basic_machine=hppa-unknown
|
|
||||||
os=-linux
|
|
||||||
;;
|
|
||||||
parisc-*)
|
|
||||||
basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
|
|
||||||
os=-linux
|
|
||||||
;;
|
|
||||||
pbd)
|
pbd)
|
||||||
basic_machine=sparc-tti
|
basic_machine=sparc-tti
|
||||||
;;
|
;;
|
||||||
@@ -960,12 +765,6 @@ case $basic_machine in
|
|||||||
pc532 | pc532-*)
|
pc532 | pc532-*)
|
||||||
basic_machine=ns32k-pc532
|
basic_machine=ns32k-pc532
|
||||||
;;
|
;;
|
||||||
pc98)
|
|
||||||
basic_machine=i386-pc
|
|
||||||
;;
|
|
||||||
pc98-*)
|
|
||||||
basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
|
|
||||||
;;
|
|
||||||
pentium | p5 | k5 | k6 | nexgen | viac3)
|
pentium | p5 | k5 | k6 | nexgen | viac3)
|
||||||
basic_machine=i586-pc
|
basic_machine=i586-pc
|
||||||
;;
|
;;
|
||||||
@@ -995,10 +794,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,14 +821,6 @@ case $basic_machine in
|
|||||||
basic_machine=i586-unknown
|
basic_machine=i586-unknown
|
||||||
os=-pw32
|
os=-pw32
|
||||||
;;
|
;;
|
||||||
rdos | rdos64)
|
|
||||||
basic_machine=x86_64-pc
|
|
||||||
os=-rdos
|
|
||||||
;;
|
|
||||||
rdos32)
|
|
||||||
basic_machine=i386-pc
|
|
||||||
os=-rdos
|
|
||||||
;;
|
|
||||||
rom68k)
|
rom68k)
|
||||||
basic_machine=m68k-rom68k
|
basic_machine=m68k-rom68k
|
||||||
os=-coff
|
os=-coff
|
||||||
@@ -1057,10 +847,6 @@ case $basic_machine in
|
|||||||
sb1el)
|
sb1el)
|
||||||
basic_machine=mipsisa64sb1el-unknown
|
basic_machine=mipsisa64sb1el-unknown
|
||||||
;;
|
;;
|
||||||
sde)
|
|
||||||
basic_machine=mipsisa32-sde
|
|
||||||
os=-elf
|
|
||||||
;;
|
|
||||||
sei)
|
sei)
|
||||||
basic_machine=mips-sei
|
basic_machine=mips-sei
|
||||||
os=-seiux
|
os=-seiux
|
||||||
@@ -1072,9 +858,6 @@ case $basic_machine in
|
|||||||
basic_machine=sh-hitachi
|
basic_machine=sh-hitachi
|
||||||
os=-hms
|
os=-hms
|
||||||
;;
|
;;
|
||||||
sh5el)
|
|
||||||
basic_machine=sh5le-unknown
|
|
||||||
;;
|
|
||||||
sh64)
|
sh64)
|
||||||
basic_machine=sh64-unknown
|
basic_machine=sh64-unknown
|
||||||
;;
|
;;
|
||||||
@@ -1096,9 +879,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,9 +935,17 @@ case $basic_machine in
|
|||||||
basic_machine=t90-cray
|
basic_machine=t90-cray
|
||||||
os=-unicos
|
os=-unicos
|
||||||
;;
|
;;
|
||||||
tile*)
|
tic54x | c54x*)
|
||||||
basic_machine=$basic_machine-unknown
|
basic_machine=tic54x-unknown
|
||||||
os=-linux-gnu
|
os=-coff
|
||||||
|
;;
|
||||||
|
tic55x | c55x*)
|
||||||
|
basic_machine=tic55x-unknown
|
||||||
|
os=-coff
|
||||||
|
;;
|
||||||
|
tic6x | c6x*)
|
||||||
|
basic_machine=tic6x-unknown
|
||||||
|
os=-coff
|
||||||
;;
|
;;
|
||||||
tx39)
|
tx39)
|
||||||
basic_machine=mipstx39-unknown
|
basic_machine=mipstx39-unknown
|
||||||
@@ -1172,10 +960,6 @@ case $basic_machine in
|
|||||||
tower | tower-32)
|
tower | tower-32)
|
||||||
basic_machine=m68k-ncr
|
basic_machine=m68k-ncr
|
||||||
;;
|
;;
|
||||||
tpf)
|
|
||||||
basic_machine=s390x-ibm
|
|
||||||
os=-tpf
|
|
||||||
;;
|
|
||||||
udi29k)
|
udi29k)
|
||||||
basic_machine=a29k-amd
|
basic_machine=a29k-amd
|
||||||
os=-udi
|
os=-udi
|
||||||
@@ -1219,16 +1003,9 @@ case $basic_machine in
|
|||||||
basic_machine=hppa1.1-winbond
|
basic_machine=hppa1.1-winbond
|
||||||
os=-proelf
|
os=-proelf
|
||||||
;;
|
;;
|
||||||
xbox)
|
|
||||||
basic_machine=i686-pc
|
|
||||||
os=-mingw32
|
|
||||||
;;
|
|
||||||
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 +1014,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
|
||||||
@@ -1260,9 +1033,6 @@ case $basic_machine in
|
|||||||
romp)
|
romp)
|
||||||
basic_machine=romp-ibm
|
basic_machine=romp-ibm
|
||||||
;;
|
;;
|
||||||
mmix)
|
|
||||||
basic_machine=mmix-knuth
|
|
||||||
;;
|
|
||||||
rs6000)
|
rs6000)
|
||||||
basic_machine=rs6000-ibm
|
basic_machine=rs6000-ibm
|
||||||
;;
|
;;
|
||||||
@@ -1279,10 +1049,13 @@ 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)
|
sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele)
|
||||||
basic_machine=sh-unknown
|
basic_machine=sh-unknown
|
||||||
;;
|
;;
|
||||||
sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
|
sh64)
|
||||||
|
basic_machine=sh64-unknown
|
||||||
|
;;
|
||||||
|
sparc | sparcv9 | sparcv9b)
|
||||||
basic_machine=sparc-sun
|
basic_machine=sparc-sun
|
||||||
;;
|
;;
|
||||||
cydra)
|
cydra)
|
||||||
@@ -1329,9 +1102,6 @@ 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,31 +1122,25 @@ 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* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
|
||||||
| -bitrig* | -openbsd* | -solidbsd* \
|
| -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
|
||||||
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
|
|
||||||
| -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* | -uxpv* | -beos* | -mpeix* | -udk* \
|
||||||
| -linux-newlib* | -linux-musl* | -linux-uclibc* \
|
|
||||||
| -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* \
|
||||||
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
|
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
|
||||||
| -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*)
|
||||||
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
|
|
||||||
# Remember, each alternative MUST END IN *, to match a version number.
|
# Remember, each alternative MUST END IN *, to match a version number.
|
||||||
;;
|
;;
|
||||||
-qnx*)
|
-qnx*)
|
||||||
@@ -1394,15 +1158,12 @@ case $os in
|
|||||||
os=`echo $os | sed -e 's|nto|nto-qnx|'`
|
os=`echo $os | sed -e 's|nto|nto-qnx|'`
|
||||||
;;
|
;;
|
||||||
-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
|
-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
|
||||||
| -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
|
| -windows* | -osx | -abug | -netware* | -os9* | -beos* \
|
||||||
| -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
|
| -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
|
||||||
;;
|
;;
|
||||||
-mac*)
|
-mac*)
|
||||||
os=`echo $os | sed -e 's|mac|macos|'`
|
os=`echo $os | sed -e 's|mac|macos|'`
|
||||||
;;
|
;;
|
||||||
-linux-dietlibc)
|
|
||||||
os=-linux-dietlibc
|
|
||||||
;;
|
|
||||||
-linux*)
|
-linux*)
|
||||||
os=`echo $os | sed -e 's|linux|linux-gnu|'`
|
os=`echo $os | sed -e 's|linux|linux-gnu|'`
|
||||||
;;
|
;;
|
||||||
@@ -1415,9 +1176,6 @@ case $os in
|
|||||||
-opened*)
|
-opened*)
|
||||||
os=-openedition
|
os=-openedition
|
||||||
;;
|
;;
|
||||||
-os400*)
|
|
||||||
os=-os400
|
|
||||||
;;
|
|
||||||
-wince*)
|
-wince*)
|
||||||
os=-wince
|
os=-wince
|
||||||
;;
|
;;
|
||||||
@@ -1439,9 +1197,6 @@ case $os in
|
|||||||
-atheos*)
|
-atheos*)
|
||||||
os=-atheos
|
os=-atheos
|
||||||
;;
|
;;
|
||||||
-syllable*)
|
|
||||||
os=-syllable
|
|
||||||
;;
|
|
||||||
-386bsd)
|
-386bsd)
|
||||||
os=-bsd
|
os=-bsd
|
||||||
;;
|
;;
|
||||||
@@ -1464,9 +1219,6 @@ case $os in
|
|||||||
-sinix*)
|
-sinix*)
|
||||||
os=-sysv4
|
os=-sysv4
|
||||||
;;
|
;;
|
||||||
-tpf*)
|
|
||||||
os=-tpf
|
|
||||||
;;
|
|
||||||
-triton*)
|
-triton*)
|
||||||
os=-sysv3
|
os=-sysv3
|
||||||
;;
|
;;
|
||||||
@@ -1500,13 +1252,8 @@ case $os in
|
|||||||
-aros*)
|
-aros*)
|
||||||
os=-aros
|
os=-aros
|
||||||
;;
|
;;
|
||||||
-zvmoe)
|
-kaos*)
|
||||||
os=-zvmoe
|
os=-kaos
|
||||||
;;
|
|
||||||
-dicos*)
|
|
||||||
os=-dicos
|
|
||||||
;;
|
|
||||||
-nacl*)
|
|
||||||
;;
|
;;
|
||||||
-none)
|
-none)
|
||||||
;;
|
;;
|
||||||
@@ -1530,12 +1277,6 @@ 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-*)
|
|
||||||
os=-elf
|
|
||||||
;;
|
|
||||||
spu-*)
|
|
||||||
os=-elf
|
|
||||||
;;
|
|
||||||
*-acorn)
|
*-acorn)
|
||||||
os=-riscix1.2
|
os=-riscix1.2
|
||||||
;;
|
;;
|
||||||
@@ -1548,21 +1289,6 @@ case $basic_machine in
|
|||||||
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-*)
|
||||||
os=-tops20
|
os=-tops20
|
||||||
@@ -1581,22 +1307,19 @@ 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-*)
|
|
||||||
os=-elf
|
|
||||||
;;
|
|
||||||
mips*-cisco)
|
mips*-cisco)
|
||||||
os=-elf
|
os=-elf
|
||||||
;;
|
;;
|
||||||
mips*-*)
|
mips*-*)
|
||||||
os=-elf
|
os=-elf
|
||||||
;;
|
;;
|
||||||
or1k-*)
|
|
||||||
os=-elf
|
|
||||||
;;
|
|
||||||
or32-*)
|
or32-*)
|
||||||
os=-coff
|
os=-coff
|
||||||
;;
|
;;
|
||||||
@@ -1609,15 +1332,9 @@ case $basic_machine in
|
|||||||
*-be)
|
*-be)
|
||||||
os=-beos
|
os=-beos
|
||||||
;;
|
;;
|
||||||
*-haiku)
|
|
||||||
os=-haiku
|
|
||||||
;;
|
|
||||||
*-ibm)
|
*-ibm)
|
||||||
os=-aix
|
os=-aix
|
||||||
;;
|
;;
|
||||||
*-knuth)
|
|
||||||
os=-mmixware
|
|
||||||
;;
|
|
||||||
*-wec)
|
*-wec)
|
||||||
os=-proelf
|
os=-proelf
|
||||||
;;
|
;;
|
||||||
@@ -1720,7 +1437,7 @@ case $basic_machine in
|
|||||||
-sunos*)
|
-sunos*)
|
||||||
vendor=sun
|
vendor=sun
|
||||||
;;
|
;;
|
||||||
-cnk*|-aix*)
|
-aix*)
|
||||||
vendor=ibm
|
vendor=ibm
|
||||||
;;
|
;;
|
||||||
-beos*)
|
-beos*)
|
||||||
@@ -1750,15 +1467,9 @@ case $basic_machine in
|
|||||||
-mvs* | -opened*)
|
-mvs* | -opened*)
|
||||||
vendor=ibm
|
vendor=ibm
|
||||||
;;
|
;;
|
||||||
-os400*)
|
|
||||||
vendor=ibm
|
|
||||||
;;
|
|
||||||
-ptx*)
|
-ptx*)
|
||||||
vendor=sequent
|
vendor=sequent
|
||||||
;;
|
;;
|
||||||
-tpf*)
|
|
||||||
vendor=ibm
|
|
||||||
;;
|
|
||||||
-vxsim* | -vxworks* | -windiss*)
|
-vxsim* | -vxworks* | -windiss*)
|
||||||
vendor=wrs
|
vendor=wrs
|
||||||
;;
|
;;
|
||||||
@@ -1783,7 +1494,7 @@ case $basic_machine in
|
|||||||
esac
|
esac
|
||||||
|
|
||||||
echo $basic_machine$os
|
echo $basic_machine$os
|
||||||
exit
|
exit 0
|
||||||
|
|
||||||
# Local variables:
|
# Local variables:
|
||||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# install - install a program, script, or datafile
|
# install - install a program, script, or datafile
|
||||||
|
|
||||||
scriptversion=2006-10-14.15
|
scriptversion=2003-06-13.21
|
||||||
|
|
||||||
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
||||||
# later released in X11R6 (xc/config/util/install.sh) with the
|
# later released in X11R6 (xc/config/util/install.sh) with the
|
||||||
@@ -39,24 +39,15 @@ scriptversion=2006-10-14.15
|
|||||||
# when there is no Makefile.
|
# when there is no Makefile.
|
||||||
#
|
#
|
||||||
# This script is compatible with the BSD install script, but was written
|
# This script is compatible with the BSD install script, but was written
|
||||||
# from scratch.
|
# from scratch. It can only install one file at a time, a restriction
|
||||||
|
# shared with many OS's install programs.
|
||||||
nl='
|
|
||||||
'
|
|
||||||
IFS=" "" $nl"
|
|
||||||
|
|
||||||
# set DOITPROG to echo to test this script
|
# set DOITPROG to echo to test this script
|
||||||
|
|
||||||
# Don't use :- since 4.3BSD and earlier shells don't like it.
|
# Don't use :- since 4.3BSD and earlier shells don't like it.
|
||||||
doit="${DOITPROG-}"
|
doit="${DOITPROG-}"
|
||||||
if test -z "$doit"; then
|
|
||||||
doit_exec=exec
|
|
||||||
else
|
|
||||||
doit_exec=$doit
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Put in absolute file names if you don't have them in your path;
|
# put in absolute paths if you don't have them in your path; or use env. vars.
|
||||||
# or use environment vars.
|
|
||||||
|
|
||||||
mvprog="${MVPROG-mv}"
|
mvprog="${MVPROG-mv}"
|
||||||
cpprog="${CPPROG-cp}"
|
cpprog="${CPPROG-cp}"
|
||||||
@@ -67,13 +58,10 @@ stripprog="${STRIPPROG-strip}"
|
|||||||
rmprog="${RMPROG-rm}"
|
rmprog="${RMPROG-rm}"
|
||||||
mkdirprog="${MKDIRPROG-mkdir}"
|
mkdirprog="${MKDIRPROG-mkdir}"
|
||||||
|
|
||||||
posix_glob=
|
transformbasename=
|
||||||
posix_mkdir=
|
transform_arg=
|
||||||
|
instcmd="$mvprog"
|
||||||
# Desired mode of installed file.
|
chmodcmd="$chmodprog 0755"
|
||||||
mode=0755
|
|
||||||
|
|
||||||
chmodcmd=$chmodprog
|
|
||||||
chowncmd=
|
chowncmd=
|
||||||
chgrpcmd=
|
chgrpcmd=
|
||||||
stripcmd=
|
stripcmd=
|
||||||
@@ -82,27 +70,22 @@ mvcmd="$mvprog"
|
|||||||
src=
|
src=
|
||||||
dst=
|
dst=
|
||||||
dir_arg=
|
dir_arg=
|
||||||
dstarg=
|
|
||||||
no_target_directory=
|
|
||||||
|
|
||||||
usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
|
usage="Usage: $0 [OPTION]... SRCFILE DSTFILE
|
||||||
or: $0 [OPTION]... SRCFILES... DIRECTORY
|
or: $0 -d DIR1 DIR2...
|
||||||
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
|
|
||||||
or: $0 [OPTION]... -d DIRECTORIES...
|
|
||||||
|
|
||||||
In the 1st form, copy SRCFILE to DSTFILE.
|
In the first form, install SRCFILE to DSTFILE, removing SRCFILE by default.
|
||||||
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
|
In the second, create the directory path DIR.
|
||||||
In the 4th, create DIRECTORIES.
|
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
-c (ignored)
|
-b=TRANSFORMBASENAME
|
||||||
|
-c copy source (using $cpprog) instead of moving (using $mvprog).
|
||||||
-d create directories instead of installing files.
|
-d create directories instead of installing files.
|
||||||
-g GROUP $chgrpprog installed files to GROUP.
|
-g GROUP $chgrp installed files to GROUP.
|
||||||
-m MODE $chmodprog installed files to MODE.
|
-m MODE $chmod installed files to MODE.
|
||||||
-o USER $chownprog installed files to USER.
|
-o USER $chown installed files to USER.
|
||||||
-s $stripprog installed files.
|
-s strip installed files (using $stripprog).
|
||||||
-t DIRECTORY install into DIRECTORY.
|
-t=TRANSFORM
|
||||||
-T report an error if DSTFILE is a directory.
|
|
||||||
--help display this help and exit.
|
--help display this help and exit.
|
||||||
--version display version info and exit.
|
--version display version info and exit.
|
||||||
|
|
||||||
@@ -110,9 +93,14 @@ Environment variables override the default commands:
|
|||||||
CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
|
CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
|
||||||
"
|
"
|
||||||
|
|
||||||
while test $# -ne 0; do
|
while test -n "$1"; do
|
||||||
case $1 in
|
case $1 in
|
||||||
-c) shift
|
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
-c) instcmd=$cpprog
|
||||||
|
shift
|
||||||
continue;;
|
continue;;
|
||||||
|
|
||||||
-d) dir_arg=true
|
-d) dir_arg=true
|
||||||
@@ -124,17 +112,11 @@ while test $# -ne 0; do
|
|||||||
shift
|
shift
|
||||||
continue;;
|
continue;;
|
||||||
|
|
||||||
--help) echo "$usage"; exit $?;;
|
--help) echo "$usage"; exit 0;;
|
||||||
|
|
||||||
-m) mode=$2
|
-m) chmodcmd="$chmodprog $2"
|
||||||
shift
|
shift
|
||||||
shift
|
shift
|
||||||
case $mode in
|
|
||||||
*' '* | *' '* | *'
|
|
||||||
'* | *'*'* | *'?'* | *'['*)
|
|
||||||
echo "$0: invalid mode: $mode" >&2
|
|
||||||
exit 1;;
|
|
||||||
esac
|
|
||||||
continue;;
|
continue;;
|
||||||
|
|
||||||
-o) chowncmd="$chownprog $2"
|
-o) chowncmd="$chownprog $2"
|
||||||
@@ -146,95 +128,41 @@ while test $# -ne 0; do
|
|||||||
shift
|
shift
|
||||||
continue;;
|
continue;;
|
||||||
|
|
||||||
-t) dstarg=$2
|
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
|
||||||
shift
|
|
||||||
shift
|
shift
|
||||||
continue;;
|
continue;;
|
||||||
|
|
||||||
-T) no_target_directory=true
|
--version) echo "$0 $scriptversion"; exit 0;;
|
||||||
|
|
||||||
|
*) if test -z "$src"; then
|
||||||
|
src=$1
|
||||||
|
else
|
||||||
|
# this colon is to work around a 386BSD /bin/sh bug
|
||||||
|
:
|
||||||
|
dst=$1
|
||||||
|
fi
|
||||||
shift
|
shift
|
||||||
continue;;
|
continue;;
|
||||||
|
|
||||||
--version) echo "$0 $scriptversion"; exit $?;;
|
|
||||||
|
|
||||||
--) shift
|
|
||||||
break;;
|
|
||||||
|
|
||||||
-*) echo "$0: invalid option: $1" >&2
|
|
||||||
exit 1;;
|
|
||||||
|
|
||||||
*) break;;
|
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
if test $# -ne 0 && test -z "$dir_arg$dstarg"; then
|
if test -z "$src"; then
|
||||||
# When -d is used, all remaining arguments are directories to create.
|
|
||||||
# When -t is used, the destination is already specified.
|
|
||||||
# Otherwise, the last argument is the destination. Remove it from $@.
|
|
||||||
for arg
|
|
||||||
do
|
|
||||||
if test -n "$dstarg"; then
|
|
||||||
# $@ is not empty: it contains at least $arg.
|
|
||||||
set fnord "$@" "$dstarg"
|
|
||||||
shift # fnord
|
|
||||||
fi
|
|
||||||
shift # arg
|
|
||||||
dstarg=$arg
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test $# -eq 0; then
|
|
||||||
if test -z "$dir_arg"; then
|
|
||||||
echo "$0: no input file specified." >&2
|
echo "$0: no input file specified." >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
# It's OK to call `install-sh -d' without argument.
|
|
||||||
# This can happen when creating conditional directories.
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test -z "$dir_arg"; then
|
|
||||||
trap '(exit $?); exit' 1 2 13 15
|
|
||||||
|
|
||||||
# Set umask so as not to create temps with too-generous modes.
|
|
||||||
# However, 'strip' requires both read and write access to temps.
|
|
||||||
case $mode in
|
|
||||||
# Optimize common cases.
|
|
||||||
*644) cp_umask=133;;
|
|
||||||
*755) cp_umask=22;;
|
|
||||||
|
|
||||||
*[0-7])
|
|
||||||
if test -z "$stripcmd"; then
|
|
||||||
u_plus_rw=
|
|
||||||
else
|
|
||||||
u_plus_rw='% 200'
|
|
||||||
fi
|
|
||||||
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
|
|
||||||
*)
|
|
||||||
if test -z "$stripcmd"; then
|
|
||||||
u_plus_rw=
|
|
||||||
else
|
|
||||||
u_plus_rw=,u+rw
|
|
||||||
fi
|
|
||||||
cp_umask=$mode$u_plus_rw;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
|
|
||||||
for src
|
|
||||||
do
|
|
||||||
# Protect names starting with `-'.
|
|
||||||
case $src in
|
|
||||||
-*) src=./$src ;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if test -n "$dir_arg"; then
|
if test -n "$dir_arg"; then
|
||||||
dst=$src
|
dst=$src
|
||||||
dstdir=$dst
|
src=
|
||||||
test -d "$dstdir"
|
|
||||||
dstdir_status=$?
|
|
||||||
else
|
|
||||||
|
|
||||||
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
|
if test -d "$dst"; then
|
||||||
|
instcmd=:
|
||||||
|
chmodcmd=
|
||||||
|
else
|
||||||
|
instcmd=$mkdirprog
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
|
||||||
# might cause directories to be created, which would be especially bad
|
# might cause directories to be created, which would be especially bad
|
||||||
# if $src (and thus $dsttmp) contains '*'.
|
# if $src (and thus $dsttmp) contains '*'.
|
||||||
if test ! -f "$src" && test ! -d "$src"; then
|
if test ! -f "$src" && test ! -d "$src"; then
|
||||||
@@ -242,248 +170,99 @@ do
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test -z "$dstarg"; then
|
if test -z "$dst"; then
|
||||||
echo "$0: no destination specified." >&2
|
echo "$0: no destination specified." >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
dst=$dstarg
|
|
||||||
# Protect names starting with `-'.
|
|
||||||
case $dst in
|
|
||||||
-*) dst=./$dst ;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# If destination is a directory, append the input filename; won't work
|
# If destination is a directory, append the input filename; won't work
|
||||||
# if double slashes aren't ignored.
|
# if double slashes aren't ignored.
|
||||||
if test -d "$dst"; then
|
if test -d "$dst"; then
|
||||||
if test -n "$no_target_directory"; then
|
dst=$dst/`basename "$src"`
|
||||||
echo "$0: $dstarg: Is a directory" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
dstdir=$dst
|
|
||||||
dst=$dstdir/`basename "$src"`
|
|
||||||
dstdir_status=0
|
|
||||||
else
|
|
||||||
# Prefer dirname, but fall back on a substitute if dirname fails.
|
|
||||||
dstdir=`
|
|
||||||
(dirname "$dst") 2>/dev/null ||
|
|
||||||
expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
|
|
||||||
X"$dst" : 'X\(//\)[^/]' \| \
|
|
||||||
X"$dst" : 'X\(//\)$' \| \
|
|
||||||
X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
|
|
||||||
echo X"$dst" |
|
|
||||||
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
|
|
||||||
s//\1/
|
|
||||||
q
|
|
||||||
}
|
|
||||||
/^X\(\/\/\)[^/].*/{
|
|
||||||
s//\1/
|
|
||||||
q
|
|
||||||
}
|
|
||||||
/^X\(\/\/\)$/{
|
|
||||||
s//\1/
|
|
||||||
q
|
|
||||||
}
|
|
||||||
/^X\(\/\).*/{
|
|
||||||
s//\1/
|
|
||||||
q
|
|
||||||
}
|
|
||||||
s/.*/./; q'
|
|
||||||
`
|
|
||||||
|
|
||||||
test -d "$dstdir"
|
|
||||||
dstdir_status=$?
|
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
obsolete_mkdir_used=false
|
## this sed command emulates the dirname command
|
||||||
|
dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
|
||||||
|
|
||||||
if test $dstdir_status != 0; then
|
# Make sure that the destination directory exists.
|
||||||
case $posix_mkdir in
|
# (this part is taken from Noah Friedman's mkinstalldirs script.)
|
||||||
'')
|
|
||||||
# Create intermediate dirs using mode 755 as modified by the umask.
|
|
||||||
# This is like FreeBSD 'install' as of 1997-10-28.
|
|
||||||
umask=`umask`
|
|
||||||
case $stripcmd.$umask in
|
|
||||||
# Optimize common cases.
|
|
||||||
*[2367][2367]) mkdir_umask=$umask;;
|
|
||||||
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
|
|
||||||
|
|
||||||
*[0-7])
|
# Skip lots of stat calls in the usual case.
|
||||||
mkdir_umask=`expr $umask + 22 \
|
if test ! -d "$dstdir"; then
|
||||||
- $umask % 100 % 40 + $umask % 20 \
|
defaultIFS='
|
||||||
- $umask % 10 % 4 + $umask % 2
|
'
|
||||||
`;;
|
IFS="${IFS-$defaultIFS}"
|
||||||
*) mkdir_umask=$umask,go-w;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# With -d, create the new directory with the user-specified mode.
|
|
||||||
# Otherwise, rely on $mkdir_umask.
|
|
||||||
if test -n "$dir_arg"; then
|
|
||||||
mkdir_mode=-m$mode
|
|
||||||
else
|
|
||||||
mkdir_mode=
|
|
||||||
fi
|
|
||||||
|
|
||||||
posix_mkdir=false
|
|
||||||
case $umask in
|
|
||||||
*[123567][0-7][0-7])
|
|
||||||
# POSIX mkdir -p sets u+wx bits regardless of umask, which
|
|
||||||
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
|
|
||||||
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
|
|
||||||
|
|
||||||
if (umask $mkdir_umask &&
|
|
||||||
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
|
|
||||||
then
|
|
||||||
if test -z "$dir_arg" || {
|
|
||||||
# Check for POSIX incompatibilities with -m.
|
|
||||||
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
|
|
||||||
# other-writeable bit of parent directory when it shouldn't.
|
|
||||||
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
|
|
||||||
ls_ld_tmpdir=`ls -ld "$tmpdir"`
|
|
||||||
case $ls_ld_tmpdir in
|
|
||||||
d????-?r-*) different_mode=700;;
|
|
||||||
d????-?--*) different_mode=755;;
|
|
||||||
*) false;;
|
|
||||||
esac &&
|
|
||||||
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
|
|
||||||
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
|
|
||||||
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
then posix_mkdir=:
|
|
||||||
fi
|
|
||||||
rmdir "$tmpdir/d" "$tmpdir"
|
|
||||||
else
|
|
||||||
# Remove any dirs left behind by ancient mkdir implementations.
|
|
||||||
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
|
|
||||||
fi
|
|
||||||
trap '' 0;;
|
|
||||||
esac;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if
|
|
||||||
$posix_mkdir && (
|
|
||||||
umask $mkdir_umask &&
|
|
||||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
|
|
||||||
)
|
|
||||||
then :
|
|
||||||
else
|
|
||||||
|
|
||||||
# The umask is ridiculous, or mkdir does not conform to POSIX,
|
|
||||||
# or it failed possibly due to a race condition. Create the
|
|
||||||
# directory the slow way, step by step, checking for races as we go.
|
|
||||||
|
|
||||||
case $dstdir in
|
|
||||||
/*) prefix=/ ;;
|
|
||||||
-*) prefix=./ ;;
|
|
||||||
*) prefix= ;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
case $posix_glob in
|
|
||||||
'')
|
|
||||||
if (set -f) 2>/dev/null; then
|
|
||||||
posix_glob=true
|
|
||||||
else
|
|
||||||
posix_glob=false
|
|
||||||
fi ;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
oIFS=$IFS
|
oIFS=$IFS
|
||||||
IFS=/
|
# Some sh's can't handle IFS=/ for some reason.
|
||||||
$posix_glob && set -f
|
IFS='%'
|
||||||
set fnord $dstdir
|
set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
|
||||||
shift
|
|
||||||
$posix_glob && set +f
|
|
||||||
IFS=$oIFS
|
IFS=$oIFS
|
||||||
|
|
||||||
prefixes=
|
pathcomp=
|
||||||
|
|
||||||
for d
|
while test $# -ne 0 ; do
|
||||||
do
|
pathcomp=$pathcomp$1
|
||||||
test -z "$d" && continue
|
shift
|
||||||
|
test -d "$pathcomp" || $mkdirprog "$pathcomp"
|
||||||
prefix=$prefix$d
|
pathcomp=$pathcomp/
|
||||||
if test -d "$prefix"; then
|
|
||||||
prefixes=
|
|
||||||
else
|
|
||||||
if $posix_mkdir; then
|
|
||||||
(umask=$mkdir_umask &&
|
|
||||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
|
|
||||||
# Don't fail if two instances are running concurrently.
|
|
||||||
test -d "$prefix" || exit 1
|
|
||||||
else
|
|
||||||
case $prefix in
|
|
||||||
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
|
|
||||||
*) qprefix=$prefix;;
|
|
||||||
esac
|
|
||||||
prefixes="$prefixes '$qprefix'"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
prefix=$prefix/
|
|
||||||
done
|
done
|
||||||
|
|
||||||
if test -n "$prefixes"; then
|
|
||||||
# Don't fail if two instances are running concurrently.
|
|
||||||
(umask $mkdir_umask &&
|
|
||||||
eval "\$doit_exec \$mkdirprog $prefixes") ||
|
|
||||||
test -d "$dstdir" || exit 1
|
|
||||||
obsolete_mkdir_used=true
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test -n "$dir_arg"; then
|
if test -n "$dir_arg"; then
|
||||||
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
|
$doit $instcmd "$dst" \
|
||||||
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
|
&& { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
|
||||||
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
|
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
|
||||||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
|
&& { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
|
||||||
|
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
|
||||||
|
|
||||||
else
|
else
|
||||||
|
# If we're going to rename the final executable, determine the name now.
|
||||||
|
if test -z "$transformarg"; then
|
||||||
|
dstfile=`basename "$dst"`
|
||||||
|
else
|
||||||
|
dstfile=`basename "$dst" $transformbasename \
|
||||||
|
| sed $transformarg`$transformbasename
|
||||||
|
fi
|
||||||
|
|
||||||
|
# don't allow the sed command to completely eliminate the filename.
|
||||||
|
test -z "$dstfile" && dstfile=`basename "$dst"`
|
||||||
|
|
||||||
# Make a couple of temp file names in the proper directory.
|
# Make a couple of temp file names in the proper directory.
|
||||||
dsttmp=$dstdir/_inst.$$_
|
dsttmp=$dstdir/_inst.$$_
|
||||||
rmtmp=$dstdir/_rm.$$_
|
rmtmp=$dstdir/_rm.$$_
|
||||||
|
|
||||||
# Trap to clean up those temp files at exit.
|
# Trap to clean up those temp files at exit.
|
||||||
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
|
trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0
|
||||||
|
trap '(exit $?); exit' 1 2 13 15
|
||||||
|
|
||||||
# Copy the file name to the temp name.
|
# Move or copy the file name to the temp name
|
||||||
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
|
$doit $instcmd "$src" "$dsttmp" &&
|
||||||
|
|
||||||
# and set any options; do chmod last to preserve setuid bits.
|
# and set any options; do chmod last to preserve setuid bits.
|
||||||
#
|
#
|
||||||
# If any of these fail, we abort the whole thing. If we want to
|
# If any of these fail, we abort the whole thing. If we want to
|
||||||
# ignore errors from any of these, just make sure not to ignore
|
# ignore errors from any of these, just make sure not to ignore
|
||||||
# errors from the above "$doit $cpprog $src $dsttmp" command.
|
# errors from the above "$doit $instcmd $src $dsttmp" command.
|
||||||
#
|
#
|
||||||
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
|
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
|
||||||
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
|
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
|
||||||
&& { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
|
&& { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
|
||||||
&& { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
|
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
|
||||||
|
|
||||||
# Now rename the file to the real destination.
|
# Now remove or move aside any old file at destination location. We
|
||||||
{ $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null \
|
# try this two ways since rm can't unlink itself on some systems and
|
||||||
|| {
|
# the destination file might be busy for other reasons. In this case,
|
||||||
# The rename failed, perhaps because mv can't rename something else
|
# the final cleanup might fail but the new file should still install
|
||||||
# to itself, or perhaps because mv is so ancient that it does not
|
# successfully.
|
||||||
# support -f.
|
|
||||||
|
|
||||||
# Now remove or move aside any old file at destination location.
|
|
||||||
# We try this two ways since rm can't unlink itself on some
|
|
||||||
# systems and the destination file might be busy for other
|
|
||||||
# reasons. In this case, the final cleanup might fail but the new
|
|
||||||
# file should still install successfully.
|
|
||||||
{
|
{
|
||||||
if test -f "$dst"; then
|
if test -f "$dstdir/$dstfile"; then
|
||||||
$doit $rmcmd -f "$dst" 2>/dev/null \
|
$doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
|
||||||
|| { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null \
|
|| $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
|
||||||
&& { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }; }\
|
|
||||||
|| {
|
|| {
|
||||||
echo "$0: cannot unlink or rename $dst" >&2
|
echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
|
||||||
(exit 1); exit 1
|
(exit 1); exit
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
:
|
:
|
||||||
@@ -491,13 +270,13 @@ do
|
|||||||
} &&
|
} &&
|
||||||
|
|
||||||
# Now rename the file to the real destination.
|
# Now rename the file to the real destination.
|
||||||
$doit $mvcmd "$dsttmp" "$dst"
|
$doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
|
||||||
}
|
fi &&
|
||||||
} || exit 1
|
|
||||||
|
|
||||||
trap '' 0
|
# The final little trick to "correctly" pass the exit status to the exit trap.
|
||||||
fi
|
{
|
||||||
done
|
(exit 0); exit
|
||||||
|
}
|
||||||
|
|
||||||
# Local variables:
|
# Local variables:
|
||||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||||
|
|||||||
@@ -1,170 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
# py-compile - Compile a Python program
|
|
||||||
|
|
||||||
scriptversion=2011-06-08.12; # UTC
|
|
||||||
|
|
||||||
# Copyright (C) 2000-2014 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
# any later version.
|
|
||||||
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
# As a special exception to the GNU General Public License, if you
|
|
||||||
# distribute this file as part of a program that contains a
|
|
||||||
# configuration script generated by Autoconf, you may include it under
|
|
||||||
# the same distribution terms that you use for the rest of that program.
|
|
||||||
|
|
||||||
# This file is maintained in Automake, please report
|
|
||||||
# bugs to <bug-automake@gnu.org> or send patches to
|
|
||||||
# <automake-patches@gnu.org>.
|
|
||||||
|
|
||||||
if [ -z "$PYTHON" ]; then
|
|
||||||
PYTHON=python
|
|
||||||
fi
|
|
||||||
|
|
||||||
me=py-compile
|
|
||||||
|
|
||||||
usage_error ()
|
|
||||||
{
|
|
||||||
echo "$me: $*" >&2
|
|
||||||
echo "Try '$me --help' for more information." >&2
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
basedir=
|
|
||||||
destdir=
|
|
||||||
while test $# -ne 0; do
|
|
||||||
case "$1" in
|
|
||||||
--basedir)
|
|
||||||
if test $# -lt 2; then
|
|
||||||
usage_error "option '--basedir' requires an argument"
|
|
||||||
else
|
|
||||||
basedir=$2
|
|
||||||
fi
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
--destdir)
|
|
||||||
if test $# -lt 2; then
|
|
||||||
usage_error "option '--destdir' requires an argument"
|
|
||||||
else
|
|
||||||
destdir=$2
|
|
||||||
fi
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
-h|--help)
|
|
||||||
cat <<\EOF
|
|
||||||
Usage: py-compile [--help] [--version] [--basedir DIR] [--destdir DIR] FILES..."
|
|
||||||
|
|
||||||
Byte compile some python scripts FILES. Use --destdir to specify any
|
|
||||||
leading directory path to the FILES that you don't want to include in the
|
|
||||||
byte compiled file. Specify --basedir for any additional path information you
|
|
||||||
do want to be shown in the byte compiled file.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
py-compile --destdir /tmp/pkg-root --basedir /usr/share/test test.py test2.py
|
|
||||||
|
|
||||||
Report bugs to <bug-automake@gnu.org>.
|
|
||||||
EOF
|
|
||||||
exit $?
|
|
||||||
;;
|
|
||||||
-v|--version)
|
|
||||||
echo "$me $scriptversion"
|
|
||||||
exit $?
|
|
||||||
;;
|
|
||||||
--)
|
|
||||||
shift
|
|
||||||
break
|
|
||||||
;;
|
|
||||||
-*)
|
|
||||||
usage_error "unrecognized option '$1'"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
break
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
shift
|
|
||||||
done
|
|
||||||
|
|
||||||
files=$*
|
|
||||||
if test -z "$files"; then
|
|
||||||
usage_error "no files given"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# if basedir was given, then it should be prepended to filenames before
|
|
||||||
# byte compilation.
|
|
||||||
if [ -z "$basedir" ]; then
|
|
||||||
pathtrans="path = file"
|
|
||||||
else
|
|
||||||
pathtrans="path = os.path.join('$basedir', file)"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# if destdir was given, then it needs to be prepended to the filename to
|
|
||||||
# byte compile but not go into the compiled file.
|
|
||||||
if [ -z "$destdir" ]; then
|
|
||||||
filetrans="filepath = path"
|
|
||||||
else
|
|
||||||
filetrans="filepath = os.path.normpath('$destdir' + os.sep + path)"
|
|
||||||
fi
|
|
||||||
|
|
||||||
$PYTHON -c "
|
|
||||||
import sys, os, py_compile, imp
|
|
||||||
|
|
||||||
files = '''$files'''
|
|
||||||
|
|
||||||
sys.stdout.write('Byte-compiling python modules...\n')
|
|
||||||
for file in files.split():
|
|
||||||
$pathtrans
|
|
||||||
$filetrans
|
|
||||||
if not os.path.exists(filepath) or not (len(filepath) >= 3
|
|
||||||
and filepath[-3:] == '.py'):
|
|
||||||
continue
|
|
||||||
sys.stdout.write(file)
|
|
||||||
sys.stdout.flush()
|
|
||||||
if hasattr(imp, 'get_tag'):
|
|
||||||
py_compile.compile(filepath, imp.cache_from_source(filepath), path)
|
|
||||||
else:
|
|
||||||
py_compile.compile(filepath, filepath + 'c', path)
|
|
||||||
sys.stdout.write('\n')" || exit $?
|
|
||||||
|
|
||||||
# this will fail for python < 1.5, but that doesn't matter ...
|
|
||||||
$PYTHON -O -c "
|
|
||||||
import sys, os, py_compile, imp
|
|
||||||
|
|
||||||
# pypy does not use .pyo optimization
|
|
||||||
if hasattr(sys, 'pypy_translation_info'):
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
files = '''$files'''
|
|
||||||
sys.stdout.write('Byte-compiling python modules (optimized versions) ...\n')
|
|
||||||
for file in files.split():
|
|
||||||
$pathtrans
|
|
||||||
$filetrans
|
|
||||||
if not os.path.exists(filepath) or not (len(filepath) >= 3
|
|
||||||
and filepath[-3:] == '.py'):
|
|
||||||
continue
|
|
||||||
sys.stdout.write(file)
|
|
||||||
sys.stdout.flush()
|
|
||||||
if hasattr(imp, 'get_tag'):
|
|
||||||
py_compile.compile(filepath, imp.cache_from_source(filepath, False), path)
|
|
||||||
else:
|
|
||||||
py_compile.compile(filepath, filepath + 'o', path)
|
|
||||||
sys.stdout.write('\n')" 2>/dev/null || :
|
|
||||||
|
|
||||||
# Local Variables:
|
|
||||||
# mode: shell-script
|
|
||||||
# sh-indentation: 2
|
|
||||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
|
||||||
# time-stamp-start: "scriptversion="
|
|
||||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
|
||||||
# time-stamp-time-zone: "UTC"
|
|
||||||
# time-stamp-end: "; # UTC"
|
|
||||||
# End:
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
# Copyright (C) 2018 Red Hat, Inc. All rights reserved.
|
|
||||||
#
|
|
||||||
# This file is part of the device-mapper userspace tools.
|
|
||||||
#
|
|
||||||
# This copyrighted material is made available to anyone wishing to use,
|
|
||||||
# modify, copy, or redistribute it subject to the terms and conditions
|
|
||||||
# of the GNU Lesser General Public License v.2.1.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation,
|
|
||||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
# Uncomment this to build the simple radix tree. You'll need to make clean too.
|
|
||||||
# Comment to build the advanced radix tree.
|
|
||||||
#base/data-struct/radix-tree.o: CFLAGS += -DSIMPLE_RADIX_TREE
|
|
||||||
|
|
||||||
# NOTE: this Makefile only works as 'include' for toplevel Makefile
|
|
||||||
# which defined all top_* variables
|
|
||||||
|
|
||||||
BASE_SOURCE=\
|
|
||||||
base/data-struct/hash.c \
|
|
||||||
base/data-struct/list.c \
|
|
||||||
base/data-struct/radix-tree.c
|
|
||||||
|
|
||||||
BASE_TARGET = base/libbase.a
|
|
||||||
BASE_DEPENDS = $(BASE_SOURCE:%.c=%.d)
|
|
||||||
BASE_OBJECTS = $(BASE_SOURCE:%.c=%.o)
|
|
||||||
CLEAN_TARGETS += $(BASE_DEPENDS) $(BASE_OBJECTS) \
|
|
||||||
$(BASE_SOURCE:%.c=%.gcda) \
|
|
||||||
$(BASE_SOURCE:%.c=%.gcno) \
|
|
||||||
$(BASE_TARGET)
|
|
||||||
|
|
||||||
$(BASE_TARGET): $(BASE_OBJECTS)
|
|
||||||
@echo " [AR] $@"
|
|
||||||
$(Q) $(RM) $@
|
|
||||||
$(Q) $(AR) rsv $@ $(BASE_OBJECTS) > /dev/null
|
|
||||||
|
|
||||||
ifeq ("$(DEPENDS)","yes")
|
|
||||||
-include $(BASE_DEPENDS)
|
|
||||||
endif
|
|
||||||
@@ -1,477 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
|
||||||
* Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* This file is part of the device-mapper userspace tools.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use,
|
|
||||||
* modify, copy, or redistribute it subject to the terms and conditions
|
|
||||||
* of the GNU Lesser General Public License v.2.1.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this program; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "device_mapper/misc/dmlib.h"
|
|
||||||
#include "base/memory/zalloc.h"
|
|
||||||
#include "hash.h"
|
|
||||||
|
|
||||||
struct dm_hash_node {
|
|
||||||
struct dm_hash_node *next;
|
|
||||||
void *data;
|
|
||||||
unsigned data_len;
|
|
||||||
unsigned keylen;
|
|
||||||
unsigned hash;
|
|
||||||
char key[0];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct dm_hash_table {
|
|
||||||
unsigned num_nodes;
|
|
||||||
unsigned num_hint;
|
|
||||||
unsigned mask_slots; /* (slots - 1) -> used as hash mask */
|
|
||||||
unsigned collisions; /* Collissions of hash keys */
|
|
||||||
unsigned search; /* How many keys were searched */
|
|
||||||
unsigned found; /* How many nodes were found */
|
|
||||||
unsigned same_hash; /* Was there a colision with same masked hash and len ? */
|
|
||||||
struct dm_hash_node **slots;
|
|
||||||
};
|
|
||||||
|
|
||||||
#if 0 /* TO BE REMOVED */
|
|
||||||
static unsigned _hash(const void *key, unsigned len)
|
|
||||||
{
|
|
||||||
/* Permutation of the Integers 0 through 255 */
|
|
||||||
static unsigned char _nums[] = {
|
|
||||||
1, 14, 110, 25, 97, 174, 132, 119, 138, 170, 125, 118, 27, 233, 140, 51,
|
|
||||||
87, 197, 177, 107, 234, 169, 56, 68, 30, 7, 173, 73, 188, 40, 36, 65,
|
|
||||||
49, 213, 104, 190, 57, 211, 148, 223, 48, 115, 15, 2, 67, 186, 210, 28,
|
|
||||||
12, 181, 103, 70, 22, 58, 75, 78, 183, 167, 238, 157, 124, 147, 172,
|
|
||||||
144,
|
|
||||||
176, 161, 141, 86, 60, 66, 128, 83, 156, 241, 79, 46, 168, 198, 41, 254,
|
|
||||||
178, 85, 253, 237, 250, 154, 133, 88, 35, 206, 95, 116, 252, 192, 54,
|
|
||||||
221,
|
|
||||||
102, 218, 255, 240, 82, 106, 158, 201, 61, 3, 89, 9, 42, 155, 159, 93,
|
|
||||||
166, 80, 50, 34, 175, 195, 100, 99, 26, 150, 16, 145, 4, 33, 8, 189,
|
|
||||||
121, 64, 77, 72, 208, 245, 130, 122, 143, 55, 105, 134, 29, 164, 185,
|
|
||||||
194,
|
|
||||||
193, 239, 101, 242, 5, 171, 126, 11, 74, 59, 137, 228, 108, 191, 232,
|
|
||||||
139,
|
|
||||||
6, 24, 81, 20, 127, 17, 91, 92, 251, 151, 225, 207, 21, 98, 113, 112,
|
|
||||||
84, 226, 18, 214, 199, 187, 13, 32, 94, 220, 224, 212, 247, 204, 196,
|
|
||||||
43,
|
|
||||||
249, 236, 45, 244, 111, 182, 153, 136, 129, 90, 217, 202, 19, 165, 231,
|
|
||||||
71,
|
|
||||||
230, 142, 96, 227, 62, 179, 246, 114, 162, 53, 160, 215, 205, 180, 47,
|
|
||||||
109,
|
|
||||||
44, 38, 31, 149, 135, 0, 216, 52, 63, 23, 37, 69, 39, 117, 146, 184,
|
|
||||||
163, 200, 222, 235, 248, 243, 219, 10, 152, 131, 123, 229, 203, 76, 120,
|
|
||||||
209
|
|
||||||
};
|
|
||||||
|
|
||||||
const uint8_t *str = key;
|
|
||||||
unsigned h = 0, g;
|
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
for (i = 0; i < len; i++) {
|
|
||||||
h <<= 4;
|
|
||||||
h += _nums[*str++];
|
|
||||||
g = h & ((unsigned) 0xf << 16u);
|
|
||||||
if (g) {
|
|
||||||
h ^= g >> 16u;
|
|
||||||
h ^= g >> 5u;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return h;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* In-kernel DM hashing, still lots of collisions */
|
|
||||||
static unsigned _hash_in_kernel(const char *key, unsigned len)
|
|
||||||
{
|
|
||||||
const unsigned char *str = (unsigned char *)key;
|
|
||||||
const unsigned hash_mult = 2654435387U;
|
|
||||||
unsigned hash = 0, i;
|
|
||||||
|
|
||||||
for (i = 0; i < len; ++i)
|
|
||||||
hash = (hash + str[i]) * hash_mult;
|
|
||||||
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#undef get16bits
|
|
||||||
#if (defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)))
|
|
||||||
#define get16bits(d) (*((const uint16_t *) (d)))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined (get16bits)
|
|
||||||
#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\
|
|
||||||
+(uint32_t)(((const uint8_t *)(d))[0]) )
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Adapted Bob Jenkins hash to read by 2 bytes if possible.
|
|
||||||
* https://secure.wikimedia.org/wikipedia/en/wiki/Jenkins_hash_function
|
|
||||||
*
|
|
||||||
* Reduces amount of hash collisions
|
|
||||||
*/
|
|
||||||
static unsigned _hash(const void *key, unsigned len)
|
|
||||||
{
|
|
||||||
const uint8_t *str = (uint8_t*) key;
|
|
||||||
unsigned hash = 0, i;
|
|
||||||
unsigned sz = len / 2;
|
|
||||||
|
|
||||||
for(i = 0; i < sz; ++i) {
|
|
||||||
hash += get16bits(str + 2 * i);
|
|
||||||
hash += (hash << 10);
|
|
||||||
hash ^= (hash >> 6);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (len & 1) {
|
|
||||||
hash += str[len - 1];
|
|
||||||
hash += (hash << 10);
|
|
||||||
hash ^= (hash >> 6);
|
|
||||||
}
|
|
||||||
|
|
||||||
hash += (hash << 3);
|
|
||||||
hash ^= (hash >> 11);
|
|
||||||
hash += (hash << 15);
|
|
||||||
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct dm_hash_node *_create_node(const void *key, unsigned len)
|
|
||||||
{
|
|
||||||
struct dm_hash_node *n = malloc(sizeof(*n) + len);
|
|
||||||
|
|
||||||
if (n) {
|
|
||||||
memcpy(n->key, key, len);
|
|
||||||
n->keylen = len;
|
|
||||||
}
|
|
||||||
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct dm_hash_table *dm_hash_create(unsigned size_hint)
|
|
||||||
{
|
|
||||||
size_t len;
|
|
||||||
unsigned new_size = 16u;
|
|
||||||
struct dm_hash_table *hc = zalloc(sizeof(*hc));
|
|
||||||
|
|
||||||
if (!hc) {
|
|
||||||
log_error("Failed to allocate memory for hash.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
hc->num_hint = size_hint;
|
|
||||||
|
|
||||||
/* round size hint up to a power of two */
|
|
||||||
while (new_size < size_hint)
|
|
||||||
new_size = new_size << 1;
|
|
||||||
|
|
||||||
hc->mask_slots = new_size - 1;
|
|
||||||
len = sizeof(*(hc->slots)) * new_size;
|
|
||||||
if (!(hc->slots = zalloc(len))) {
|
|
||||||
free(hc);
|
|
||||||
log_error("Failed to allocate slots for hash.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return hc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _free_nodes(struct dm_hash_table *t)
|
|
||||||
{
|
|
||||||
struct dm_hash_node *c, *n;
|
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
log_debug("Free hash hint:%d slots:%d nodes:%d (s:%d f:%d c:%d h:%d)",
|
|
||||||
t->num_hint, t->mask_slots + 1, t->num_nodes,
|
|
||||||
t->search, t->found, t->collisions, t->same_hash);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!t->num_nodes)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (i = 0; i <= t->mask_slots; i++)
|
|
||||||
for (c = t->slots[i]; c; c = n) {
|
|
||||||
n = c->next;
|
|
||||||
free(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void dm_hash_destroy(struct dm_hash_table *t)
|
|
||||||
{
|
|
||||||
_free_nodes(t);
|
|
||||||
free(t->slots);
|
|
||||||
free(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct dm_hash_node **_findh(struct dm_hash_table *t, const void *key,
|
|
||||||
uint32_t len, unsigned hash)
|
|
||||||
{
|
|
||||||
struct dm_hash_node **c;
|
|
||||||
|
|
||||||
++t->search;
|
|
||||||
for (c = &t->slots[hash & t->mask_slots]; *c; c = &((*c)->next)) {
|
|
||||||
if ((*c)->keylen == len && (*c)->hash == hash) {
|
|
||||||
if (!memcmp(key, (*c)->key, len)) {
|
|
||||||
++t->found;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
++t->same_hash;
|
|
||||||
}
|
|
||||||
++t->collisions;
|
|
||||||
}
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct dm_hash_node **_find(struct dm_hash_table *t, const void *key,
|
|
||||||
uint32_t len)
|
|
||||||
{
|
|
||||||
return _findh(t, key, len, _hash(key, len));
|
|
||||||
}
|
|
||||||
|
|
||||||
void *dm_hash_lookup_binary(struct dm_hash_table *t, const void *key,
|
|
||||||
uint32_t len)
|
|
||||||
{
|
|
||||||
struct dm_hash_node **c = _find(t, key, len);
|
|
||||||
|
|
||||||
return *c ? (*c)->data : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int dm_hash_insert_binary(struct dm_hash_table *t, const void *key,
|
|
||||||
uint32_t len, void *data)
|
|
||||||
{
|
|
||||||
unsigned hash = _hash(key, len);
|
|
||||||
struct dm_hash_node **c = _findh(t, key, len, hash);
|
|
||||||
|
|
||||||
if (*c)
|
|
||||||
(*c)->data = data;
|
|
||||||
else {
|
|
||||||
struct dm_hash_node *n = _create_node(key, len);
|
|
||||||
|
|
||||||
if (!n)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
n->data = data;
|
|
||||||
n->hash = hash;
|
|
||||||
n->next = 0;
|
|
||||||
*c = n;
|
|
||||||
t->num_nodes++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dm_hash_remove_binary(struct dm_hash_table *t, const void *key,
|
|
||||||
uint32_t len)
|
|
||||||
{
|
|
||||||
struct dm_hash_node **c = _find(t, key, len);
|
|
||||||
|
|
||||||
if (*c) {
|
|
||||||
struct dm_hash_node *old = *c;
|
|
||||||
*c = (*c)->next;
|
|
||||||
free(old);
|
|
||||||
t->num_nodes--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void *dm_hash_lookup(struct dm_hash_table *t, const char *key)
|
|
||||||
{
|
|
||||||
return dm_hash_lookup_binary(t, key, strlen(key) + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int dm_hash_insert(struct dm_hash_table *t, const char *key, void *data)
|
|
||||||
{
|
|
||||||
return dm_hash_insert_binary(t, key, strlen(key) + 1, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void dm_hash_remove(struct dm_hash_table *t, const char *key)
|
|
||||||
{
|
|
||||||
dm_hash_remove_binary(t, key, strlen(key) + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct dm_hash_node **_find_str_with_val(struct dm_hash_table *t,
|
|
||||||
const void *key, const void *val,
|
|
||||||
uint32_t len, uint32_t val_len)
|
|
||||||
{
|
|
||||||
struct dm_hash_node **c;
|
|
||||||
unsigned h;
|
|
||||||
|
|
||||||
h = _hash(key, len) & t->mask_slots;
|
|
||||||
|
|
||||||
for (c = &t->slots[h]; *c; c = &((*c)->next)) {
|
|
||||||
if ((*c)->keylen != len)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!memcmp(key, (*c)->key, len) && (*c)->data) {
|
|
||||||
if (((*c)->data_len == val_len) &&
|
|
||||||
!memcmp(val, (*c)->data, val_len))
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int dm_hash_insert_allow_multiple(struct dm_hash_table *t, const char *key,
|
|
||||||
const void *val, uint32_t val_len)
|
|
||||||
{
|
|
||||||
struct dm_hash_node *n;
|
|
||||||
struct dm_hash_node *first;
|
|
||||||
int len = strlen(key) + 1;
|
|
||||||
unsigned h;
|
|
||||||
|
|
||||||
n = _create_node(key, len);
|
|
||||||
if (!n)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
n->data = (void *)val;
|
|
||||||
n->data_len = val_len;
|
|
||||||
|
|
||||||
h = _hash(key, len) & t->mask_slots;
|
|
||||||
|
|
||||||
first = t->slots[h];
|
|
||||||
|
|
||||||
if (first)
|
|
||||||
n->next = first;
|
|
||||||
else
|
|
||||||
n->next = 0;
|
|
||||||
t->slots[h] = n;
|
|
||||||
|
|
||||||
t->num_nodes++;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Look through multiple entries with the same key for one that has a
|
|
||||||
* matching val and return that. If none have maching val, return NULL.
|
|
||||||
*/
|
|
||||||
void *dm_hash_lookup_with_val(struct dm_hash_table *t, const char *key,
|
|
||||||
const void *val, uint32_t val_len)
|
|
||||||
{
|
|
||||||
struct dm_hash_node **c;
|
|
||||||
|
|
||||||
c = _find_str_with_val(t, key, val, strlen(key) + 1, val_len);
|
|
||||||
|
|
||||||
return (c && *c) ? (*c)->data : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Look through multiple entries with the same key for one that has a
|
|
||||||
* matching val and remove that.
|
|
||||||
*/
|
|
||||||
void dm_hash_remove_with_val(struct dm_hash_table *t, const char *key,
|
|
||||||
const void *val, uint32_t val_len)
|
|
||||||
{
|
|
||||||
struct dm_hash_node **c;
|
|
||||||
|
|
||||||
c = _find_str_with_val(t, key, val, strlen(key) + 1, val_len);
|
|
||||||
|
|
||||||
if (c && *c) {
|
|
||||||
struct dm_hash_node *old = *c;
|
|
||||||
*c = (*c)->next;
|
|
||||||
free(old);
|
|
||||||
t->num_nodes--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Look up the value for a key and count how many
|
|
||||||
* entries have the same key.
|
|
||||||
*
|
|
||||||
* If no entries have key, return NULL and set count to 0.
|
|
||||||
*
|
|
||||||
* If one entry has the key, the function returns the val,
|
|
||||||
* and sets count to 1.
|
|
||||||
*
|
|
||||||
* If N entries have the key, the function returns the val
|
|
||||||
* from the first entry, and sets count to N.
|
|
||||||
*/
|
|
||||||
void *dm_hash_lookup_with_count(struct dm_hash_table *t, const char *key, int *count)
|
|
||||||
{
|
|
||||||
struct dm_hash_node **c;
|
|
||||||
struct dm_hash_node **c1 = NULL;
|
|
||||||
uint32_t len = strlen(key) + 1;
|
|
||||||
unsigned h;
|
|
||||||
|
|
||||||
*count = 0;
|
|
||||||
|
|
||||||
h = _hash(key, len) & t->mask_slots;
|
|
||||||
|
|
||||||
for (c = &t->slots[h]; *c; c = &((*c)->next)) {
|
|
||||||
if ((*c)->keylen != len)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!memcmp(key, (*c)->key, len)) {
|
|
||||||
(*count)++;
|
|
||||||
if (!c1)
|
|
||||||
c1 = c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!c1)
|
|
||||||
return NULL;
|
|
||||||
else
|
|
||||||
return *c1 ? (*c1)->data : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned dm_hash_get_num_entries(struct dm_hash_table *t)
|
|
||||||
{
|
|
||||||
return t->num_nodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dm_hash_iter(struct dm_hash_table *t, dm_hash_iterate_fn f)
|
|
||||||
{
|
|
||||||
struct dm_hash_node *c, *n;
|
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
for (i = 0; i <= t->mask_slots; i++)
|
|
||||||
for (c = t->slots[i]; c; c = n) {
|
|
||||||
n = c->next;
|
|
||||||
f(c->data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void dm_hash_wipe(struct dm_hash_table *t)
|
|
||||||
{
|
|
||||||
_free_nodes(t);
|
|
||||||
memset(t->slots, 0, sizeof(struct dm_hash_node *) * (t->mask_slots + 1));
|
|
||||||
t->num_nodes = t->collisions = t->search = t->same_hash = 0u;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *dm_hash_get_key(struct dm_hash_table *t __attribute__((unused)),
|
|
||||||
struct dm_hash_node *n)
|
|
||||||
{
|
|
||||||
return n->key;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *dm_hash_get_data(struct dm_hash_table *t __attribute__((unused)),
|
|
||||||
struct dm_hash_node *n)
|
|
||||||
{
|
|
||||||
return n->data;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct dm_hash_node *_next_slot(struct dm_hash_table *t, unsigned s)
|
|
||||||
{
|
|
||||||
struct dm_hash_node *c = NULL;
|
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
for (i = s; i <= t->mask_slots && !c; i++)
|
|
||||||
c = t->slots[i];
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct dm_hash_node *dm_hash_get_first(struct dm_hash_table *t)
|
|
||||||
{
|
|
||||||
return _next_slot(t, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct dm_hash_node *dm_hash_get_next(struct dm_hash_table *t, struct dm_hash_node *n)
|
|
||||||
{
|
|
||||||
return n->next ? n->next : _next_slot(t, (n->hash & t->mask_slots) + 1);
|
|
||||||
}
|
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
#ifndef BASE_DATA_STRUCT_HASH_H
|
|
||||||
#define BASE_DATA_STRUCT_HASH_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
|
||||||
|
|
||||||
struct dm_hash_table;
|
|
||||||
struct dm_hash_node;
|
|
||||||
|
|
||||||
typedef void (*dm_hash_iterate_fn) (void *data);
|
|
||||||
|
|
||||||
struct dm_hash_table *dm_hash_create(unsigned size_hint)
|
|
||||||
__attribute__((__warn_unused_result__));
|
|
||||||
void dm_hash_destroy(struct dm_hash_table *t);
|
|
||||||
void dm_hash_wipe(struct dm_hash_table *t);
|
|
||||||
|
|
||||||
void *dm_hash_lookup(struct dm_hash_table *t, const char *key);
|
|
||||||
int dm_hash_insert(struct dm_hash_table *t, const char *key, void *data);
|
|
||||||
void dm_hash_remove(struct dm_hash_table *t, const char *key);
|
|
||||||
|
|
||||||
void *dm_hash_lookup_binary(struct dm_hash_table *t, const void *key, uint32_t len);
|
|
||||||
int dm_hash_insert_binary(struct dm_hash_table *t, const void *key, uint32_t len,
|
|
||||||
void *data);
|
|
||||||
void dm_hash_remove_binary(struct dm_hash_table *t, const void *key, uint32_t len);
|
|
||||||
|
|
||||||
unsigned dm_hash_get_num_entries(struct dm_hash_table *t);
|
|
||||||
void dm_hash_iter(struct dm_hash_table *t, dm_hash_iterate_fn f);
|
|
||||||
|
|
||||||
char *dm_hash_get_key(struct dm_hash_table *t, struct dm_hash_node *n);
|
|
||||||
void *dm_hash_get_data(struct dm_hash_table *t, struct dm_hash_node *n);
|
|
||||||
struct dm_hash_node *dm_hash_get_first(struct dm_hash_table *t);
|
|
||||||
struct dm_hash_node *dm_hash_get_next(struct dm_hash_table *t, struct dm_hash_node *n);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* dm_hash_insert() replaces the value of an existing
|
|
||||||
* entry with a matching key if one exists. Otherwise
|
|
||||||
* it adds a new entry.
|
|
||||||
*
|
|
||||||
* dm_hash_insert_with_val() inserts a new entry if
|
|
||||||
* another entry with the same key already exists.
|
|
||||||
* val_len is the size of the data being inserted.
|
|
||||||
*
|
|
||||||
* If two entries with the same key exist,
|
|
||||||
* (added using dm_hash_insert_allow_multiple), then:
|
|
||||||
* . dm_hash_lookup() returns the first one it finds, and
|
|
||||||
* dm_hash_lookup_with_val() returns the one with a matching
|
|
||||||
* val_len/val.
|
|
||||||
* . dm_hash_remove() removes the first one it finds, and
|
|
||||||
* dm_hash_remove_with_val() removes the one with a matching
|
|
||||||
* val_len/val.
|
|
||||||
*
|
|
||||||
* If a single entry with a given key exists, and it has
|
|
||||||
* zero val_len, then:
|
|
||||||
* . dm_hash_lookup() returns it
|
|
||||||
* . dm_hash_lookup_with_val(val_len=0) returns it
|
|
||||||
* . dm_hash_remove() removes it
|
|
||||||
* . dm_hash_remove_with_val(val_len=0) removes it
|
|
||||||
*
|
|
||||||
* dm_hash_lookup_with_count() is a single call that will
|
|
||||||
* both lookup a key's value and check if there is more
|
|
||||||
* than one entry with the given key.
|
|
||||||
*
|
|
||||||
* (It is not meant to retrieve all the entries with the
|
|
||||||
* given key. In the common case where a single entry exists
|
|
||||||
* for the key, it is useful to have a single call that will
|
|
||||||
* both look up the value and indicate if multiple values
|
|
||||||
* exist for the key.)
|
|
||||||
*
|
|
||||||
* dm_hash_lookup_with_count:
|
|
||||||
* . If no entries exist, the function returns NULL, and
|
|
||||||
* the count is set to 0.
|
|
||||||
* . If only one entry exists, the value of that entry is
|
|
||||||
* returned and count is set to 1.
|
|
||||||
* . If N entries exists, the value of the first entry is
|
|
||||||
* returned and count is set to N.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void *dm_hash_lookup_with_val(struct dm_hash_table *t, const char *key,
|
|
||||||
const void *val, uint32_t val_len);
|
|
||||||
void dm_hash_remove_with_val(struct dm_hash_table *t, const char *key,
|
|
||||||
const void *val, uint32_t val_len);
|
|
||||||
int dm_hash_insert_allow_multiple(struct dm_hash_table *t, const char *key,
|
|
||||||
const void *val, uint32_t val_len);
|
|
||||||
void *dm_hash_lookup_with_count(struct dm_hash_table *t, const char *key, int *count);
|
|
||||||
|
|
||||||
|
|
||||||
#define dm_hash_iterate(v, h) \
|
|
||||||
for (v = dm_hash_get_first((h)); v; \
|
|
||||||
v = dm_hash_get_next((h), v))
|
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,170 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
|
||||||
* Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* This file is part of LVM2.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use,
|
|
||||||
* modify, copy, or redistribute it subject to the terms and conditions
|
|
||||||
* of the GNU 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "list.h"
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialise a list before use.
|
|
||||||
* The list head's next and previous pointers point back to itself.
|
|
||||||
*/
|
|
||||||
void dm_list_init(struct dm_list *head)
|
|
||||||
{
|
|
||||||
head->n = head->p = head;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Insert an element before 'head'.
|
|
||||||
* If 'head' is the list head, this adds an element to the end of the list.
|
|
||||||
*/
|
|
||||||
void dm_list_add(struct dm_list *head, struct dm_list *elem)
|
|
||||||
{
|
|
||||||
assert(head->n);
|
|
||||||
|
|
||||||
elem->n = head;
|
|
||||||
elem->p = head->p;
|
|
||||||
|
|
||||||
head->p->n = elem;
|
|
||||||
head->p = elem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Insert an element after 'head'.
|
|
||||||
* If 'head' is the list head, this adds an element to the front of the list.
|
|
||||||
*/
|
|
||||||
void dm_list_add_h(struct dm_list *head, struct dm_list *elem)
|
|
||||||
{
|
|
||||||
assert(head->n);
|
|
||||||
|
|
||||||
elem->n = head->n;
|
|
||||||
elem->p = head;
|
|
||||||
|
|
||||||
head->n->p = elem;
|
|
||||||
head->n = elem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Delete an element from its list.
|
|
||||||
* Note that this doesn't change the element itself - it may still be safe
|
|
||||||
* to follow its pointers.
|
|
||||||
*/
|
|
||||||
void dm_list_del(struct dm_list *elem)
|
|
||||||
{
|
|
||||||
elem->n->p = elem->p;
|
|
||||||
elem->p->n = elem->n;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Remove an element from existing list and insert before 'head'.
|
|
||||||
*/
|
|
||||||
void dm_list_move(struct dm_list *head, struct dm_list *elem)
|
|
||||||
{
|
|
||||||
dm_list_del(elem);
|
|
||||||
dm_list_add(head, elem);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Is the list empty?
|
|
||||||
*/
|
|
||||||
int dm_list_empty(const struct dm_list *head)
|
|
||||||
{
|
|
||||||
return head->n == head;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Is this the first element of the list?
|
|
||||||
*/
|
|
||||||
int dm_list_start(const struct dm_list *head, const struct dm_list *elem)
|
|
||||||
{
|
|
||||||
return elem->p == head;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Is this the last element of the list?
|
|
||||||
*/
|
|
||||||
int dm_list_end(const struct dm_list *head, const struct dm_list *elem)
|
|
||||||
{
|
|
||||||
return elem->n == head;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return first element of the list or NULL if empty
|
|
||||||
*/
|
|
||||||
struct dm_list *dm_list_first(const struct dm_list *head)
|
|
||||||
{
|
|
||||||
return (dm_list_empty(head) ? NULL : head->n);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return last element of the list or NULL if empty
|
|
||||||
*/
|
|
||||||
struct dm_list *dm_list_last(const struct dm_list *head)
|
|
||||||
{
|
|
||||||
return (dm_list_empty(head) ? NULL : head->p);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return the previous element of the list, or NULL if we've reached the start.
|
|
||||||
*/
|
|
||||||
struct dm_list *dm_list_prev(const struct dm_list *head, const struct dm_list *elem)
|
|
||||||
{
|
|
||||||
return (dm_list_start(head, elem) ? NULL : elem->p);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return the next element of the list, or NULL if we've reached the end.
|
|
||||||
*/
|
|
||||||
struct dm_list *dm_list_next(const struct dm_list *head, const struct dm_list *elem)
|
|
||||||
{
|
|
||||||
return (dm_list_end(head, elem) ? NULL : elem->n);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return the number of elements in a list by walking it.
|
|
||||||
*/
|
|
||||||
unsigned int dm_list_size(const struct dm_list *head)
|
|
||||||
{
|
|
||||||
unsigned int s = 0;
|
|
||||||
const struct dm_list *v;
|
|
||||||
|
|
||||||
dm_list_iterate(v, head)
|
|
||||||
s++;
|
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Join two lists together.
|
|
||||||
* This moves all the elements of the list 'head1' to the end of the list
|
|
||||||
* 'head', leaving 'head1' empty.
|
|
||||||
*/
|
|
||||||
void dm_list_splice(struct dm_list *head, struct dm_list *head1)
|
|
||||||
{
|
|
||||||
assert(head->n);
|
|
||||||
assert(head1->n);
|
|
||||||
|
|
||||||
if (dm_list_empty(head1))
|
|
||||||
return;
|
|
||||||
|
|
||||||
head1->p->n = head;
|
|
||||||
head1->n->p = head->p;
|
|
||||||
|
|
||||||
head->p->n = head1->n;
|
|
||||||
head->p = head1->p;
|
|
||||||
|
|
||||||
dm_list_init(head1);
|
|
||||||
}
|
|
||||||
@@ -1,211 +0,0 @@
|
|||||||
#ifndef BASE_DATA_STRUCT_LIST_H
|
|
||||||
#define BASE_DATA_STRUCT_LIST_H
|
|
||||||
|
|
||||||
#include "base/memory/container_of.h"
|
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
|
||||||
|
|
||||||
/*
|
|
||||||
* A list consists of a list head plus elements.
|
|
||||||
* Each element has 'next' and 'previous' pointers.
|
|
||||||
* The list head's pointers point to the first and the last element.
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct dm_list {
|
|
||||||
struct dm_list *n, *p;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* String list.
|
|
||||||
*/
|
|
||||||
struct dm_str_list {
|
|
||||||
struct dm_list list;
|
|
||||||
const char *str;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialise a list before use.
|
|
||||||
* The list head's next and previous pointers point back to itself.
|
|
||||||
*/
|
|
||||||
#define DM_LIST_HEAD_INIT(name) { &(name), &(name) }
|
|
||||||
#define DM_LIST_INIT(name) struct dm_list name = DM_LIST_HEAD_INIT(name)
|
|
||||||
void dm_list_init(struct dm_list *head);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Insert an element before 'head'.
|
|
||||||
* If 'head' is the list head, this adds an element to the end of the list.
|
|
||||||
*/
|
|
||||||
void dm_list_add(struct dm_list *head, struct dm_list *elem);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Insert an element after 'head'.
|
|
||||||
* If 'head' is the list head, this adds an element to the front of the list.
|
|
||||||
*/
|
|
||||||
void dm_list_add_h(struct dm_list *head, struct dm_list *elem);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Delete an element from its list.
|
|
||||||
* Note that this doesn't change the element itself - it may still be safe
|
|
||||||
* to follow its pointers.
|
|
||||||
*/
|
|
||||||
void dm_list_del(struct dm_list *elem);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Remove an element from existing list and insert before 'head'.
|
|
||||||
*/
|
|
||||||
void dm_list_move(struct dm_list *head, struct dm_list *elem);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Join 'head1' to the end of 'head'.
|
|
||||||
*/
|
|
||||||
void dm_list_splice(struct dm_list *head, struct dm_list *head1);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Is the list empty?
|
|
||||||
*/
|
|
||||||
int dm_list_empty(const struct dm_list *head);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Is this the first element of the list?
|
|
||||||
*/
|
|
||||||
int dm_list_start(const struct dm_list *head, const struct dm_list *elem);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Is this the last element of the list?
|
|
||||||
*/
|
|
||||||
int dm_list_end(const struct dm_list *head, const struct dm_list *elem);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return first element of the list or NULL if empty
|
|
||||||
*/
|
|
||||||
struct dm_list *dm_list_first(const struct dm_list *head);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return last element of the list or NULL if empty
|
|
||||||
*/
|
|
||||||
struct dm_list *dm_list_last(const struct dm_list *head);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return the previous element of the list, or NULL if we've reached the start.
|
|
||||||
*/
|
|
||||||
struct dm_list *dm_list_prev(const struct dm_list *head, const struct dm_list *elem);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return the next element of the list, or NULL if we've reached the end.
|
|
||||||
*/
|
|
||||||
struct dm_list *dm_list_next(const struct dm_list *head, const struct dm_list *elem);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Given the address v of an instance of 'struct dm_list' called 'head'
|
|
||||||
* contained in a structure of type t, return the containing structure.
|
|
||||||
*/
|
|
||||||
#define dm_list_struct_base(v, t, head) \
|
|
||||||
container_of(v, t, head)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Given the address v of an instance of 'struct dm_list list' contained in
|
|
||||||
* a structure of type t, return the containing structure.
|
|
||||||
*/
|
|
||||||
#define dm_list_item(v, t) dm_list_struct_base((v), t, list)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Given the address v of one known element e in a known structure of type t,
|
|
||||||
* return another element f.
|
|
||||||
*/
|
|
||||||
#define dm_struct_field(v, t, e, f) \
|
|
||||||
(((t *)((uintptr_t)(v) - offsetof(t, e)))->f)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Given the address v of a known element e in a known structure of type t,
|
|
||||||
* return the list head 'list'
|
|
||||||
*/
|
|
||||||
#define dm_list_head(v, t, e) dm_struct_field(v, t, e, list)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set v to each element of a list in turn.
|
|
||||||
*/
|
|
||||||
#define dm_list_iterate(v, head) \
|
|
||||||
for (v = (head)->n; v != head; v = v->n)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set v to each element in a list in turn, starting from the element
|
|
||||||
* in front of 'start'.
|
|
||||||
* You can use this to 'unwind' a list_iterate and back out actions on
|
|
||||||
* already-processed elements.
|
|
||||||
* If 'start' is 'head' it walks the list backwards.
|
|
||||||
*/
|
|
||||||
#define dm_list_uniterate(v, head, start) \
|
|
||||||
for (v = (start)->p; v != head; v = v->p)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* A safe way to walk a list and delete and free some elements along
|
|
||||||
* the way.
|
|
||||||
* t must be defined as a temporary variable of the same type as v.
|
|
||||||
*/
|
|
||||||
#define dm_list_iterate_safe(v, t, head) \
|
|
||||||
for (v = (head)->n, t = v->n; v != head; v = t, t = v->n)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Walk a list, setting 'v' in turn to the containing structure of each item.
|
|
||||||
* The containing structure should be the same type as 'v'.
|
|
||||||
* The 'struct dm_list' variable within the containing structure is 'field'.
|
|
||||||
*/
|
|
||||||
#define dm_list_iterate_items_gen(v, head, field) \
|
|
||||||
for (v = dm_list_struct_base((head)->n, __typeof__(*v), field); \
|
|
||||||
&v->field != (head); \
|
|
||||||
v = dm_list_struct_base(v->field.n, __typeof__(*v), field))
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Walk a list, setting 'v' in turn to the containing structure of each item.
|
|
||||||
* The containing structure should be the same type as 'v'.
|
|
||||||
* The list should be 'struct dm_list list' within the containing structure.
|
|
||||||
*/
|
|
||||||
#define dm_list_iterate_items(v, head) dm_list_iterate_items_gen(v, (head), list)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Walk a list, setting 'v' in turn to the containing structure of each item.
|
|
||||||
* The containing structure should be the same type as 'v'.
|
|
||||||
* The 'struct dm_list' variable within the containing structure is 'field'.
|
|
||||||
* t must be defined as a temporary variable of the same type as v.
|
|
||||||
*/
|
|
||||||
#define dm_list_iterate_items_gen_safe(v, t, head, field) \
|
|
||||||
for (v = dm_list_struct_base((head)->n, __typeof__(*v), field), \
|
|
||||||
t = dm_list_struct_base(v->field.n, __typeof__(*v), field); \
|
|
||||||
&v->field != (head); \
|
|
||||||
v = t, t = dm_list_struct_base(v->field.n, __typeof__(*v), field))
|
|
||||||
/*
|
|
||||||
* Walk a list, setting 'v' in turn to the containing structure of each item.
|
|
||||||
* The containing structure should be the same type as 'v'.
|
|
||||||
* The list should be 'struct dm_list list' within the containing structure.
|
|
||||||
* t must be defined as a temporary variable of the same type as v.
|
|
||||||
*/
|
|
||||||
#define dm_list_iterate_items_safe(v, t, head) \
|
|
||||||
dm_list_iterate_items_gen_safe(v, t, (head), list)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Walk a list backwards, setting 'v' in turn to the containing structure
|
|
||||||
* of each item.
|
|
||||||
* The containing structure should be the same type as 'v'.
|
|
||||||
* The 'struct dm_list' variable within the containing structure is 'field'.
|
|
||||||
*/
|
|
||||||
#define dm_list_iterate_back_items_gen(v, head, field) \
|
|
||||||
for (v = dm_list_struct_base((head)->p, __typeof__(*v), field); \
|
|
||||||
&v->field != (head); \
|
|
||||||
v = dm_list_struct_base(v->field.p, __typeof__(*v), field))
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Walk a list backwards, setting 'v' in turn to the containing structure
|
|
||||||
* of each item.
|
|
||||||
* The containing structure should be the same type as 'v'.
|
|
||||||
* The list should be 'struct dm_list list' within the containing structure.
|
|
||||||
*/
|
|
||||||
#define dm_list_iterate_back_items(v, head) dm_list_iterate_back_items_gen(v, (head), list)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return the number of elements in a list by walking it.
|
|
||||||
*/
|
|
||||||
unsigned int dm_list_size(const struct dm_list *head);
|
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
|
||||||
|
|
||||||
#endif
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,256 +0,0 @@
|
|||||||
// Copyright (C) 2018 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
#include "radix-tree.h"
|
|
||||||
|
|
||||||
#include "base/memory/container_of.h"
|
|
||||||
#include "base/memory/zalloc.h"
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
|
||||||
// This implementation is based around nested binary trees. Very
|
|
||||||
// simple (and hopefully correct).
|
|
||||||
|
|
||||||
struct node {
|
|
||||||
struct node *left;
|
|
||||||
struct node *right;
|
|
||||||
|
|
||||||
uint8_t key;
|
|
||||||
struct node *center;
|
|
||||||
|
|
||||||
bool has_value;
|
|
||||||
union radix_value value;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct radix_tree {
|
|
||||||
radix_value_dtr dtr;
|
|
||||||
void *dtr_context;
|
|
||||||
|
|
||||||
struct node *root;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct radix_tree *
|
|
||||||
radix_tree_create(radix_value_dtr dtr, void *dtr_context)
|
|
||||||
{
|
|
||||||
struct radix_tree *rt = zalloc(sizeof(*rt));
|
|
||||||
|
|
||||||
if (rt) {
|
|
||||||
rt->dtr = dtr;
|
|
||||||
rt->dtr_context = dtr_context;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rt;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the number of entries in the tree
|
|
||||||
static unsigned _destroy_tree(struct node *n, radix_value_dtr dtr, void *context)
|
|
||||||
{
|
|
||||||
unsigned r;
|
|
||||||
|
|
||||||
if (!n)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
r = _destroy_tree(n->left, dtr, context);
|
|
||||||
r += _destroy_tree(n->right, dtr, context);
|
|
||||||
r += _destroy_tree(n->center, dtr, context);
|
|
||||||
|
|
||||||
if (n->has_value) {
|
|
||||||
if (dtr)
|
|
||||||
dtr(context, n->value);
|
|
||||||
r++;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(n);
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
void radix_tree_destroy(struct radix_tree *rt)
|
|
||||||
{
|
|
||||||
_destroy_tree(rt->root, rt->dtr, rt->dtr_context);
|
|
||||||
free(rt);
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned _count(struct node *n)
|
|
||||||
{
|
|
||||||
unsigned r;
|
|
||||||
|
|
||||||
if (!n)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
r = _count(n->left);
|
|
||||||
r += _count(n->right);
|
|
||||||
r += _count(n->center);
|
|
||||||
|
|
||||||
if (n->has_value)
|
|
||||||
r++;
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned radix_tree_size(struct radix_tree *rt)
|
|
||||||
{
|
|
||||||
return _count(rt->root);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct node **_lookup(struct node **pn, uint8_t *kb, uint8_t *ke)
|
|
||||||
{
|
|
||||||
struct node *n = *pn;
|
|
||||||
|
|
||||||
if (!n || (kb == ke))
|
|
||||||
return pn;
|
|
||||||
|
|
||||||
if (*kb < n->key)
|
|
||||||
return _lookup(&n->left, kb, ke);
|
|
||||||
|
|
||||||
else if (*kb > n->key)
|
|
||||||
return _lookup(&n->right, kb, ke);
|
|
||||||
|
|
||||||
else
|
|
||||||
return _lookup(&n->center, kb + 1, ke);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool _insert(struct node **pn, uint8_t *kb, uint8_t *ke, union radix_value v)
|
|
||||||
{
|
|
||||||
struct node *n = *pn;
|
|
||||||
|
|
||||||
if (!n) {
|
|
||||||
n = zalloc(sizeof(*n));
|
|
||||||
if (!n)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
n->key = *kb;
|
|
||||||
*pn = n;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (kb == ke) {
|
|
||||||
n->has_value = true;
|
|
||||||
n->value = v;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*kb < n->key)
|
|
||||||
return _insert(&n->left, kb, ke, v);
|
|
||||||
|
|
||||||
else if (*kb > n->key)
|
|
||||||
return _insert(&n->right, kb, ke, v);
|
|
||||||
|
|
||||||
else
|
|
||||||
return _insert(&n->center, kb + 1, ke, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool radix_tree_insert(struct radix_tree *rt, uint8_t *kb, uint8_t *ke, union radix_value v)
|
|
||||||
{
|
|
||||||
return _insert(&rt->root, kb, ke, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool radix_tree_remove(struct radix_tree *rt, uint8_t *kb, uint8_t *ke)
|
|
||||||
{
|
|
||||||
struct node **pn = _lookup(&rt->root, kb, ke);
|
|
||||||
struct node *n = *pn;
|
|
||||||
|
|
||||||
if (!n || !n->has_value)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
else {
|
|
||||||
if (rt->dtr)
|
|
||||||
rt->dtr(rt->dtr_context, n->value);
|
|
||||||
|
|
||||||
if (n->left || n->center || n->right) {
|
|
||||||
n->has_value = false;
|
|
||||||
return true;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// FIXME: delete parent if this was the last entry
|
|
||||||
free(n);
|
|
||||||
*pn = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned radix_tree_remove_prefix(struct radix_tree *rt, uint8_t *kb, uint8_t *ke)
|
|
||||||
{
|
|
||||||
struct node **pn;
|
|
||||||
unsigned count;
|
|
||||||
|
|
||||||
pn = _lookup(&rt->root, kb, ke);
|
|
||||||
|
|
||||||
if (*pn) {
|
|
||||||
count = _destroy_tree(*pn, rt->dtr, rt->dtr_context);
|
|
||||||
*pn = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
radix_tree_lookup(struct radix_tree *rt, uint8_t *kb, uint8_t *ke, union radix_value *result)
|
|
||||||
{
|
|
||||||
struct node **pn = _lookup(&rt->root, kb, ke);
|
|
||||||
struct node *n = *pn;
|
|
||||||
|
|
||||||
if (n && n->has_value) {
|
|
||||||
*result = n->value;
|
|
||||||
return true;
|
|
||||||
} else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _iterate(struct node *n, struct radix_tree_iterator *it)
|
|
||||||
{
|
|
||||||
if (!n)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_iterate(n->left, it);
|
|
||||||
|
|
||||||
if (n->has_value)
|
|
||||||
// FIXME: fill out the key
|
|
||||||
it->visit(it, NULL, NULL, n->value);
|
|
||||||
|
|
||||||
_iterate(n->center, it);
|
|
||||||
_iterate(n->right, it);
|
|
||||||
}
|
|
||||||
|
|
||||||
void radix_tree_iterate(struct radix_tree *rt, uint8_t *kb, uint8_t *ke,
|
|
||||||
struct radix_tree_iterator *it)
|
|
||||||
{
|
|
||||||
if (kb == ke)
|
|
||||||
_iterate(rt->root, it);
|
|
||||||
|
|
||||||
else {
|
|
||||||
struct node **pn = _lookup(&rt->root, kb, ke);
|
|
||||||
struct node *n = *pn;
|
|
||||||
|
|
||||||
if (n) {
|
|
||||||
if (n->has_value)
|
|
||||||
it->visit(it, NULL, NULL, n->value);
|
|
||||||
_iterate(n->center, it);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool radix_tree_is_well_formed(struct radix_tree *rt)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void radix_tree_dump(struct radix_tree *rt, FILE *out)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
|
||||||
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
// Copyright (C) 2018 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
|
||||||
|
|
||||||
#ifdef SIMPLE_RADIX_TREE
|
|
||||||
#include "base/data-struct/radix-tree-simple.c"
|
|
||||||
#else
|
|
||||||
#include "base/data-struct/radix-tree-adaptive.c"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
// Copyright (C) 2018 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
#ifndef BASE_DATA_STRUCT_RADIX_TREE_H
|
|
||||||
#define BASE_DATA_STRUCT_RADIX_TREE_H
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
|
||||||
|
|
||||||
struct radix_tree;
|
|
||||||
|
|
||||||
union radix_value {
|
|
||||||
void *ptr;
|
|
||||||
uint64_t n;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef void (*radix_value_dtr)(void *context, union radix_value v);
|
|
||||||
|
|
||||||
// dtr will be called on any deleted entries. dtr may be NULL.
|
|
||||||
struct radix_tree *radix_tree_create(radix_value_dtr dtr, void *dtr_context);
|
|
||||||
void radix_tree_destroy(struct radix_tree *rt);
|
|
||||||
|
|
||||||
unsigned radix_tree_size(struct radix_tree *rt);
|
|
||||||
bool radix_tree_insert(struct radix_tree *rt, uint8_t *kb, uint8_t *ke, union radix_value v);
|
|
||||||
bool radix_tree_remove(struct radix_tree *rt, uint8_t *kb, uint8_t *ke);
|
|
||||||
|
|
||||||
// Returns the number of values removed
|
|
||||||
unsigned radix_tree_remove_prefix(struct radix_tree *rt, uint8_t *prefix_b, uint8_t *prefix_e);
|
|
||||||
|
|
||||||
bool radix_tree_lookup(struct radix_tree *rt,
|
|
||||||
uint8_t *kb, uint8_t *ke, union radix_value *result);
|
|
||||||
|
|
||||||
// The radix tree stores entries in lexicographical order. Which means
|
|
||||||
// we can iterate entries, in order. Or iterate entries with a particular
|
|
||||||
// prefix.
|
|
||||||
struct radix_tree_iterator {
|
|
||||||
// Returns false if the iteration should end.
|
|
||||||
bool (*visit)(struct radix_tree_iterator *it,
|
|
||||||
uint8_t *kb, uint8_t *ke, union radix_value v);
|
|
||||||
};
|
|
||||||
|
|
||||||
void radix_tree_iterate(struct radix_tree *rt, uint8_t *kb, uint8_t *ke,
|
|
||||||
struct radix_tree_iterator *it);
|
|
||||||
|
|
||||||
// Checks that some constraints on the shape of the tree are
|
|
||||||
// being held. For debug only.
|
|
||||||
bool radix_tree_is_well_formed(struct radix_tree *rt);
|
|
||||||
void radix_tree_dump(struct radix_tree *rt, FILE *out);
|
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
// Copyright (C) 2018 - 2020 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
#ifndef BASE_MEMORY_CONTAINER_OF_H
|
|
||||||
#define BASE_MEMORY_CONTAINER_OF_H
|
|
||||||
|
|
||||||
#include <stddef.h> // offsetof
|
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
|
||||||
|
|
||||||
#define container_of(v, t, head) \
|
|
||||||
((t *)((char *)(v) - offsetof(t, head)))
|
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
// Copyright (C) 2018 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
#ifndef BASE_MEMORY_ZALLOC_H
|
|
||||||
#define BASE_MEMORY_ZALLOC_H
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
|
||||||
|
|
||||||
static inline void *zalloc(size_t len)
|
|
||||||
{
|
|
||||||
return calloc(1, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
|
||||||
|
|
||||||
#endif
|
|
||||||
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,60 +0,0 @@
|
|||||||
#
|
|
||||||
# Copyright (C) 2004-2018 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 \
|
|
||||||
$(srcdir)/vdo-small.profile \
|
|
||||||
$(srcdir)/lvmdbusd.profile
|
|
||||||
|
|
||||||
include $(top_builddir)/make.tmpl
|
|
||||||
|
|
||||||
.PHONY: install_conf install_localconf install_profiles
|
|
||||||
|
|
||||||
generate:
|
|
||||||
$(top_builddir)/tools/lvm dumpconfig --type default --unconfigured --withgeneralpreamble --withcomments --ignorelocal --withspaces > example.conf.in
|
|
||||||
$(top_builddir)/tools/lvm dumpconfig --type default --unconfigured --withlocalpreamble --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)
|
|
||||||
@echo " [INSTALL] $<"
|
|
||||||
$(Q) $(INSTALL_DIR) $(profiledir)
|
|
||||||
$(Q) $(INSTALL_DATA) $(PROFILES) $(profiledir)/
|
|
||||||
|
|
||||||
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 settings for "smq" policy
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,74 +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.
|
|
||||||
#
|
|
||||||
allocation {
|
|
||||||
cache_mode="writethrough"
|
|
||||||
cache_settings {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
log {
|
|
||||||
report_command_log=0
|
|
||||||
command_log_sort="log_seq_num"
|
|
||||||
command_log_cols="log_seq_num,log_type,log_context,log_object_type,log_object_name,log_object_id,log_object_group,log_object_group_id,log_message,log_errno,log_ret_code"
|
|
||||||
command_log_selection="!(log_type=status && message=success)"
|
|
||||||
}
|
|
||||||
global {
|
|
||||||
units="h"
|
|
||||||
si_unit_consistency=1
|
|
||||||
suffix=1
|
|
||||||
lvdisplay_shows_full_device_path=0
|
|
||||||
}
|
|
||||||
report {
|
|
||||||
output_format="basic"
|
|
||||||
compact_output=0
|
|
||||||
compact_output_cols=""
|
|
||||||
aligned=1
|
|
||||||
buffered=1
|
|
||||||
headings=1
|
|
||||||
separator=" "
|
|
||||||
list_item_separator=","
|
|
||||||
prefixes=0
|
|
||||||
quoted=1
|
|
||||||
columns_as_rows=0
|
|
||||||
binary_values_as_numeric=0
|
|
||||||
time_format="%Y-%m-%d %T %z"
|
|
||||||
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"
|
|
||||||
vgs_cols_full="vg_all"
|
|
||||||
pvs_cols_full="pv_all"
|
|
||||||
lvs_cols_full="lv_all"
|
|
||||||
pvsegs_cols_full="pvseg_all,pv_uuid,lv_uuid"
|
|
||||||
segs_cols_full="seg_all,lv_uuid"
|
|
||||||
vgs_sort_full="vg_name"
|
|
||||||
pvs_sort_full="pv_name"
|
|
||||||
lvs_sort_full="vg_name,lv_name"
|
|
||||||
pvsegs_sort_full="pv_uuid,pvseg_start"
|
|
||||||
segs_sort_full="lv_uuid,seg_start"
|
|
||||||
mark_hidden_devices=1
|
|
||||||
}
|
|
||||||
2449
conf/example.conf.in
2449
conf/example.conf.in
File diff suppressed because it is too large
Load Diff
@@ -1,50 +0,0 @@
|
|||||||
#
|
|
||||||
# DO NOT EDIT THIS FILE!
|
|
||||||
#
|
|
||||||
# LVM configuration profile used by lvmdbusd daemon.
|
|
||||||
#
|
|
||||||
# This sets up LVM to produce output in the most suitable format for processing
|
|
||||||
# by lvmdbusd daemon which utilizes LVM shell to execute LVM commands.
|
|
||||||
#
|
|
||||||
# Do not edit this file in any way. This profile is distributed together with
|
|
||||||
# lvmdbusd and it contains configuration that is important for lvmdbusd to
|
|
||||||
# cooperate and interface with LVM correctly.
|
|
||||||
#
|
|
||||||
|
|
||||||
global {
|
|
||||||
# use bytes for expected and deterministic output
|
|
||||||
units=b
|
|
||||||
# no need for suffix if we have units set
|
|
||||||
suffix=0
|
|
||||||
}
|
|
||||||
|
|
||||||
report {
|
|
||||||
compact_output=0
|
|
||||||
compact_output_cols=""
|
|
||||||
binary_values_as_numeric=0
|
|
||||||
# time in number of seconds since the Epoch
|
|
||||||
time_format="%s"
|
|
||||||
mark_hidden_devices=1
|
|
||||||
# lvmdbusd expects JSON output
|
|
||||||
output_format=json
|
|
||||||
# *_cols_full for lvm fullreport's fields which lvmdbusd relies on to update its state
|
|
||||||
vgs_cols_full="vg_name,vg_uuid,vg_fmt,vg_size,vg_free,vg_sysid,vg_extent_size,vg_extent_count,vg_free_count,vg_profile,max_lv,max_pv,pv_count,lv_count,snap_count,vg_seqno,vg_mda_count,vg_mda_free,vg_mda_size,vg_mda_used_count,vg_attr,vg_tags"
|
|
||||||
pvs_cols_full="pv_name,pv_uuid,pv_fmt,pv_size,pv_free,pv_used,dev_size,pv_mda_size,pv_mda_free,pv_ba_start,pv_ba_size,pe_start,pv_pe_count,pv_pe_alloc_count,pv_attr,pv_tags,vg_name,vg_uuid"
|
|
||||||
lvs_cols_full="lv_uuid,lv_name,lv_path,lv_size,vg_name,pool_lv_uuid,pool_lv,origin_uuid,origin,data_percent,lv_attr,lv_tags,vg_uuid,lv_active,data_lv,metadata_lv,lv_parent,lv_role,lv_layout"
|
|
||||||
pvsegs_cols_full="pvseg_start,pvseg_size,segtype,pv_uuid,lv_uuid,pv_name"
|
|
||||||
segs_cols_full="seg_pe_ranges,segtype,lv_uuid"
|
|
||||||
vgs_sort_full="vg_name"
|
|
||||||
pvs_sort_full="pv_name"
|
|
||||||
lvs_sort_full="vg_name,lv_name"
|
|
||||||
pvsegs_sort_full="pv_uuid,pvseg_start"
|
|
||||||
segs_sort_full="lv_uuid,seg_start"
|
|
||||||
}
|
|
||||||
|
|
||||||
log {
|
|
||||||
# lvmdbusd relies on command log report to inspect LVM command's execution status
|
|
||||||
report_command_log=1
|
|
||||||
# display only outermost LVM shell-related log that lvmdbusd inspects first after LVM command execution (it calls 'lastlog' for more detailed log afterwards if needed)
|
|
||||||
command_log_selection="log_context=shell"
|
|
||||||
command_log_cols="log_seq_num,log_type,log_context,log_object_type,log_object_name,log_object_id,log_object_group,log_object_group_id,log_message,log_errno,log_ret_code"
|
|
||||||
command_log_sort="log_seq_num"
|
|
||||||
}
|
|
||||||
@@ -1,57 +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.
|
|
||||||
# Applicable only if LVM is compiled with lockd support
|
|
||||||
# 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
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
# Demo configuration for 'VDO' using less memory.
|
|
||||||
# ~lvmconfig --type full | grep vdo
|
|
||||||
|
|
||||||
allocation {
|
|
||||||
vdo_use_compression=1
|
|
||||||
vdo_use_deduplication=1
|
|
||||||
vdo_use_metadata_hints=1
|
|
||||||
vdo_minimum_io_size=4096
|
|
||||||
vdo_block_map_cache_size_mb=128
|
|
||||||
vdo_block_map_period=16380
|
|
||||||
vdo_check_point_frequency=0
|
|
||||||
vdo_use_sparse_index=0
|
|
||||||
vdo_index_memory_size_mb=256
|
|
||||||
vdo_slab_size_mb=2048
|
|
||||||
vdo_ack_threads=1
|
|
||||||
vdo_bio_threads=1
|
|
||||||
vdo_bio_rotation=64
|
|
||||||
vdo_cpu_threads=2
|
|
||||||
vdo_hash_zone_threads=1
|
|
||||||
vdo_logical_threads=1
|
|
||||||
vdo_physical_threads=1
|
|
||||||
vdo_write_policy="auto"
|
|
||||||
vdo_max_discard=1
|
|
||||||
}
|
|
||||||
2070
configure.ac
2070
configure.ac
File diff suppressed because it is too large
Load Diff
594
configure.in
Normal file
594
configure.in
Normal file
@@ -0,0 +1,594 @@
|
|||||||
|
##
|
||||||
|
## Copyright (C) 2000-2004 Sistina Software, Inc. All rights reserved.
|
||||||
|
## Copyright (C) 2004 Red Hat, Inc. All rights reserved.
|
||||||
|
##
|
||||||
|
## This file is part of the LVM2.
|
||||||
|
##
|
||||||
|
## This copyrighted material is made available to anyone wishing to use,
|
||||||
|
## modify, copy, or redistribute it subject to the terms and conditions
|
||||||
|
## 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
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
AC_PREREQ(2.53)
|
||||||
|
################################################################################
|
||||||
|
dnl -- Process this file with autoconf to produce a configure script.
|
||||||
|
AC_INIT(lib/device/dev-cache.h)
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
dnl -- Setup the directory where autoconf has auxilary files
|
||||||
|
AC_CONFIG_AUX_DIR(autoconf)
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
dnl -- Get system type
|
||||||
|
AC_CANONICAL_SYSTEM
|
||||||
|
|
||||||
|
case "$host_os" in
|
||||||
|
linux*)
|
||||||
|
CFLAGS="$CFLAGS"
|
||||||
|
COPTIMISE_FLAG="-O2"
|
||||||
|
CLDFLAGS="$CLDFLAGS -Wl,--version-script,.export.sym"
|
||||||
|
CLDWHOLEARCHIVE="-Wl,-whole-archive"
|
||||||
|
CLDNOWHOLEARCHIVE="-Wl,-no-whole-archive"
|
||||||
|
LDDEPS="$LDDEPS .export.sym"
|
||||||
|
LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
|
||||||
|
SOFLAG="-shared"
|
||||||
|
DEVMAPPER=yes
|
||||||
|
ODIRECT=yes
|
||||||
|
SELINUX=yes
|
||||||
|
CLUSTER=internal
|
||||||
|
FSADM=no ;;
|
||||||
|
darwin*)
|
||||||
|
CFLAGS="$CFLAGS -no-cpp-precomp -fno-common"
|
||||||
|
COPTIMISE_FLAG="-O2"
|
||||||
|
CLDFLAGS="$CLDFLAGS"
|
||||||
|
CLDWHOLEARCHIVE="-all_load"
|
||||||
|
CLDNOWHOLEARCHIVE=
|
||||||
|
LDDEPS="$LDDEPS"
|
||||||
|
LDFLAGS="$LDFLAGS"
|
||||||
|
SOFLAG="-dynamiclib"
|
||||||
|
DEVMAPPER=no
|
||||||
|
ODIRECT=no
|
||||||
|
SELINUX=no
|
||||||
|
CLUSTER=none
|
||||||
|
FSADM=no ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
dnl -- Checks for programs.
|
||||||
|
AC_PROG_AWK
|
||||||
|
AC_PROG_CC
|
||||||
|
AC_PROG_INSTALL
|
||||||
|
AC_PROG_LN_S
|
||||||
|
AC_PROG_MAKE_SET
|
||||||
|
AC_PROG_RANLIB
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
dnl -- Checks for header files.
|
||||||
|
AC_HEADER_DIRENT
|
||||||
|
AC_HEADER_STDC
|
||||||
|
AC_HEADER_SYS_WAIT
|
||||||
|
AC_HEADER_TIME
|
||||||
|
|
||||||
|
AC_CHECK_HEADERS(fcntl.h limits.h locale.h stddef.h syslog.h sys/file.h sys/ioctl.h sys/param.h sys/time.h,,AC_MSG_ERROR(bailing out))
|
||||||
|
AC_CHECK_HEADERS(assert.h ctype.h libgen.h signal.h stdio.h sys/mman.h sys/resource.h sys/stat.h sys/types.h sys/utsname.h sys/wait.h time.h,,AC_MSG_ERROR(bailing out))
|
||||||
|
|
||||||
|
case "$host_os" in
|
||||||
|
linux*)
|
||||||
|
AC_CHECK_HEADERS(asm/byteorder.h linux/fs.h malloc.h,,AC_MSG_ERROR(bailing out)) ;;
|
||||||
|
darwin*)
|
||||||
|
AC_CHECK_HEADERS(machine/endian.h sys/disk.h,,AC_MSG_ERROR(bailing out)) ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
dnl -- Checks for typedefs, structures, and compiler characteristics.
|
||||||
|
AC_C_CONST
|
||||||
|
AC_C_INLINE
|
||||||
|
AC_TYPE_OFF_T
|
||||||
|
AC_TYPE_PID_T
|
||||||
|
AC_TYPE_SIZE_T
|
||||||
|
AC_TYPE_MODE_T
|
||||||
|
AC_STRUCT_ST_RDEV
|
||||||
|
AC_STRUCT_TM
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
dnl -- Check for functions
|
||||||
|
AC_CHECK_FUNCS(gethostname getpagesize memset munmap setlocale strcasecmp strchr strdup strncasecmp strerror strrchr strstr strtol strtoul,,AC_MSG_ERROR(bailing out))
|
||||||
|
AC_FUNC_ALLOCA
|
||||||
|
AC_FUNC_CLOSEDIR_VOID
|
||||||
|
AC_FUNC_FORK
|
||||||
|
AC_FUNC_LSTAT
|
||||||
|
AC_FUNC_MALLOC
|
||||||
|
AC_FUNC_MEMCMP
|
||||||
|
AC_FUNC_MMAP
|
||||||
|
AC_FUNC_STAT
|
||||||
|
AC_FUNC_STRTOD
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
dnl -- Prefix is /usr by default, the exec_prefix default is setup later
|
||||||
|
AC_PREFIX_DEFAULT(/usr)
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
dnl -- Parallel make jobs?
|
||||||
|
AC_ARG_ENABLE(jobs, [ --enable-jobs=NUM Number of jobs to run simultaneously], JOBS=-j$enableval, JOBS=-j2)
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
dnl -- Setup the ownership of the files
|
||||||
|
AC_MSG_CHECKING(file owner)
|
||||||
|
OWNER="root"
|
||||||
|
|
||||||
|
AC_ARG_WITH(user,
|
||||||
|
[ --with-user=USER Set the owner of installed files ],
|
||||||
|
[ OWNER="$withval" ])
|
||||||
|
AC_MSG_RESULT($OWNER)
|
||||||
|
|
||||||
|
if test x$OWNER != x; then
|
||||||
|
OWNER="-o $OWNER"
|
||||||
|
fi
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
dnl -- Setup the group ownership of the files
|
||||||
|
AC_MSG_CHECKING(group owner)
|
||||||
|
GROUP="root"
|
||||||
|
AC_ARG_WITH(group,
|
||||||
|
[ --with-group=GROUP Set the group owner of installed files ],
|
||||||
|
[ GROUP="$withval" ])
|
||||||
|
AC_MSG_RESULT($GROUP)
|
||||||
|
|
||||||
|
if test x$GROUP != x; then
|
||||||
|
GROUP="-g $GROUP"
|
||||||
|
fi
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
dnl -- LVM1 tool fallback option
|
||||||
|
AC_MSG_CHECKING(whether to enable lvm1 fallback)
|
||||||
|
AC_ARG_ENABLE(lvm1_fallback, [ --enable-lvm1_fallback Use this to fall back and use LVM1 binaries if
|
||||||
|
device-mapper is missing from the kernel], LVM1_FALLBACK=$enableval, LVM1_FALLBACK=no)
|
||||||
|
AC_MSG_RESULT($LVM1_FALLBACK)
|
||||||
|
|
||||||
|
if test x$LVM1_FALLBACK = xyes; then
|
||||||
|
CFLAGS="$CFLAGS -DLVM1_FALLBACK"
|
||||||
|
fi
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
dnl -- format1 inclusion type
|
||||||
|
AC_MSG_CHECKING(whether to include support for lvm1 metadata)
|
||||||
|
AC_ARG_WITH(lvm1,
|
||||||
|
[ --with-lvm1=TYPE LVM1 metadata support: internal/shared/none
|
||||||
|
[TYPE=internal] ],
|
||||||
|
[ LVM1="$withval" ],
|
||||||
|
[ LVM1="internal" ])
|
||||||
|
AC_MSG_RESULT($LVM1)
|
||||||
|
|
||||||
|
if [[ "x$LVM1" != xnone -a "x$LVM1" != xinternal -a "x$LVM1" != xshared ]];
|
||||||
|
then AC_MSG_ERROR(
|
||||||
|
--with-lvm1 parameter invalid
|
||||||
|
)
|
||||||
|
fi;
|
||||||
|
|
||||||
|
if test x$LVM1 = xinternal; then
|
||||||
|
CFLAGS="$CFLAGS -DLVM1_INTERNAL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
dnl -- format_pool inclusion type
|
||||||
|
AC_MSG_CHECKING(whether to include support for GFS pool metadata)
|
||||||
|
AC_ARG_WITH(pool,
|
||||||
|
[ --with-pool=TYPE GFS pool read-only support: internal/shared/none
|
||||||
|
[TYPE=internal] ],
|
||||||
|
[ POOL="$withval" ],
|
||||||
|
[ POOL="internal" ])
|
||||||
|
AC_MSG_RESULT($POOL)
|
||||||
|
|
||||||
|
if [[ "x$POOL" != xnone -a "x$POOL" != xinternal -a "x$POOL" != xshared ]];
|
||||||
|
then AC_MSG_ERROR(
|
||||||
|
--with-pool parameter invalid
|
||||||
|
)
|
||||||
|
fi;
|
||||||
|
|
||||||
|
if test x$POOL = xinternal; then
|
||||||
|
CFLAGS="$CFLAGS -DPOOL_INTERNAL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
dnl -- cluster_locking inclusion type
|
||||||
|
AC_MSG_CHECKING(whether to include support for cluster locking)
|
||||||
|
AC_ARG_WITH(cluster,
|
||||||
|
[ --with-cluster=TYPE Cluster LVM locking support: internal/shared/none
|
||||||
|
[TYPE=internal] ],
|
||||||
|
[ CLUSTER="$withval" ])
|
||||||
|
AC_MSG_RESULT($CLUSTER)
|
||||||
|
|
||||||
|
if [[ "x$CLUSTER" != xnone -a "x$CLUSTER" != xinternal -a "x$CLUSTER" != xshared ]];
|
||||||
|
then AC_MSG_ERROR(
|
||||||
|
--with-cluster parameter invalid
|
||||||
|
)
|
||||||
|
fi;
|
||||||
|
|
||||||
|
if test x$CLUSTER = xinternal; then
|
||||||
|
CFLAGS="$CFLAGS -DCLUSTER_LOCKING_INTERNAL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
dnl -- snapshots inclusion type
|
||||||
|
AC_MSG_CHECKING(whether to include snapshots)
|
||||||
|
AC_ARG_WITH(snapshots,
|
||||||
|
[ --with-snapshots=TYPE Snapshot support: internal/shared/none
|
||||||
|
[TYPE=internal] ],
|
||||||
|
[ SNAPSHOTS="$withval" ],
|
||||||
|
[ SNAPSHOTS="internal" ])
|
||||||
|
AC_MSG_RESULT($SNAPSHOTS)
|
||||||
|
|
||||||
|
if [[ "x$SNAPSHOTS" != xnone -a "x$SNAPSHOTS" != xinternal -a "x$SNAPSHOTS" != xshared ]];
|
||||||
|
then AC_MSG_ERROR(
|
||||||
|
--with-snapshots parameter invalid
|
||||||
|
)
|
||||||
|
fi;
|
||||||
|
|
||||||
|
if test x$SNAPSHOTS = xinternal; then
|
||||||
|
CFLAGS="$CFLAGS -DSNAPSHOT_INTERNAL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
dnl -- mirrors inclusion type
|
||||||
|
AC_MSG_CHECKING(whether to include mirrors)
|
||||||
|
AC_ARG_WITH(mirrors,
|
||||||
|
[ --with-mirrors=TYPE Mirror support: internal/shared/none
|
||||||
|
[TYPE=internal] ],
|
||||||
|
[ MIRRORS="$withval" ],
|
||||||
|
[ MIRRORS="internal" ])
|
||||||
|
AC_MSG_RESULT($MIRRORS)
|
||||||
|
|
||||||
|
if [[ "x$MIRRORS" != xnone -a "x$MIRRORS" != xinternal -a "x$MIRRORS" != xshared ]];
|
||||||
|
then AC_MSG_ERROR(
|
||||||
|
--with-mirrors parameter invalid
|
||||||
|
)
|
||||||
|
fi;
|
||||||
|
|
||||||
|
if test x$MIRRORS = xinternal; then
|
||||||
|
CFLAGS="$CFLAGS -DMIRRORED_INTERNAL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
dnl -- Enables staticly-linked tools
|
||||||
|
AC_MSG_CHECKING(whether to use static linking)
|
||||||
|
AC_ARG_ENABLE(static_link, [ --enable-static_link Use this to link the tools to their libraries
|
||||||
|
statically. Default is dynamic linking], STATIC_LINK=$enableval, STATIC_LINK=no)
|
||||||
|
AC_MSG_RESULT($STATIC_LINK)
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
dnl -- Enable readline
|
||||||
|
AC_MSG_CHECKING(whether to enable readline)
|
||||||
|
AC_ARG_ENABLE(readline, [ --enable-readline Enable readline support],
|
||||||
|
READLINE=$enableval, READLINE=no)
|
||||||
|
AC_MSG_RESULT($READLINE)
|
||||||
|
|
||||||
|
if test x$READLINE = xyes; then
|
||||||
|
CFLAGS="$CFLAGS -DREADLINE_SUPPORT"
|
||||||
|
fi
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
dnl -- Disable selinux
|
||||||
|
AC_MSG_CHECKING(whether to enable selinux support)
|
||||||
|
AC_ARG_ENABLE(selinux, [ --disable-selinux Disable selinux support],
|
||||||
|
SELINUX=$enableval)
|
||||||
|
AC_MSG_RESULT($SELINUX)
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
dnl -- Build cluster LVM daemon
|
||||||
|
AC_MSG_CHECKING(whether to build cluster LVM daemon)
|
||||||
|
AC_ARG_WITH(clvmd,
|
||||||
|
[ --with-clvmd=TYPE Build cluster LVM Daemon: cman/gulm/none/all
|
||||||
|
[TYPE=none] ],
|
||||||
|
[ CLVMD="$withval" ],
|
||||||
|
[ CLVMD="none" ])
|
||||||
|
if test x$CLVMD = xyes; then
|
||||||
|
CLVMD=all
|
||||||
|
fi
|
||||||
|
AC_MSG_RESULT($CLVMD)
|
||||||
|
|
||||||
|
dnl -- If clvmd enabled without cluster locking, automagically include it
|
||||||
|
if test x$CLVMD != xnone && test x$CLUSTER = xnone; then
|
||||||
|
CLUSTER=internal
|
||||||
|
fi
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
dnl -- Enable debugging
|
||||||
|
AC_MSG_CHECKING(whether to enable debugging)
|
||||||
|
AC_ARG_ENABLE(debug, [ --enable-debug Enable debugging],
|
||||||
|
DEBUG=$enableval, DEBUG=no)
|
||||||
|
AC_MSG_RESULT($DEBUG)
|
||||||
|
|
||||||
|
dnl -- Normally turn off optimisation for debug builds
|
||||||
|
if test x$DEBUG = xyes; then
|
||||||
|
COPTIMISE_FLAG=
|
||||||
|
fi
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
dnl -- Override optimisation
|
||||||
|
AC_MSG_CHECKING(for C optimisation flag)
|
||||||
|
AC_ARG_WITH(optimisation,
|
||||||
|
[ --with-optimisation=OPT C optimisation flag [OPT=-O2] ],
|
||||||
|
[ COPTIMISE_FLAG="$withval" ])
|
||||||
|
AC_MSG_RESULT($COPTIMISE_FLAG)
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
dnl -- Disable devmapper
|
||||||
|
AC_MSG_CHECKING(whether to use device-mapper)
|
||||||
|
AC_ARG_ENABLE(devmapper, [ --disable-devmapper Disable device-mapper interaction],
|
||||||
|
DEVMAPPER=$enableval)
|
||||||
|
AC_MSG_RESULT($DEVMAPPER)
|
||||||
|
|
||||||
|
if test x$DEVMAPPER = xyes; then
|
||||||
|
CFLAGS="$CFLAGS -DDEVMAPPER_SUPPORT"
|
||||||
|
fi
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
dnl -- Disable O_DIRECT
|
||||||
|
AC_MSG_CHECKING(whether to enable O_DIRECT)
|
||||||
|
AC_ARG_ENABLE(o_direct, [ --disable-o_direct Disable O_DIRECT],
|
||||||
|
ODIRECT=$enableval)
|
||||||
|
AC_MSG_RESULT($ODIRECT)
|
||||||
|
|
||||||
|
if test x$ODIRECT = xyes; then
|
||||||
|
CFLAGS="$CFLAGS -DO_DIRECT_SUPPORT"
|
||||||
|
fi
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
dnl -- Enable cmdlib
|
||||||
|
AC_MSG_CHECKING(whether to compile liblvm2cmd.so)
|
||||||
|
AC_ARG_ENABLE(cmdlib, [ --enable-cmdlib Build shared command library],
|
||||||
|
CMDLIB=$enableval, CMDLIB=no)
|
||||||
|
AC_MSG_RESULT($CMDLIB)
|
||||||
|
|
||||||
|
if test x$CMDLIB = xyes; then
|
||||||
|
CFLAGS="$CFLAGS -DCMDLIB"
|
||||||
|
fi
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
dnl -- Enable fsadm
|
||||||
|
AC_MSG_CHECKING(whether to build fsadm)
|
||||||
|
AC_ARG_ENABLE(fsadm, [ --enable-fsadm Enable fsadm],
|
||||||
|
FSADM=$enableval)
|
||||||
|
AC_MSG_RESULT($FSADM)
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
dnl -- Mess with default exec_prefix
|
||||||
|
if [[ "x$exec_prefix" = xNONE -a "x$prefix" = xNONE ]];
|
||||||
|
then exec_prefix="";
|
||||||
|
fi;
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
dnl -- Checks for library functions.
|
||||||
|
AC_PROG_GCC_TRADITIONAL
|
||||||
|
AC_TYPE_SIGNAL
|
||||||
|
AC_FUNC_VPRINTF
|
||||||
|
AC_CHECK_FUNCS(mkdir rmdir uname,,AC_MSG_ERROR(bailing out))
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
dnl -- Check for termcap (Shamelessly copied from parted 1.4.17)
|
||||||
|
if test x$READLINE = xyes; then
|
||||||
|
AC_SEARCH_LIBS(tgetent, ncurses curses termcap termlib, ,
|
||||||
|
AC_MSG_ERROR(
|
||||||
|
termcap could not be found which is required for the
|
||||||
|
--enable-readline option (which is enabled by default). Either disable readline
|
||||||
|
support with --disable-readline or download and install termcap from:
|
||||||
|
ftp.gnu.org/gnu/termcap
|
||||||
|
Note: if you are using precompiled packages you will also need the development
|
||||||
|
package as well (which may be called termcap-devel or something similar).
|
||||||
|
Note: (n)curses also seems to work as a substitute for termcap. This was
|
||||||
|
not found either - but you could try installing that as well.
|
||||||
|
)
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
dnl -- Check for dlopen
|
||||||
|
AC_CHECK_LIB(dl, dlopen, HAVE_LIBDL=yes, HAVE_LIBDL=no)
|
||||||
|
|
||||||
|
if [[ "x$HAVE_LIBDL" = xyes ]]; then
|
||||||
|
CFLAGS="$CFLAGS -DHAVE_LIBDL"
|
||||||
|
LIBS="-ldl $LIBS"
|
||||||
|
else
|
||||||
|
HAVE_LIBDL=no
|
||||||
|
fi
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
dnl -- Check for shared/static conflicts
|
||||||
|
if [[ \( "x$LVM1" = xshared -o "x$POOL" = xshared -o "x$CLUSTER" = xshared \
|
||||||
|
-o "x$SNAPSHOTS" = xshared -o "x$MIRRORS" = xshared \
|
||||||
|
\) -a "x$STATIC_LINK" = xyes ]];
|
||||||
|
then AC_MSG_ERROR(
|
||||||
|
Features cannot be 'shared' when building statically
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
dnl -- Check for is_selinux_enabled
|
||||||
|
if test x$SELINUX = xyes; then
|
||||||
|
AC_MSG_CHECKING(for is_selinux_enabled function)
|
||||||
|
AC_CHECK_LIB(selinux, is_selinux_enabled, HAVE_SELINUX=yes, HAVE_SELINUX=no)
|
||||||
|
AC_MSG_RESULT($HAVE_SELINUX)
|
||||||
|
|
||||||
|
if test x$HAVE_SELINUX = xyes; then
|
||||||
|
CFLAGS="$CFLAGS -DHAVE_SELINUX"
|
||||||
|
LIBS="-lselinux $LIBS"
|
||||||
|
else
|
||||||
|
AC_MSG_WARN(Disabling selinux)
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
dnl -- Check for getopt
|
||||||
|
AC_CHECK_HEADERS(getopt.h, CFLAGS="$CFLAGS -DHAVE_GETOPTLONG")
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
dnl -- Check for readline (Shamelessly copied from parted 1.4.17)
|
||||||
|
if test x$READLINE = xyes; then
|
||||||
|
AC_CHECK_LIB(readline, readline, ,
|
||||||
|
AC_MSG_ERROR(
|
||||||
|
GNU Readline could not be found which is required for the
|
||||||
|
--enable-readline option (which is enabled by default). Either disable readline
|
||||||
|
support with --disable-readline or download and install readline from:
|
||||||
|
ftp.gnu.org/gnu/readline
|
||||||
|
Note: if you are using precompiled packages you will also need the development
|
||||||
|
package as well (which may be called readline-devel or something similar).
|
||||||
|
)
|
||||||
|
)
|
||||||
|
AC_CHECK_FUNC(rl_completion_matches, CFLAGS="$CFLAGS -DHAVE_RL_COMPLETION_MATCHES")
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
dnl -- Internationalisation stuff
|
||||||
|
AC_MSG_CHECKING(whether to enable internationalisation)
|
||||||
|
AC_ARG_ENABLE(nls, [ --enable-nls Enable Native Language Support],
|
||||||
|
INTL=$enableval, INTL=no)
|
||||||
|
AC_MSG_RESULT($INTL)
|
||||||
|
|
||||||
|
if test x$INTL = xyes; then
|
||||||
|
INTL_PACKAGE="lvm2"
|
||||||
|
AC_PATH_PROG(MSGFMT, msgfmt)
|
||||||
|
if [[ "x$MSGFMT" == x ]];
|
||||||
|
then AC_MSG_ERROR(
|
||||||
|
msgfmt not found in path $PATH
|
||||||
|
)
|
||||||
|
fi;
|
||||||
|
|
||||||
|
AC_ARG_WITH(localedir,
|
||||||
|
[ --with-localedir=DIR Translation files in DIR [PREFIX/share/locale]],
|
||||||
|
[ LOCALEDIR="$withval" ],
|
||||||
|
[ LOCALEDIR='${prefix}/share/locale' ])
|
||||||
|
fi
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
AC_ARG_WITH(confdir,
|
||||||
|
[ --with-confdir=DIR Configuration files in DIR [/etc]],
|
||||||
|
[ CONFDIR="$withval" ],
|
||||||
|
[ CONFDIR='/etc' ])
|
||||||
|
|
||||||
|
AC_ARG_WITH(staticdir,
|
||||||
|
[ --with-staticdir=DIR Static binary in DIR [EXEC_PREFIX/sbin]],
|
||||||
|
[ STATICDIR="$withval" ],
|
||||||
|
[ STATICDIR='${exec_prefix}/sbin' ])
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
dnl -- Ensure additional headers required
|
||||||
|
if test x$READLINE = xyes; then
|
||||||
|
AC_CHECK_HEADERS(readline/readline.h readline/history.h,,AC_MSG_ERROR(bailing out))
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test x$CLVMD != xnone; then
|
||||||
|
AC_CHECK_HEADERS(mntent.h netdb.h netinet/in.h pthread.h search.h sys/mount.h sys/socket.h sys/uio.h sys/un.h utmpx.h,,AC_MSG_ERROR(bailing out))
|
||||||
|
AC_CHECK_FUNCS(dup2 getmntent memmove select socket,,AC_MSG_ERROR(bailing out))
|
||||||
|
AC_FUNC_GETMNTENT
|
||||||
|
# AC_FUNC_REALLOC
|
||||||
|
AC_FUNC_SELECT_ARGTYPES
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test x$FSADM = xyes; then
|
||||||
|
AC_CHECK_HEADERS(fstab.h sys/mount.h sys/vfs.h,,AC_MSG_ERROR(bailing out))
|
||||||
|
AC_CHECK_FUNCS(memmove,,AC_MSG_ERROR(bailing out))
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test x$CLUSTER != xnone; then
|
||||||
|
AC_CHECK_HEADERS(sys/socket.h sys/un.h,,AC_MSG_ERROR(bailing out))
|
||||||
|
AC_CHECK_FUNCS(socket,,AC_MSG_ERROR(bailing out))
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test x$HAVE_LIBDL = xyes; then
|
||||||
|
AC_CHECK_HEADERS(dlfcn.h,,AC_MSG_ERROR(bailing out))
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test x$INTL = xyes; then
|
||||||
|
AC_CHECK_HEADERS(libintl.h,,AC_MSG_ERROR(bailing out))
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test x$DEVMAPPER = xyes; then
|
||||||
|
AC_CHECK_HEADERS(libdevmapper.h,,AC_MSG_ERROR(bailing out))
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test x$HAVE_SELINUX = xyes; then
|
||||||
|
AC_CHECK_HEADERS(selinux/selinux.h,,AC_MSG_ERROR(bailing out))
|
||||||
|
fi
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
if test "-f VERSION"; then
|
||||||
|
LVM_VERSION="\"`cat VERSION`\""
|
||||||
|
else
|
||||||
|
LVM_VERSION="Unknown"
|
||||||
|
fi
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
AC_SUBST(JOBS)
|
||||||
|
AC_SUBST(STATIC_LINK)
|
||||||
|
AC_SUBST(LVM1)
|
||||||
|
AC_SUBST(POOL)
|
||||||
|
AC_SUBST(SNAPSHOTS)
|
||||||
|
AC_SUBST(MIRRORS)
|
||||||
|
AC_SUBST(OWNER)
|
||||||
|
AC_SUBST(GROUP)
|
||||||
|
AC_SUBST(CFLAGS)
|
||||||
|
AC_SUBST(COPTIMISE_FLAG)
|
||||||
|
AC_SUBST(CLDFLAGS)
|
||||||
|
AC_SUBST(CLDWHOLEARCHIVE)
|
||||||
|
AC_SUBST(CLDNOWHOLEARCHIVE)
|
||||||
|
AC_SUBST(LDDEPS)
|
||||||
|
AC_SUBST(LDFLAGS)
|
||||||
|
AC_SUBST(SOFLAG)
|
||||||
|
AC_SUBST(LIBS)
|
||||||
|
AC_SUBST(LVM_VERSION)
|
||||||
|
AC_SUBST(LVM1_FALLBACK)
|
||||||
|
AC_SUBST(DEBUG)
|
||||||
|
AC_SUBST(DEVMAPPER)
|
||||||
|
AC_SUBST(HAVE_LIBDL)
|
||||||
|
AC_SUBST(HAVE_SELINUX)
|
||||||
|
AC_SUBST(CMDLIB)
|
||||||
|
AC_SUBST(MSGFMT)
|
||||||
|
AC_SUBST(LOCALEDIR)
|
||||||
|
AC_SUBST(CONFDIR)
|
||||||
|
AC_SUBST(STATICDIR)
|
||||||
|
AC_SUBST(INTL_PACKAGE)
|
||||||
|
AC_SUBST(INTL)
|
||||||
|
AC_SUBST(CLVMD)
|
||||||
|
AC_SUBST(CLUSTER)
|
||||||
|
AC_SUBST(FSADM)
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
dnl -- First and last lines should not contain files to generate in order to
|
||||||
|
dnl -- keep utility scripts running properly
|
||||||
|
AC_OUTPUT( \
|
||||||
|
Makefile \
|
||||||
|
make.tmpl \
|
||||||
|
daemons/Makefile \
|
||||||
|
daemons/clvmd/Makefile \
|
||||||
|
doc/Makefile \
|
||||||
|
include/Makefile \
|
||||||
|
lib/Makefile \
|
||||||
|
lib/format1/Makefile \
|
||||||
|
lib/format_pool/Makefile \
|
||||||
|
lib/locking/Makefile \
|
||||||
|
lib/mirror/Makefile \
|
||||||
|
lib/snapshot/Makefile \
|
||||||
|
man/Makefile \
|
||||||
|
po/Makefile \
|
||||||
|
tools/Makefile \
|
||||||
|
tools/version.h \
|
||||||
|
tools/fsadm/Makefile \
|
||||||
|
test/mm/Makefile \
|
||||||
|
test/device/Makefile \
|
||||||
|
test/format1/Makefile \
|
||||||
|
test/regex/Makefile \
|
||||||
|
test/filters/Makefile \
|
||||||
|
)
|
||||||
|
|
||||||
|
if test x$ODIRECT != xyes; then
|
||||||
|
AC_MSG_WARN(Warning: O_DIRECT disabled: low-memory pvmove may lock up)
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test x$FSADM == xyes; then
|
||||||
|
AC_MSG_WARN(fsadm support is untested)
|
||||||
|
fi
|
||||||
@@ -1,148 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Coverity usage:
|
|
||||||
*
|
|
||||||
* translate model into xml
|
|
||||||
* cov-make-library -of coverity_model.xml coverity_model.c
|
|
||||||
*
|
|
||||||
* compile (using outdir 'cov'):
|
|
||||||
* cov-build --dir=cov make CC=gcc
|
|
||||||
*
|
|
||||||
* analyze (agressively, using 'cov')
|
|
||||||
* cov-analyze --dir cov --wait-for-license --hfa --concurrency --enable-fnptr --enable-constraint-fpp --security --all --aggressiveness-level=high --field-offset-escape --user-model-file=coverity/coverity_model.xml
|
|
||||||
*
|
|
||||||
* generate html output (to 'html' from 'cov'):
|
|
||||||
* cov-format-errors --dir cov --html-output html
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct lv_segment;
|
|
||||||
struct logical_volume;
|
|
||||||
|
|
||||||
struct lv_segment *first_seg(const struct logical_volume *lv)
|
|
||||||
{
|
|
||||||
return ((struct lv_segment **)lv)[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
struct lv_segment *last_seg(const struct logical_volume *lv)
|
|
||||||
{
|
|
||||||
return ((struct lv_segment **)lv)[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *find_config_tree_str(struct cmd_context *cmd, int id, struct profile *profile)
|
|
||||||
{
|
|
||||||
return "STRING";
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
struct logical_volume *origin_from_cow(const struct logical_volume *lv)
|
|
||||||
{
|
|
||||||
if (lv)
|
|
||||||
return lv;
|
|
||||||
|
|
||||||
__coverity_panic__();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* simple_memccpy() from glibc */
|
|
||||||
void *memccpy(void *dest, const void *src, int c, size_t n)
|
|
||||||
{
|
|
||||||
const char *s = src;
|
|
||||||
char *d = dest;
|
|
||||||
|
|
||||||
while (n-- > 0)
|
|
||||||
if ((*d++ = *s++) == (char) c)
|
|
||||||
return d;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 2 lines bellow needs to be placed in coverity/config/user_nodefs.h
|
|
||||||
* Not sure about any other way.
|
|
||||||
* Without them, coverity shows warning since x86 system header files
|
|
||||||
* are using inline assembly to reset fdset
|
|
||||||
*/
|
|
||||||
//#nodef FD_ZERO model_FD_ZERO
|
|
||||||
//void model_FD_ZERO(void *fdset);
|
|
||||||
|
|
||||||
void model_FD_ZERO(void *fdset)
|
|
||||||
{
|
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
for (i = 0; i < 1024 / 8 / sizeof(long); ++i)
|
|
||||||
((long*)fdset)[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Resent Coverity reports quite weird errors... */
|
|
||||||
int *__errno_location(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
const unsigned short **__ctype_b_loc (void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Added extra pointer check to not need these models,
|
|
||||||
* for now just keep then in file
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
struct cmd_context;
|
|
||||||
struct profile;
|
|
||||||
|
|
||||||
const char *find_config_tree_str(struct cmd_context *cmd, int id, struct profile *profile)
|
|
||||||
{
|
|
||||||
return "text";
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *find_config_tree_str_allow_empty(struct cmd_context *cmd, int id, struct profile *profile)
|
|
||||||
{
|
|
||||||
return "text";
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Until fixed coverity case# 00531860:
|
|
||||||
* A FORWARD_NULL false positive on a recursive function call
|
|
||||||
*
|
|
||||||
* model also these functions:
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
const struct dm_config_node;
|
|
||||||
const struct dm_config_node *find_config_tree_array(struct cmd_context *cmd, int id, struct profile *profile)
|
|
||||||
{
|
|
||||||
const struct dm_config_node *cn;
|
|
||||||
|
|
||||||
return cn;
|
|
||||||
}
|
|
||||||
|
|
||||||
const struct dm_config_node *find_config_tree_node(struct cmd_context *cmd, int id, struct profile *profile)
|
|
||||||
{
|
|
||||||
const struct dm_config_node *cn;
|
|
||||||
|
|
||||||
return cn;
|
|
||||||
}
|
|
||||||
|
|
||||||
int find_config_tree_bool(struct cmd_context *cmd, int id, struct profile *profile)
|
|
||||||
{
|
|
||||||
int b;
|
|
||||||
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#
|
#
|
||||||
# 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 the LVM2.
|
||||||
#
|
#
|
||||||
# This copyrighted material is made available to anyone wishing to use,
|
# This copyrighted material is made available to anyone wishing to use,
|
||||||
# modify, copy, or redistribute it subject to the terms and conditions
|
# modify, copy, or redistribute it subject to the terms and conditions
|
||||||
@@ -9,43 +9,15 @@
|
|||||||
#
|
#
|
||||||
# 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, write to the Free Software Foundation,
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
srcdir = @srcdir@
|
srcdir = @srcdir@
|
||||||
top_srcdir = @top_srcdir@
|
top_srcdir = @top_srcdir@
|
||||||
top_builddir = @top_builddir@
|
VPATH = @srcdir@
|
||||||
|
|
||||||
.PHONY: dmeventd cmirrord lvmpolld lvmlockd
|
ifneq ("@CLVMD@", "none")
|
||||||
|
SUBDIRS = clvmd
|
||||||
ifeq ("@BUILD_CMIRRORD@", "yes")
|
|
||||||
SUBDIRS += cmirrord
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ("@BUILD_DMEVENTD@", "yes")
|
include $(top_srcdir)/make.tmpl
|
||||||
SUBDIRS += dmeventd
|
|
||||||
ifneq ("$(CFLOW_CMD)", "")
|
|
||||||
daemons.cflow: dmeventd.cflow
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ("@BUILD_LVMPOLLD@", "yes")
|
|
||||||
SUBDIRS += lvmpolld
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ("@BUILD_LVMLOCKD@", "yes")
|
|
||||||
SUBDIRS += lvmlockd
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ("@BUILD_LVMDBUSD@", "yes")
|
|
||||||
SUBDIRS += lvmdbusd
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(MAKECMDGOALS),distclean)
|
|
||||||
SUBDIRS = cmirrord dmeventd lvmpolld lvmlockd lvmdbusd
|
|
||||||
endif
|
|
||||||
|
|
||||||
include $(top_builddir)/make.tmpl
|
|
||||||
|
|
||||||
ifeq ("@BUILD_DMEVENTD@", "yes")
|
|
||||||
device-mapper: dmeventd.device-mapper
|
|
||||||
endif
|
|
||||||
|
|||||||
76
daemons/clvmd/Makefile.in
Normal file
76
daemons/clvmd/Makefile.in
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2004 Red Hat, Inc. All rights reserved.
|
||||||
|
#
|
||||||
|
# This file is part of the LVM2.
|
||||||
|
#
|
||||||
|
# This copyrighted material is made available to anyone wishing to use,
|
||||||
|
# modify, copy, or redistribute it subject to the terms and conditions
|
||||||
|
# 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@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
|
||||||
|
SOURCES = \
|
||||||
|
clvmd-command.c \
|
||||||
|
clvmd.c \
|
||||||
|
lvm-functions.c \
|
||||||
|
system-lv.c
|
||||||
|
|
||||||
|
ifeq ("@CLVMD@", "gulm")
|
||||||
|
GULM = yes
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ("@CLVMD@", "cman")
|
||||||
|
CMAN = yes
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ("@CLVMD@", "all")
|
||||||
|
GULM = yes
|
||||||
|
CMAN = yes
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ("@DEBUG@", "yes")
|
||||||
|
CFLAGS += -DDEBUG
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ("$(GULM)", "yes")
|
||||||
|
SOURCES += clvmd-gulm.c tcp-comms.c
|
||||||
|
LMLIBS += -lccs -lgulm
|
||||||
|
CFLAGS += -DUSE_GULM
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ("$(CMAN)", "yes")
|
||||||
|
SOURCES += clvmd-cman.c
|
||||||
|
LMLIBS += -ldlm
|
||||||
|
CFLAGS += -DUSE_CMAN
|
||||||
|
endif
|
||||||
|
|
||||||
|
TARGETS = \
|
||||||
|
clvmd
|
||||||
|
|
||||||
|
include $(top_srcdir)/make.tmpl
|
||||||
|
|
||||||
|
CFLAGS += -D_REENTRANT -fno-strict-aliasing
|
||||||
|
LIBS += -ldevmapper -llvm -lpthread
|
||||||
|
|
||||||
|
INSTALL_TARGETS = \
|
||||||
|
install_clvmd
|
||||||
|
|
||||||
|
clvmd: $(OBJECTS) $(top_srcdir)/lib/liblvm.a
|
||||||
|
$(CC) -o clvmd $(OBJECTS) $(LDFLAGS) $(LVMLIBS) $(LMLIBS) $(LIBS)
|
||||||
|
|
||||||
|
.PHONY: install_clvmd
|
||||||
|
|
||||||
|
install_clvmd: $(TARGETS)
|
||||||
|
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) clvmd \
|
||||||
|
$(sbindir)/clvmd
|
||||||
|
|
||||||
|
install: $(INSTALL_TARGETS)
|
||||||
|
|
||||||
|
install_cluster: $(INSTALL_TARGETS)
|
||||||
|
|
||||||
66
daemons/clvmd/clvm.h
Normal file
66
daemons/clvmd/clvm.h
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
|
||||||
|
* Copyright (C) 2004 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Definitions for CLVMD server and clients */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The protocol spoken over the cluster and across the local socket.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _CLVM_H
|
||||||
|
#define _CLVM_H
|
||||||
|
|
||||||
|
struct clvm_header {
|
||||||
|
uint8_t cmd; /* See below */
|
||||||
|
uint8_t flags; /* See below */
|
||||||
|
uint16_t xid; /* Transaction ID */
|
||||||
|
uint32_t clientid; /* Only used in Daemon->Daemon comms */
|
||||||
|
int32_t status; /* For replies, whether request succeeded */
|
||||||
|
uint32_t arglen; /* Length of argument below.
|
||||||
|
If >1500 then it will be passed
|
||||||
|
around the cluster in the system LV */
|
||||||
|
char node[1]; /* Actually a NUL-terminated string, node name.
|
||||||
|
If this is empty then the command is
|
||||||
|
forwarded to all cluster nodes unless
|
||||||
|
FLAG_LOCAL is also set. */
|
||||||
|
char args[1]; /* Arguments for the command follow the
|
||||||
|
node name, This member is only
|
||||||
|
valid if the node name is empty */
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
/* Flags */
|
||||||
|
#define CLVMD_FLAG_LOCAL 1 /* Only do this on the local node */
|
||||||
|
#define CLVMD_FLAG_SYSTEMLV 2 /* Data in system LV under my node name */
|
||||||
|
#define CLVMD_FLAG_NODEERRS 4 /* Reply has errors in node-specific portion */
|
||||||
|
|
||||||
|
/* Name of the local socket to communicate between libclvm and clvmd */
|
||||||
|
//static const char CLVMD_SOCKNAME[]="/var/run/clvmd";
|
||||||
|
static const char CLVMD_SOCKNAME[] = "\0clvmd";
|
||||||
|
|
||||||
|
/* Internal commands & replies */
|
||||||
|
#define CLVMD_CMD_REPLY 1
|
||||||
|
#define CLVMD_CMD_VERSION 2 /* Send version around cluster when we start */
|
||||||
|
#define CLVMD_CMD_GOAWAY 3 /* Die if received this - we are running
|
||||||
|
an incompatible version */
|
||||||
|
#define CLVMD_CMD_TEST 4 /* Just for mucking about */
|
||||||
|
|
||||||
|
#define CLVMD_CMD_LOCK 30
|
||||||
|
#define CLVMD_CMD_UNLOCK 31
|
||||||
|
|
||||||
|
/* Lock/Unlock commands */
|
||||||
|
#define CLVMD_CMD_LOCK_LV 50
|
||||||
|
#define CLVMD_CMD_LOCK_VG 51
|
||||||
|
|
||||||
|
#endif
|
||||||
540
daemons/clvmd/clvmd-cman.c
Normal file
540
daemons/clvmd/clvmd-cman.c
Normal file
@@ -0,0 +1,540 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
|
||||||
|
* Copyright (C) 2004 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CMAN communication layer for clvmd.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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 "clvmd-comms.h"
|
||||||
|
#include "clvm.h"
|
||||||
|
#include "libdlm.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "clvmd.h"
|
||||||
|
#include "lvm-functions.h"
|
||||||
|
|
||||||
|
#define LOCKSPACE_NAME "clvmd"
|
||||||
|
|
||||||
|
static int cluster_sock;
|
||||||
|
static int num_nodes;
|
||||||
|
static struct cl_cluster_node *nodes = NULL;
|
||||||
|
static int count_nodes; /* size of allocated nodes array */
|
||||||
|
static int max_updown_nodes = 50; /* Current size of the allocated array */
|
||||||
|
/* Node up/down status, indexed by nodeid */
|
||||||
|
static int *node_updown = NULL;
|
||||||
|
static dlm_lshandle_t *lockspace;
|
||||||
|
|
||||||
|
static void count_clvmds_running(void);
|
||||||
|
static void get_members(void);
|
||||||
|
static int nodeid_from_csid(char *csid);
|
||||||
|
static int name_from_nodeid(int nodeid, char *name);
|
||||||
|
|
||||||
|
struct lock_wait {
|
||||||
|
pthread_cond_t cond;
|
||||||
|
pthread_mutex_t mutex;
|
||||||
|
struct dlm_lksb lksb;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int _init_cluster(void)
|
||||||
|
{
|
||||||
|
struct sockaddr_cl saddr;
|
||||||
|
int port = CLUSTER_PORT_CLVMD;
|
||||||
|
|
||||||
|
/* Open the cluster communication socket */
|
||||||
|
cluster_sock = socket(AF_CLUSTER, SOCK_DGRAM, CLPROTO_CLIENT);
|
||||||
|
if (cluster_sock == -1) {
|
||||||
|
/* Don't print an error here because we could be just probing for CMAN */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/* Set Close-on-exec */
|
||||||
|
fcntl(cluster_sock, F_SETFD, 1);
|
||||||
|
|
||||||
|
/* Bind to our port number on the cluster.
|
||||||
|
Writes to this will block if the cluster loses quorum */
|
||||||
|
saddr.scl_family = AF_CLUSTER;
|
||||||
|
saddr.scl_port = port;
|
||||||
|
|
||||||
|
if (bind
|
||||||
|
(cluster_sock, (struct sockaddr *) &saddr,
|
||||||
|
sizeof(struct sockaddr_cl))) {
|
||||||
|
syslog(LOG_ERR, "Can't bind cluster socket: %m");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the cluster members list */
|
||||||
|
get_members();
|
||||||
|
count_clvmds_running();
|
||||||
|
|
||||||
|
/* Create a lockspace for LV & VG locks to live in */
|
||||||
|
lockspace = dlm_create_lockspace(LOCKSPACE_NAME, 0600);
|
||||||
|
if (!lockspace) {
|
||||||
|
syslog(LOG_ERR, "Unable to create lockspace for CLVM: %m");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
dlm_ls_pthread_init(lockspace);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _cluster_init_completed(void)
|
||||||
|
{
|
||||||
|
clvmd_cluster_init_completed();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _get_main_cluster_fd()
|
||||||
|
{
|
||||||
|
return cluster_sock;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _get_num_nodes()
|
||||||
|
{
|
||||||
|
return num_nodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* send_message with the fd check removed */
|
||||||
|
static int _cluster_send_message(void *buf, int msglen, char *csid, const char *errtext)
|
||||||
|
{
|
||||||
|
struct iovec iov[2];
|
||||||
|
struct msghdr msg;
|
||||||
|
struct sockaddr_cl saddr;
|
||||||
|
int len = 0;
|
||||||
|
|
||||||
|
msg.msg_control = NULL;
|
||||||
|
msg.msg_controllen = 0;
|
||||||
|
msg.msg_iovlen = 1;
|
||||||
|
msg.msg_iov = iov;
|
||||||
|
msg.msg_flags = 0;
|
||||||
|
iov[0].iov_len = msglen;
|
||||||
|
iov[0].iov_base = buf;
|
||||||
|
|
||||||
|
saddr.scl_family = AF_CLUSTER;
|
||||||
|
saddr.scl_port = CLUSTER_PORT_CLVMD;
|
||||||
|
if (csid) {
|
||||||
|
msg.msg_name = &saddr;
|
||||||
|
msg.msg_namelen = sizeof(saddr);
|
||||||
|
memcpy(&saddr.scl_nodeid, csid, CMAN_MAX_CSID_LEN);
|
||||||
|
} else { /* Cluster broadcast */
|
||||||
|
|
||||||
|
msg.msg_name = NULL;
|
||||||
|
msg.msg_namelen = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
len = sendmsg(cluster_sock, &msg, 0);
|
||||||
|
if (len < 0 && errno != EAGAIN)
|
||||||
|
log_error(errtext);
|
||||||
|
|
||||||
|
} while (len == -1 && errno == EAGAIN);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _get_our_csid(char *csid)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
memset(csid, 0, CMAN_MAX_CSID_LEN);
|
||||||
|
|
||||||
|
for (i = 0; i < num_nodes; i++) {
|
||||||
|
if (nodes[i].us)
|
||||||
|
memcpy(csid, &nodes[i].node_id, CMAN_MAX_CSID_LEN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Call a callback routine for each node that known (down mean not running a clvmd) */
|
||||||
|
static int _cluster_do_node_callback(struct local_client *client,
|
||||||
|
void (*callback) (struct local_client *, char *,
|
||||||
|
int))
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int somedown = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < _get_num_nodes(); i++) {
|
||||||
|
callback(client, (char *)&nodes[i].node_id, node_updown[nodes[i].node_id]);
|
||||||
|
if (!node_updown[nodes[i].node_id])
|
||||||
|
somedown = -1;
|
||||||
|
}
|
||||||
|
return somedown;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Process OOB message from the cluster socket,
|
||||||
|
this currently just means that a node has stopped listening on our port */
|
||||||
|
static void process_oob_msg(char *buf, int len, int nodeid)
|
||||||
|
{
|
||||||
|
char namebuf[256];
|
||||||
|
switch (buf[0]) {
|
||||||
|
case CLUSTER_OOB_MSG_PORTCLOSED:
|
||||||
|
name_from_nodeid(nodeid, namebuf);
|
||||||
|
log_notice("clvmd on node %s has died\n", namebuf);
|
||||||
|
DEBUGLOG("Got OOB message, removing node %s\n", namebuf);
|
||||||
|
|
||||||
|
node_updown[nodeid] = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLUSTER_OOB_MSG_STATECHANGE:
|
||||||
|
DEBUGLOG("Got OOB message, Cluster state change\n");
|
||||||
|
get_members();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* ERROR */
|
||||||
|
DEBUGLOG("Got unknown OOB message: %d\n", buf[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _cluster_fd_callback(struct local_client *client, char *buf, int len, char *csid,
|
||||||
|
struct local_client **new_client)
|
||||||
|
{
|
||||||
|
struct iovec iov[2];
|
||||||
|
struct msghdr msg;
|
||||||
|
struct sockaddr_cl saddr;
|
||||||
|
|
||||||
|
/* We never return a new client */
|
||||||
|
*new_client = NULL;
|
||||||
|
|
||||||
|
msg.msg_control = NULL;
|
||||||
|
msg.msg_controllen = 0;
|
||||||
|
msg.msg_iovlen = 1;
|
||||||
|
msg.msg_iov = iov;
|
||||||
|
msg.msg_name = &saddr;
|
||||||
|
msg.msg_flags = 0;
|
||||||
|
msg.msg_namelen = sizeof(saddr);
|
||||||
|
iov[0].iov_len = len;
|
||||||
|
iov[0].iov_base = buf;
|
||||||
|
|
||||||
|
len = recvmsg(cluster_sock, &msg, MSG_OOB | O_NONBLOCK);
|
||||||
|
if (len < 0 && errno == EAGAIN)
|
||||||
|
return len;
|
||||||
|
|
||||||
|
DEBUGLOG("Read on cluster socket, len = %d\n", len);
|
||||||
|
|
||||||
|
/* A real error */
|
||||||
|
if (len < 0) {
|
||||||
|
log_error("read error on cluster socket: %m");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* EOF - we have left the cluster */
|
||||||
|
if (len == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Is it OOB? probably a node gone down */
|
||||||
|
if (msg.msg_flags & MSG_OOB) {
|
||||||
|
process_oob_msg(iov[0].iov_base, len, saddr.scl_nodeid);
|
||||||
|
|
||||||
|
/* Tell the upper layer to ignore this message */
|
||||||
|
len = -1;
|
||||||
|
errno = EAGAIN;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
memcpy(csid, &saddr.scl_nodeid, sizeof(saddr.scl_nodeid));
|
||||||
|
/* Send it back to clvmd */
|
||||||
|
process_message(client, buf, len, csid);
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _add_up_node(char *csid)
|
||||||
|
{
|
||||||
|
/* It's up ! */
|
||||||
|
int nodeid = nodeid_from_csid(csid);
|
||||||
|
|
||||||
|
if (nodeid >= max_updown_nodes) {
|
||||||
|
int new_size = nodeid + 10;
|
||||||
|
int *new_updown = realloc(node_updown, new_size);
|
||||||
|
|
||||||
|
if (new_updown) {
|
||||||
|
node_updown = new_updown;
|
||||||
|
max_updown_nodes = new_size;
|
||||||
|
DEBUGLOG("realloced more space for nodes. now %d\n",
|
||||||
|
max_updown_nodes);
|
||||||
|
} else {
|
||||||
|
log_error
|
||||||
|
("Realloc failed. Node status for clvmd will be wrong. quitting\n");
|
||||||
|
exit(999);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
node_updown[nodeid] = 1;
|
||||||
|
DEBUGLOG("Added new node %d to updown list\n", nodeid);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _cluster_closedown()
|
||||||
|
{
|
||||||
|
unlock_all();
|
||||||
|
dlm_release_lockspace(LOCKSPACE_NAME, lockspace, 1);
|
||||||
|
close(cluster_sock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int is_listening(int nodeid)
|
||||||
|
{
|
||||||
|
struct cl_listen_request rq;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
rq.port = CLUSTER_PORT_CLVMD;
|
||||||
|
rq.nodeid = nodeid;
|
||||||
|
|
||||||
|
do {
|
||||||
|
status = ioctl(cluster_sock, SIOCCLUSTER_ISLISTENING, &rq);
|
||||||
|
if (status < 0 && errno == EBUSY) { /* Don't busywait */
|
||||||
|
sleep(1);
|
||||||
|
errno = EBUSY; /* In case sleep trashes it */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (status < 0 && errno == EBUSY);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Populate the list of CLVMDs running.
|
||||||
|
called only at startup time */
|
||||||
|
static void count_clvmds_running(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < num_nodes; i++) {
|
||||||
|
node_updown[nodes[i].node_id] = is_listening(nodes[i].node_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get a list of active cluster members */
|
||||||
|
static void get_members()
|
||||||
|
{
|
||||||
|
struct cl_cluster_nodelist nodelist;
|
||||||
|
|
||||||
|
num_nodes = ioctl(cluster_sock, SIOCCLUSTER_GETMEMBERS, 0);
|
||||||
|
if (num_nodes == -1) {
|
||||||
|
log_error("Unable to get node count");
|
||||||
|
} else {
|
||||||
|
/* Not enough room for new nodes list ? */
|
||||||
|
if (num_nodes > count_nodes && nodes) {
|
||||||
|
free(nodes);
|
||||||
|
nodes = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nodes == NULL) {
|
||||||
|
count_nodes = num_nodes + 10; /* Overallocate a little */
|
||||||
|
nodes = malloc(count_nodes * sizeof(struct cl_cluster_node));
|
||||||
|
if (!nodes) {
|
||||||
|
log_error("Unable to allocate nodes array\n");
|
||||||
|
exit(5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nodelist.max_members = count_nodes;
|
||||||
|
nodelist.nodes = nodes;
|
||||||
|
|
||||||
|
num_nodes = ioctl(cluster_sock, SIOCCLUSTER_GETMEMBERS, &nodelist);
|
||||||
|
if (num_nodes <= 0) {
|
||||||
|
log_error("Unable to get node details");
|
||||||
|
exit(6);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sanity check struct */
|
||||||
|
if (nodes[0].size != sizeof(struct cl_cluster_node)) {
|
||||||
|
log_error
|
||||||
|
("sizeof(cl_cluster_node) does not match size returned from the kernel: aborting\n");
|
||||||
|
exit(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node_updown == NULL) {
|
||||||
|
node_updown =
|
||||||
|
(int *) malloc(sizeof(int) *
|
||||||
|
max(num_nodes, max_updown_nodes));
|
||||||
|
memset(node_updown, 0,
|
||||||
|
sizeof(int) * max(num_nodes, max_updown_nodes));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert a node name to a CSID */
|
||||||
|
static int _csid_from_name(char *csid, char *name)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < num_nodes; i++) {
|
||||||
|
if (strcmp(name, nodes[i].name) == 0) {
|
||||||
|
memcpy(csid, &nodes[i].node_id, CMAN_MAX_CSID_LEN);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert a CSID to a node name */
|
||||||
|
static int _name_from_csid(char *csid, char *name)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < num_nodes; i++) {
|
||||||
|
if (memcmp(csid, &nodes[i].node_id, CMAN_MAX_CSID_LEN) == 0) {
|
||||||
|
strcpy(name, nodes[i].name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Who?? */
|
||||||
|
strcpy(name, "Unknown");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert a node ID to a node name */
|
||||||
|
static int name_from_nodeid(int nodeid, char *name)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < num_nodes; i++) {
|
||||||
|
if (nodeid == nodes[i].node_id) {
|
||||||
|
strcpy(name, nodes[i].name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Who?? */
|
||||||
|
strcpy(name, "Unknown");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert a CSID to a node ID */
|
||||||
|
static int nodeid_from_csid(char *csid)
|
||||||
|
{
|
||||||
|
int nodeid;
|
||||||
|
|
||||||
|
memcpy(&nodeid, csid, CMAN_MAX_CSID_LEN);
|
||||||
|
|
||||||
|
return nodeid;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _is_quorate()
|
||||||
|
{
|
||||||
|
return ioctl(cluster_sock, SIOCCLUSTER_ISQUORATE, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sync_ast_routine(void *arg)
|
||||||
|
{
|
||||||
|
struct lock_wait *lwait = arg;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&lwait->mutex);
|
||||||
|
pthread_cond_signal(&lwait->cond);
|
||||||
|
pthread_mutex_unlock(&lwait->mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _sync_lock(const char *resource, int mode, int flags, int *lockid)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
struct lock_wait lwait;
|
||||||
|
|
||||||
|
if (!lockid) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUGLOG("sync_lock: '%s' mode:%d flags=%d\n", resource,mode,flags);
|
||||||
|
/* Conversions need the lockid in the LKSB */
|
||||||
|
if (flags & LKF_CONVERT)
|
||||||
|
lwait.lksb.sb_lkid = *lockid;
|
||||||
|
|
||||||
|
pthread_cond_init(&lwait.cond, NULL);
|
||||||
|
pthread_mutex_init(&lwait.mutex, NULL);
|
||||||
|
pthread_mutex_lock(&lwait.mutex);
|
||||||
|
|
||||||
|
status = dlm_ls_lock(lockspace,
|
||||||
|
mode,
|
||||||
|
&lwait.lksb,
|
||||||
|
flags,
|
||||||
|
resource,
|
||||||
|
strlen(resource),
|
||||||
|
0, sync_ast_routine, &lwait, NULL, NULL);
|
||||||
|
if (status)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
/* Wait for it to complete */
|
||||||
|
pthread_cond_wait(&lwait.cond, &lwait.mutex);
|
||||||
|
pthread_mutex_unlock(&lwait.mutex);
|
||||||
|
|
||||||
|
*lockid = lwait.lksb.sb_lkid;
|
||||||
|
|
||||||
|
errno = lwait.lksb.sb_status;
|
||||||
|
DEBUGLOG("sync_lock: returning lkid %x\n", *lockid);
|
||||||
|
if (lwait.lksb.sb_status)
|
||||||
|
return -1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _sync_unlock(const char *resource /* UNUSED */, int lockid)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
struct lock_wait lwait;
|
||||||
|
|
||||||
|
DEBUGLOG("sync_unlock: '%s' lkid:%x\n", resource, lockid);
|
||||||
|
|
||||||
|
pthread_cond_init(&lwait.cond, NULL);
|
||||||
|
pthread_mutex_init(&lwait.mutex, NULL);
|
||||||
|
pthread_mutex_lock(&lwait.mutex);
|
||||||
|
|
||||||
|
status = dlm_ls_unlock(lockspace, lockid, 0, &lwait.lksb, &lwait);
|
||||||
|
|
||||||
|
if (status)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
/* Wait for it to complete */
|
||||||
|
pthread_cond_wait(&lwait.cond, &lwait.mutex);
|
||||||
|
pthread_mutex_unlock(&lwait.mutex);
|
||||||
|
|
||||||
|
errno = lwait.lksb.sb_status;
|
||||||
|
if (lwait.lksb.sb_status != EUNLOCK)
|
||||||
|
return -1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct cluster_ops _cluster_cman_ops = {
|
||||||
|
.cluster_init_completed = _cluster_init_completed,
|
||||||
|
.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,
|
||||||
|
.cluster_closedown = _cluster_closedown,
|
||||||
|
.sync_lock = _sync_lock,
|
||||||
|
.sync_unlock = _sync_unlock,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cluster_ops *init_cman_cluster(void)
|
||||||
|
{
|
||||||
|
if (!_init_cluster())
|
||||||
|
return &_cluster_cman_ops;
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
286
daemons/clvmd/clvmd-command.c
Normal file
286
daemons/clvmd/clvmd-command.c
Normal file
@@ -0,0 +1,286 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
|
||||||
|
* Copyright (C) 2004 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
CLVMD Cluster LVM daemon command processor.
|
||||||
|
|
||||||
|
To add commands to the daemon simply add a processor in do_command and return
|
||||||
|
and messages back in buf and the length in *retlen. The initial value of
|
||||||
|
buflen is the maximum size of the buffer. if buf is not large enough then it
|
||||||
|
may be reallocated by the functions in here to a suitable size bearing in
|
||||||
|
mind that anything larger than the passed-in size will have to be returned
|
||||||
|
using the system LV and so performance will suffer.
|
||||||
|
|
||||||
|
The status return will be negated and passed back to the originating node.
|
||||||
|
|
||||||
|
pre- and post- command routines are called only on the local node. The
|
||||||
|
purpose is primarily to get and release locks, though the pre- routine should
|
||||||
|
also do any other local setups required by the command (if any) and can
|
||||||
|
return a failure code that prevents the command from being distributed around
|
||||||
|
the cluster
|
||||||
|
|
||||||
|
The pre- and post- routines are run in their own thread so can block as long
|
||||||
|
they like, do_command is run in the main clvmd thread so should not block for
|
||||||
|
too long. If the pre-command returns an error code (!=0) then the command
|
||||||
|
will not be propogated around the cluster but the post-command WILL be called
|
||||||
|
|
||||||
|
Also note that the pre and post routine are *always* called on the local
|
||||||
|
node, even if the command to be executed was only requested to run on a
|
||||||
|
remote node. It may peek inside the client structure to check the status of
|
||||||
|
the command.
|
||||||
|
|
||||||
|
The clients of the daemon must, naturally, understand the return messages and
|
||||||
|
codes.
|
||||||
|
|
||||||
|
Routines in here may only READ the values in the client structure passed in
|
||||||
|
apart from client->private which they are free to do what they like with.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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 "list.h"
|
||||||
|
#include "hash.h"
|
||||||
|
#include "locking.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "lvm-functions.h"
|
||||||
|
#include "clvmd-comms.h"
|
||||||
|
#include "clvm.h"
|
||||||
|
#include "clvmd.h"
|
||||||
|
#include "libdlm.h"
|
||||||
|
|
||||||
|
/* This is where all the real work happens:
|
||||||
|
NOTE: client will be NULL when this is executed on a remote node */
|
||||||
|
int do_command(struct local_client *client, struct clvm_header *msg, int msglen,
|
||||||
|
char **buf, int buflen, int *retlen)
|
||||||
|
{
|
||||||
|
char *args = msg->node + strlen(msg->node) + 1;
|
||||||
|
int arglen = msglen - sizeof(struct clvm_header) - strlen(msg->node);
|
||||||
|
int status = 0;
|
||||||
|
char *lockname;
|
||||||
|
struct utsname nodeinfo;
|
||||||
|
unsigned char lock_cmd;
|
||||||
|
unsigned char lock_flags;
|
||||||
|
|
||||||
|
/* Do the command */
|
||||||
|
switch (msg->cmd) {
|
||||||
|
/* Just a test message */
|
||||||
|
case CLVMD_CMD_TEST:
|
||||||
|
if (arglen > buflen) {
|
||||||
|
buflen = arglen + 200;
|
||||||
|
*buf = realloc(*buf, buflen);
|
||||||
|
}
|
||||||
|
uname(&nodeinfo);
|
||||||
|
*retlen = 1 + snprintf(*buf, buflen, "TEST from %s: %s v%s",
|
||||||
|
nodeinfo.nodename, args,
|
||||||
|
nodeinfo.release);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLVMD_CMD_LOCK_VG:
|
||||||
|
/* Check to see if the VG is in use by LVM1 */
|
||||||
|
status = do_check_lvm1(&args[2]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLVMD_CMD_LOCK_LV:
|
||||||
|
/* This is the biggie */
|
||||||
|
lock_cmd = args[0];
|
||||||
|
lock_flags = args[1];
|
||||||
|
lockname = &args[2];
|
||||||
|
status = do_lock_lv(lock_cmd, lock_flags, lockname);
|
||||||
|
/* Replace EIO with something less scary */
|
||||||
|
if (status == EIO) {
|
||||||
|
*retlen =
|
||||||
|
1 + snprintf(*buf, buflen,
|
||||||
|
"Internal lvm error, check syslog");
|
||||||
|
return EIO;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* Won't get here because command is validated in pre_command */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check the status of the command and return the error text */
|
||||||
|
if (status) {
|
||||||
|
*retlen = 1 + snprintf(*buf, buflen, strerror(status));
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lock_vg(struct local_client *client)
|
||||||
|
{
|
||||||
|
struct hash_table *lock_hash;
|
||||||
|
struct clvm_header *header =
|
||||||
|
(struct clvm_header *) client->bits.localsock.cmd;
|
||||||
|
unsigned char lock_cmd;
|
||||||
|
unsigned char lock_flags;
|
||||||
|
char *args = header->node + strlen(header->node) + 1;
|
||||||
|
int lkid;
|
||||||
|
int status = 0;
|
||||||
|
char *lockname;
|
||||||
|
|
||||||
|
/* Keep a track of VG locks in our own hash table. In current
|
||||||
|
practice there should only ever be more than two VGs locked
|
||||||
|
if a user tries to merge lots of them at once */
|
||||||
|
if (client->bits.localsock.private) {
|
||||||
|
lock_hash = (struct hash_table *)client->bits.localsock.private;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lock_hash = hash_create(3);
|
||||||
|
if (!lock_hash)
|
||||||
|
return ENOMEM;
|
||||||
|
client->bits.localsock.private = (void *)lock_hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
lock_cmd = args[0];
|
||||||
|
lock_flags = args[1];
|
||||||
|
lockname = &args[2];
|
||||||
|
DEBUGLOG("doing PRE command LOCK_VG '%s' at %x (client=%p)\n", lockname, lock_cmd, client);
|
||||||
|
|
||||||
|
if (lock_cmd == LCK_UNLOCK) {
|
||||||
|
|
||||||
|
lkid = (int)(long)hash_lookup(lock_hash, lockname);
|
||||||
|
if (lkid == 0)
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
status = sync_unlock(lockname, lkid);
|
||||||
|
if (status)
|
||||||
|
status = errno;
|
||||||
|
else
|
||||||
|
hash_remove(lock_hash, lockname);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
status = sync_lock(lockname, (int)lock_cmd, (int)lock_flags, &lkid);
|
||||||
|
if (status)
|
||||||
|
status = errno;
|
||||||
|
else
|
||||||
|
hash_insert(lock_hash, lockname, (void *)lkid);
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Pre-command is a good place to get locks that are needed only for the duration
|
||||||
|
of the commands around the cluster (don't forget to free them in post-command),
|
||||||
|
and to sanity check the command arguments */
|
||||||
|
int do_pre_command(struct local_client *client)
|
||||||
|
{
|
||||||
|
struct clvm_header *header =
|
||||||
|
(struct clvm_header *) client->bits.localsock.cmd;
|
||||||
|
unsigned char lock_cmd;
|
||||||
|
unsigned char lock_flags;
|
||||||
|
char *args = header->node + strlen(header->node) + 1;
|
||||||
|
int lockid;
|
||||||
|
int status = 0;
|
||||||
|
char *lockname;
|
||||||
|
|
||||||
|
switch (header->cmd) {
|
||||||
|
case CLVMD_CMD_TEST:
|
||||||
|
status = sync_lock("CLVMD_TEST", LKM_EXMODE, 0, &lockid);
|
||||||
|
client->bits.localsock.private = (void *) lockid;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLVMD_CMD_LOCK_VG:
|
||||||
|
status = lock_vg(client);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLVMD_CMD_LOCK_LV:
|
||||||
|
lock_cmd = args[0];
|
||||||
|
lock_flags = args[1];
|
||||||
|
lockname = &args[2];
|
||||||
|
status = pre_lock_lv(lock_cmd, lock_flags, lockname);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
log_error("Unknown command %d received\n", header->cmd);
|
||||||
|
status = EINVAL;
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Note that the post-command routine is called even if the pre-command or the real command
|
||||||
|
failed */
|
||||||
|
int do_post_command(struct local_client *client)
|
||||||
|
{
|
||||||
|
struct clvm_header *header =
|
||||||
|
(struct clvm_header *) client->bits.localsock.cmd;
|
||||||
|
int status = 0;
|
||||||
|
unsigned char lock_cmd;
|
||||||
|
unsigned char lock_flags;
|
||||||
|
char *args = header->node + strlen(header->node) + 1;
|
||||||
|
char *lockname;
|
||||||
|
|
||||||
|
switch (header->cmd) {
|
||||||
|
case CLVMD_CMD_TEST:
|
||||||
|
status =
|
||||||
|
sync_unlock("CLVMD_TEST", (int) (long) client->bits.localsock.private);
|
||||||
|
client->bits.localsock.private = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLVMD_CMD_LOCK_VG:
|
||||||
|
/* Nothing to do here */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLVMD_CMD_LOCK_LV:
|
||||||
|
lock_cmd = args[0];
|
||||||
|
lock_flags = args[1];
|
||||||
|
lockname = &args[2];
|
||||||
|
status = post_lock_lv(lock_cmd, lock_flags, lockname);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Called when the client is about to be deleted */
|
||||||
|
void cmd_client_cleanup(struct local_client *client)
|
||||||
|
{
|
||||||
|
if (client->bits.localsock.private) {
|
||||||
|
|
||||||
|
struct hash_node *v;
|
||||||
|
struct hash_table *lock_hash =
|
||||||
|
(struct hash_table *)client->bits.localsock.private;
|
||||||
|
|
||||||
|
hash_iterate(v, lock_hash) {
|
||||||
|
int lkid = (int)(long)hash_get_data(lock_hash, v);
|
||||||
|
char *lockname = hash_get_key(lock_hash, v);
|
||||||
|
|
||||||
|
DEBUGLOG("cleanup: Unlocking lock %s %x\n", lockname, lkid);
|
||||||
|
sync_unlock(lockname, lkid);
|
||||||
|
}
|
||||||
|
|
||||||
|
hash_destroy(lock_hash);
|
||||||
|
client->bits.localsock.private = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
70
daemons/clvmd/clvmd-comms.h
Normal file
70
daemons/clvmd/clvmd-comms.h
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
|
||||||
|
* Copyright (C) 2004 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Abstraction layer for clvmd cluster communications
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _CLVMD_COMMS_H
|
||||||
|
#define _CLVMD_COMMS_H
|
||||||
|
|
||||||
|
struct local_client;
|
||||||
|
|
||||||
|
struct cluster_ops {
|
||||||
|
void (*cluster_init_completed) (void);
|
||||||
|
|
||||||
|
int (*cluster_send_message) (void *buf, int msglen, char *csid,
|
||||||
|
const char *errtext);
|
||||||
|
int (*name_from_csid) (char *csid, char *name);
|
||||||
|
int (*csid_from_name) (char *csid, char *name);
|
||||||
|
int (*get_num_nodes) (void);
|
||||||
|
int (*cluster_fd_callback) (struct local_client *fd, char *buf, int len,
|
||||||
|
char *csid, struct local_client **new_client);
|
||||||
|
int (*get_main_cluster_fd) (void); /* gets accept FD or cman cluster socket */
|
||||||
|
int (*cluster_do_node_callback) (struct local_client *client,
|
||||||
|
void (*callback) (struct local_client *,
|
||||||
|
char *csid, int node_up));
|
||||||
|
int (*is_quorate) (void);
|
||||||
|
|
||||||
|
void (*get_our_csid) (char *csid);
|
||||||
|
void (*add_up_node) (char *csid);
|
||||||
|
void (*reread_config) (void);
|
||||||
|
void (*cluster_closedown) (void);
|
||||||
|
|
||||||
|
int (*sync_lock) (const char *resource, int mode, int flags, int *lockid);
|
||||||
|
int (*sync_unlock) (const char *resource, int lockid);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef USE_GULM
|
||||||
|
# include "tcp-comms.h"
|
||||||
|
struct cluster_ops *init_gulm_cluster(void);
|
||||||
|
#define MAX_CSID_LEN GULM_MAX_CSID_LEN
|
||||||
|
#define MAX_CLUSTER_MEMBER_NAME_LEN GULM_MAX_CLUSTER_MEMBER_NAME_LEN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_CMAN
|
||||||
|
# include "cnxman-socket.h"
|
||||||
|
# define CMAN_MAX_CSID_LEN 4
|
||||||
|
# ifndef MAX_CSID_LEN
|
||||||
|
# define MAX_CSID_LEN CMAN_MAX_CSID_LEN
|
||||||
|
# endif
|
||||||
|
# undef MAX_CLUSTER_MEMBER_NAME_LEN
|
||||||
|
# define MAX_CLUSTER_MEMBER_NAME_LEN CMAN_MAX_CLUSTER_MEMBER_NAME_LEN
|
||||||
|
struct cluster_ops *init_cman_cluster(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
997
daemons/clvmd/clvmd-gulm.c
Normal file
997
daemons/clvmd/clvmd-gulm.c
Normal file
@@ -0,0 +1,997 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
*******************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) Sistina Software, Inc. 2002-2003 All rights reserved.
|
||||||
|
** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
|
||||||
|
**
|
||||||
|
*******************************************************************************
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/* This provides the interface between clvmd and gulm as the cluster
|
||||||
|
* and lock manager.
|
||||||
|
*
|
||||||
|
* It also provides the "liblm" functions too as it's hard (and pointless)
|
||||||
|
* to seperate them out when using gulm.
|
||||||
|
*
|
||||||
|
* What it does /not/ provide is the communications between clvmd daemons
|
||||||
|
* on the cluster nodes. That is done in tcp-comms.c
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/utsname.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/file.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <utmpx.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "ccs.h"
|
||||||
|
#include "list.h"
|
||||||
|
#include "locking.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "clvm.h"
|
||||||
|
#include "clvmd-comms.h"
|
||||||
|
#include "lvm-functions.h"
|
||||||
|
#include "clvmd.h"
|
||||||
|
#include "hash.h"
|
||||||
|
#include "clvmd-gulm.h"
|
||||||
|
#include "libgulm.h"
|
||||||
|
#include "hash.h"
|
||||||
|
|
||||||
|
/* Hash list of nodes in the cluster */
|
||||||
|
static struct hash_table *node_hash;
|
||||||
|
|
||||||
|
/* hash list of outstanding lock requests */
|
||||||
|
static struct hash_table *lock_hash;
|
||||||
|
|
||||||
|
/* Copy of the current quorate state */
|
||||||
|
static uint8_t gulm_quorate = 0;
|
||||||
|
static enum {INIT_NOTDONE, INIT_DONE, INIT_WAITQUORATE} init_state = INIT_NOTDONE;
|
||||||
|
|
||||||
|
/* Number of active nodes */
|
||||||
|
static int num_nodes;
|
||||||
|
|
||||||
|
static char *cluster_name;
|
||||||
|
static int in_shutdown = 0;
|
||||||
|
|
||||||
|
static pthread_mutex_t lock_start_mutex;
|
||||||
|
static volatile int lock_start_flag;
|
||||||
|
|
||||||
|
struct node_info
|
||||||
|
{
|
||||||
|
enum {NODE_UNKNOWN, NODE_DOWN, NODE_UP, NODE_CLVMD} state;
|
||||||
|
char name[GULM_MAX_CLUSTER_MEMBER_NAME_LEN];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct lock_wait
|
||||||
|
{
|
||||||
|
pthread_cond_t cond;
|
||||||
|
pthread_mutex_t mutex;
|
||||||
|
int status;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Forward */
|
||||||
|
static int read_from_core_sock(struct local_client *client, char *buf, int len, char *csid,
|
||||||
|
struct local_client **new_client);
|
||||||
|
static int read_from_lock_sock(struct local_client *client, char *buf, int len, char *csid,
|
||||||
|
struct local_client **new_client);
|
||||||
|
static int get_all_cluster_nodes(void);
|
||||||
|
static int _csid_from_name(char *csid, char *name);
|
||||||
|
static void _cluster_closedown(void);
|
||||||
|
|
||||||
|
/* In tcp-comms.c */
|
||||||
|
extern struct hash_table *sock_hash;
|
||||||
|
|
||||||
|
static int add_internal_client(int fd, fd_callback_t callback)
|
||||||
|
{
|
||||||
|
struct local_client *client;
|
||||||
|
|
||||||
|
DEBUGLOG("Add_internal_client, fd = %d\n", fd);
|
||||||
|
|
||||||
|
/* Add a GULM file descriptor it to the main loop */
|
||||||
|
client = malloc(sizeof(struct local_client));
|
||||||
|
if (!client)
|
||||||
|
{
|
||||||
|
DEBUGLOG("malloc failed\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(client, 0, sizeof(struct local_client));
|
||||||
|
client->fd = fd;
|
||||||
|
client->type = CLUSTER_INTERNAL;
|
||||||
|
client->callback = callback;
|
||||||
|
add_client(client);
|
||||||
|
|
||||||
|
/* Set Close-on-exec */
|
||||||
|
fcntl(fd, F_SETFD, 1);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Gulm library handle */
|
||||||
|
static gulm_interface_p gulm_if;
|
||||||
|
static lg_core_callbacks_t core_callbacks;
|
||||||
|
static lg_lockspace_callbacks_t lock_callbacks;
|
||||||
|
|
||||||
|
static void badsig_handler(int sig)
|
||||||
|
{
|
||||||
|
DEBUGLOG("got sig %d\n", sig);
|
||||||
|
_cluster_closedown();
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _reread_config(void)
|
||||||
|
{
|
||||||
|
/* Re-read CCS node list */
|
||||||
|
DEBUGLOG("Re-reading CCS config\n");
|
||||||
|
get_all_cluster_nodes();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _init_cluster(void)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
int ccs_h;
|
||||||
|
int port = 0;
|
||||||
|
char *portstr;
|
||||||
|
|
||||||
|
/* Get cluster name from CCS */
|
||||||
|
ccs_h = ccs_force_connect(NULL, 0);
|
||||||
|
if (ccs_h < 0)
|
||||||
|
{
|
||||||
|
syslog(LOG_ERR, "Cannot login in to CCSD server\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ccs_get(ccs_h, "//cluster/@name", &cluster_name);
|
||||||
|
DEBUGLOG("got cluster name %s\n", cluster_name);
|
||||||
|
|
||||||
|
if (!ccs_get(ccs_h, "//cluster/clvm/@port", &portstr))
|
||||||
|
{
|
||||||
|
port = atoi(portstr);
|
||||||
|
free(portstr);
|
||||||
|
DEBUGLOG("got port number %d\n", port);
|
||||||
|
|
||||||
|
if (port <= 0 && port >= 65536)
|
||||||
|
port = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ccs_disconnect(ccs_h);
|
||||||
|
|
||||||
|
/* Block locking until we are logged in */
|
||||||
|
pthread_mutex_init(&lock_start_mutex, NULL);
|
||||||
|
pthread_mutex_lock(&lock_start_mutex);
|
||||||
|
lock_start_flag = 1;
|
||||||
|
|
||||||
|
node_hash = hash_create(100);
|
||||||
|
lock_hash = hash_create(10);
|
||||||
|
|
||||||
|
/* Get all nodes from CCS */
|
||||||
|
if (get_all_cluster_nodes())
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Initialise GULM library */
|
||||||
|
status = lg_initialize(&gulm_if, cluster_name, "clvmd");
|
||||||
|
if (status)
|
||||||
|
{
|
||||||
|
DEBUGLOG("lg_initialize failed: %d\n", status);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Connect to core - we are not "important" :-) */
|
||||||
|
status = lg_core_login(gulm_if, 0);
|
||||||
|
if (status)
|
||||||
|
{
|
||||||
|
DEBUGLOG("lg_core_login failed: %d\n", status);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialise the inter-node comms */
|
||||||
|
status = init_comms(port);
|
||||||
|
if (status)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
/* Add core FD to the list */
|
||||||
|
status = add_internal_client(lg_core_selector(gulm_if), read_from_core_sock);
|
||||||
|
if (status)
|
||||||
|
{
|
||||||
|
DEBUGLOG("can't allocate client space\n");
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Connect to the lock server */
|
||||||
|
if (lg_lock_login(gulm_if, "CLVM"))
|
||||||
|
{
|
||||||
|
syslog(LOG_ERR, "Cannot login in to LOCK server\n");
|
||||||
|
DEBUGLOG("Cannot login in to LOCK server\n");
|
||||||
|
exit(88);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add lockspace FD to the list */
|
||||||
|
status = add_internal_client(lg_lock_selector(gulm_if), read_from_lock_sock);
|
||||||
|
if (status)
|
||||||
|
{
|
||||||
|
DEBUGLOG("can't allocate client space\n");
|
||||||
|
exit(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Request a list of nodes, we can't really do anything until
|
||||||
|
this comes back */
|
||||||
|
status = lg_core_nodelist(gulm_if);
|
||||||
|
if (status)
|
||||||
|
{
|
||||||
|
DEBUGLOG("lg_core_nodelist failed: %d\n", status);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* So I can kill it without taking GULM down too */
|
||||||
|
signal(SIGINT, badsig_handler);
|
||||||
|
signal(SIGTERM, badsig_handler);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _cluster_closedown(void)
|
||||||
|
{
|
||||||
|
DEBUGLOG("cluster_closedown\n");
|
||||||
|
in_shutdown = 1;
|
||||||
|
unlock_all();
|
||||||
|
lg_lock_logout(gulm_if);
|
||||||
|
lg_core_logout(gulm_if);
|
||||||
|
lg_release(gulm_if);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Expire locks for a named node, or us */
|
||||||
|
#define GIO_KEY_SIZE 46
|
||||||
|
static void drop_expired_locks(char *nodename)
|
||||||
|
{
|
||||||
|
struct utsname nodeinfo;
|
||||||
|
uint8_t mask[GIO_KEY_SIZE];
|
||||||
|
|
||||||
|
DEBUGLOG("Dropping expired locks for %s\n", nodename?nodename:"(null)");
|
||||||
|
memset(mask, 0xff, GIO_KEY_SIZE);
|
||||||
|
|
||||||
|
if (!nodename)
|
||||||
|
{
|
||||||
|
uname(&nodeinfo);
|
||||||
|
nodename = nodeinfo.nodename;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lg_lock_drop_exp(gulm_if, nodename, mask, GIO_KEY_SIZE))
|
||||||
|
{
|
||||||
|
DEBUGLOG("Error calling lg_lock_drop_exp()\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int read_from_core_sock(struct local_client *client, char *buf, int len, char *csid,
|
||||||
|
struct local_client **new_client)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
|
||||||
|
*new_client = NULL;
|
||||||
|
status = lg_core_handle_messages(gulm_if, &core_callbacks, NULL);
|
||||||
|
return status<0 ? status : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int read_from_lock_sock(struct local_client *client, char *buf, int len, char *csid,
|
||||||
|
struct local_client **new_client)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
|
||||||
|
*new_client = NULL;
|
||||||
|
status = lg_lock_handle_messages(gulm_if, &lock_callbacks, NULL);
|
||||||
|
return status<0 ? status : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* CORE callback routines */
|
||||||
|
static int core_login_reply(void *misc, uint64_t gen, uint32_t error, uint32_t rank, uint8_t corestate)
|
||||||
|
{
|
||||||
|
DEBUGLOG("CORE Got a Login reply. gen:%lld err:%d rank:%d corestate:%d\n",
|
||||||
|
gen, error, rank, corestate);
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
exit(error);
|
||||||
|
|
||||||
|
/* Get the current core state (for quorum) */
|
||||||
|
lg_core_corestate(gulm_if);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_node_state(struct node_info *ninfo, char *csid, uint8_t nodestate)
|
||||||
|
{
|
||||||
|
int oldstate = ninfo->state;
|
||||||
|
|
||||||
|
if (nodestate == lg_core_Logged_in)
|
||||||
|
{
|
||||||
|
/* Don't clobber NODE_CLVMD state */
|
||||||
|
if (ninfo->state != NODE_CLVMD)
|
||||||
|
{
|
||||||
|
if (ninfo->state == NODE_UNKNOWN ||
|
||||||
|
ninfo->state == NODE_DOWN)
|
||||||
|
num_nodes++;
|
||||||
|
|
||||||
|
ninfo->state = NODE_UP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (nodestate == lg_core_Expired ||
|
||||||
|
nodestate == lg_core_Fenced ||
|
||||||
|
nodestate == lg_core_Logged_out)
|
||||||
|
{
|
||||||
|
if (ninfo->state != NODE_DOWN)
|
||||||
|
num_nodes--;
|
||||||
|
ninfo->state = NODE_DOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Gulm doesn't always send node DOWN events, so even if this a a node UP we must
|
||||||
|
* assume (ahem) that it prevously went down at some time. So we close
|
||||||
|
* the sockets here to make sure that we don't have any dead connections
|
||||||
|
* to that node.
|
||||||
|
*/
|
||||||
|
tcp_remove_client(csid);
|
||||||
|
|
||||||
|
DEBUGLOG("set_node_state, '%s' state = %d (oldstate=%d), num_nodes=%d\n",
|
||||||
|
ninfo->name, ninfo->state, oldstate, num_nodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct node_info *add_or_set_node(char *name, struct in6_addr *ip, uint8_t state)
|
||||||
|
{
|
||||||
|
struct node_info *ninfo;
|
||||||
|
|
||||||
|
ninfo = hash_lookup_binary(node_hash, (char *)ip, GULM_MAX_CSID_LEN);
|
||||||
|
if (!ninfo)
|
||||||
|
{
|
||||||
|
/* If we can't find that node then re-read the config file in case it
|
||||||
|
was added after we were started */
|
||||||
|
DEBUGLOG("Node %s not found, re-reading config file\n", name);
|
||||||
|
get_all_cluster_nodes();
|
||||||
|
|
||||||
|
/* Now try again */
|
||||||
|
ninfo = hash_lookup_binary(node_hash, (char *)ip, GULM_MAX_CSID_LEN);
|
||||||
|
if (!ninfo)
|
||||||
|
{
|
||||||
|
DEBUGLOG("Ignoring node %s, not part of the SAN cluster\n", name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set_node_state(ninfo, (char *)ip, state);
|
||||||
|
|
||||||
|
return ninfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _get_our_csid(char *csid)
|
||||||
|
{
|
||||||
|
get_our_gulm_csid(csid);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int core_nodelist(void *misc, lglcb_t type, char *name, struct in6_addr *ip, uint8_t state)
|
||||||
|
{
|
||||||
|
DEBUGLOG("CORE nodelist\n");
|
||||||
|
|
||||||
|
if (type == lglcb_start)
|
||||||
|
{
|
||||||
|
DEBUGLOG("Got Nodelist, start\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (type == lglcb_item)
|
||||||
|
{
|
||||||
|
DEBUGLOG("Got nodelist, item: %s, %#x\n", name, state);
|
||||||
|
|
||||||
|
add_or_set_node(name, ip, state);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (type == lglcb_stop)
|
||||||
|
{
|
||||||
|
char ourcsid[GULM_MAX_CSID_LEN];
|
||||||
|
|
||||||
|
DEBUGLOG("Got Nodelist, stop\n");
|
||||||
|
if (gulm_quorate)
|
||||||
|
{
|
||||||
|
clvmd_cluster_init_completed();
|
||||||
|
init_state = INIT_DONE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (init_state == INIT_NOTDONE)
|
||||||
|
init_state = INIT_WAITQUORATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mark ourself as up */
|
||||||
|
_get_our_csid(ourcsid);
|
||||||
|
gulm_add_up_node(ourcsid);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DEBUGLOG("Unknown lglcb_t %#x\n", type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int core_statechange(void *misc, uint8_t corestate, uint8_t quorate, struct in6_addr *masterip, char *mastername)
|
||||||
|
{
|
||||||
|
DEBUGLOG("CORE Got statechange. quorate:%d, corestate:%x mastername:%s\n",
|
||||||
|
quorate, corestate, mastername);
|
||||||
|
|
||||||
|
gulm_quorate = quorate;
|
||||||
|
if (quorate && init_state == INIT_WAITQUORATE)
|
||||||
|
{
|
||||||
|
clvmd_cluster_init_completed();
|
||||||
|
init_state = INIT_DONE;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int core_nodechange(void *misc, char *nodename, struct in6_addr *nodeip, uint8_t nodestate)
|
||||||
|
{
|
||||||
|
struct node_info *ninfo;
|
||||||
|
|
||||||
|
DEBUGLOG("CORE node change, name=%s, state = %d\n", nodename, nodestate);
|
||||||
|
|
||||||
|
/* If we don't get nodeip here, try a lookup by name */
|
||||||
|
if (!nodeip)
|
||||||
|
_csid_from_name((char *)nodeip, nodename);
|
||||||
|
if (!nodeip)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ninfo = add_or_set_node(nodename, nodeip, nodestate);
|
||||||
|
if (!ninfo)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Check if we need to drop any expired locks */
|
||||||
|
if (ninfo->state == NODE_DOWN)
|
||||||
|
{
|
||||||
|
drop_expired_locks(nodename);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static int core_error(void *misc, uint32_t err)
|
||||||
|
{
|
||||||
|
DEBUGLOG("CORE error: %d\n", err);
|
||||||
|
// Not sure what happens here
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* LOCK callback routines */
|
||||||
|
static int lock_login_reply(void *misc, uint32_t error, uint8_t which)
|
||||||
|
{
|
||||||
|
DEBUGLOG("LOCK Got a Login reply. err:%d which:%d\n",
|
||||||
|
error, which);
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
exit(error);
|
||||||
|
|
||||||
|
/* Drop any expired locks for us that might be hanging around */
|
||||||
|
drop_expired_locks(NULL);
|
||||||
|
|
||||||
|
/* Enable locking operations in other threads */
|
||||||
|
if (lock_start_flag)
|
||||||
|
{
|
||||||
|
lock_start_flag = 0;
|
||||||
|
pthread_mutex_unlock(&lock_start_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lock_lock_state(void *misc, uint8_t *key, uint16_t keylen,
|
||||||
|
uint64_t subid, uint64_t start, uint64_t stop,
|
||||||
|
uint8_t state, uint32_t flags, uint32_t error,
|
||||||
|
uint8_t *LVB, uint16_t LVBlen)
|
||||||
|
{
|
||||||
|
struct lock_wait *lwait;
|
||||||
|
|
||||||
|
DEBUGLOG("LOCK lock state: %s, error = %d\n", key, error);
|
||||||
|
|
||||||
|
/* No waiting process to wake up when we are shutting down */
|
||||||
|
if (in_shutdown)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
lwait = hash_lookup(lock_hash, key);
|
||||||
|
if (!lwait)
|
||||||
|
{
|
||||||
|
DEBUGLOG("Can't find hash entry for resource %s\n", key);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
lwait->status = error;
|
||||||
|
pthread_mutex_lock(&lwait->mutex);
|
||||||
|
pthread_cond_signal(&lwait->cond);
|
||||||
|
pthread_mutex_unlock(&lwait->mutex);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static int lock_error(void *misc, uint32_t err)
|
||||||
|
{
|
||||||
|
DEBUGLOG("LOCK error: %d\n", err);
|
||||||
|
// Not sure what happens here
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* CORE callbacks */
|
||||||
|
static lg_core_callbacks_t core_callbacks = {
|
||||||
|
.login_reply = core_login_reply,
|
||||||
|
.nodelist = core_nodelist,
|
||||||
|
.statechange = core_statechange,
|
||||||
|
.nodechange = core_nodechange,
|
||||||
|
.error = core_error,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* LOCK callbacks */
|
||||||
|
static lg_lockspace_callbacks_t lock_callbacks = {
|
||||||
|
.login_reply = lock_login_reply,
|
||||||
|
.lock_state = lock_lock_state,
|
||||||
|
.error = lock_error,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Allow tcp-comms to loop round the list of active nodes */
|
||||||
|
int get_next_node_csid(void **context, char *csid)
|
||||||
|
{
|
||||||
|
struct node_info *ninfo = NULL;
|
||||||
|
|
||||||
|
/* First node */
|
||||||
|
if (!*context)
|
||||||
|
{
|
||||||
|
*context = hash_get_first(node_hash);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*context = hash_get_next(node_hash, *context);
|
||||||
|
}
|
||||||
|
if (*context)
|
||||||
|
ninfo = hash_get_data(node_hash, *context);
|
||||||
|
|
||||||
|
/* Find a node that is UP */
|
||||||
|
while (*context && ninfo->state == NODE_DOWN)
|
||||||
|
{
|
||||||
|
*context = hash_get_next(node_hash, *context);
|
||||||
|
if (*context)
|
||||||
|
{
|
||||||
|
ninfo = hash_get_data(node_hash, *context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!*context || ninfo->state == NODE_DOWN)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(csid, hash_get_key(node_hash, *context), GULM_MAX_CSID_LEN);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int gulm_name_from_csid(char *csid, char *name)
|
||||||
|
{
|
||||||
|
struct node_info *ninfo;
|
||||||
|
|
||||||
|
ninfo = hash_lookup_binary(node_hash, csid, GULM_MAX_CSID_LEN);
|
||||||
|
if (!ninfo)
|
||||||
|
{
|
||||||
|
sprintf(name, "UNKNOWN %s", print_csid(csid));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(name, ninfo->name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int _csid_from_name(char *csid, char *name)
|
||||||
|
{
|
||||||
|
struct hash_node *hn;
|
||||||
|
struct node_info *ninfo;
|
||||||
|
|
||||||
|
hash_iterate(hn, node_hash)
|
||||||
|
{
|
||||||
|
ninfo = hash_get_data(node_hash, hn);
|
||||||
|
if (strcmp(ninfo->name, name) == 0)
|
||||||
|
{
|
||||||
|
memcpy(csid, hash_get_key(node_hash, hn), GULM_MAX_CSID_LEN);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _get_num_nodes()
|
||||||
|
{
|
||||||
|
DEBUGLOG("num_nodes = %d\n", num_nodes);
|
||||||
|
return num_nodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Node is now known to be running a clvmd */
|
||||||
|
void gulm_add_up_node(char *csid)
|
||||||
|
{
|
||||||
|
struct node_info *ninfo;
|
||||||
|
|
||||||
|
ninfo = hash_lookup_binary(node_hash, csid, GULM_MAX_CSID_LEN);
|
||||||
|
if (!ninfo) {
|
||||||
|
DEBUGLOG("gulm_add_up_node no node_hash entry for csid %s\n", print_csid(csid));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUGLOG("gulm_add_up_node %s\n", ninfo->name);
|
||||||
|
|
||||||
|
if (ninfo->state == NODE_DOWN)
|
||||||
|
num_nodes++;
|
||||||
|
ninfo->state = NODE_CLVMD;
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
/* Node is now known to be NOT running a clvmd */
|
||||||
|
void add_down_node(char *csid)
|
||||||
|
{
|
||||||
|
struct node_info *ninfo;
|
||||||
|
|
||||||
|
ninfo = hash_lookup_binary(node_hash, csid, GULM_MAX_CSID_LEN);
|
||||||
|
if (!ninfo)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Only set it to UP if it was previously known to be
|
||||||
|
running clvmd - gulm may set it DOWN quite soon */
|
||||||
|
if (ninfo->state == NODE_CLVMD)
|
||||||
|
ninfo->state = NODE_UP;
|
||||||
|
drop_expired_locks(ninfo->name);
|
||||||
|
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 *, char *csid, int node_up))
|
||||||
|
{
|
||||||
|
struct hash_node *hn;
|
||||||
|
struct node_info *ninfo;
|
||||||
|
|
||||||
|
hash_iterate(hn, node_hash)
|
||||||
|
{
|
||||||
|
char csid[GULM_MAX_CSID_LEN];
|
||||||
|
struct local_client *client;
|
||||||
|
|
||||||
|
ninfo = hash_get_data(node_hash, hn);
|
||||||
|
memcpy(csid, hash_get_key(node_hash, hn), GULM_MAX_CSID_LEN);
|
||||||
|
|
||||||
|
DEBUGLOG("down_callback. node %s, state = %d\n", ninfo->name, ninfo->state);
|
||||||
|
|
||||||
|
client = hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
|
||||||
|
if (!client)
|
||||||
|
{
|
||||||
|
/* If it's up but not connected, try to make contact */
|
||||||
|
if (ninfo->state == NODE_UP)
|
||||||
|
gulm_connect_csid(csid, &client);
|
||||||
|
|
||||||
|
client = hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
|
||||||
|
|
||||||
|
}
|
||||||
|
if (ninfo->state != NODE_DOWN)
|
||||||
|
callback(master_client, csid, ninfo->state == NODE_CLVMD);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert gulm error codes to unix errno numbers */
|
||||||
|
static int gulm_to_errno(int gulm_ret)
|
||||||
|
{
|
||||||
|
switch (gulm_ret)
|
||||||
|
{
|
||||||
|
case lg_err_TryFailed:
|
||||||
|
case lg_err_AlreadyPend:
|
||||||
|
errno = EAGAIN;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* More?? */
|
||||||
|
default:
|
||||||
|
errno = EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return gulm_ret ? -1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Real locking */
|
||||||
|
static int _lock_resource(char *resource, int mode, int flags, int *lockid)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
struct lock_wait lwait;
|
||||||
|
|
||||||
|
/* Wait until the lock module is ready */
|
||||||
|
if (lock_start_flag)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&lock_start_mutex);
|
||||||
|
pthread_mutex_unlock(&lock_start_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_cond_init(&lwait.cond, NULL);
|
||||||
|
pthread_mutex_init(&lwait.mutex, NULL);
|
||||||
|
pthread_mutex_lock(&lwait.mutex);
|
||||||
|
|
||||||
|
/* This needs to be converted from DLM/LVM2 value for GULM */
|
||||||
|
if (flags == LCK_NONBLOCK) flags = lg_lock_flag_Try;
|
||||||
|
|
||||||
|
hash_insert(lock_hash, resource, &lwait);
|
||||||
|
DEBUGLOG("lock_resource '%s', flags=%d, mode=%d\n", resource, flags, mode);
|
||||||
|
|
||||||
|
status = lg_lock_state_req(gulm_if, resource, strlen(resource)+1,
|
||||||
|
0, 0, 0,
|
||||||
|
mode, flags, NULL, 0);
|
||||||
|
if (status)
|
||||||
|
{
|
||||||
|
DEBUGLOG("lg_lock_state returned %d\n", status);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait for it to complete */
|
||||||
|
pthread_cond_wait(&lwait.cond, &lwait.mutex);
|
||||||
|
pthread_mutex_unlock(&lwait.mutex);
|
||||||
|
|
||||||
|
hash_remove(lock_hash, resource);
|
||||||
|
DEBUGLOG("lock-resource returning %d\n", lwait.status);
|
||||||
|
|
||||||
|
return gulm_to_errno(lwait.status);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int _unlock_resource(char *resource, int lockid)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
struct lock_wait lwait;
|
||||||
|
|
||||||
|
pthread_cond_init(&lwait.cond, NULL);
|
||||||
|
pthread_mutex_init(&lwait.mutex, NULL);
|
||||||
|
pthread_mutex_lock(&lwait.mutex);
|
||||||
|
|
||||||
|
hash_insert(lock_hash, resource, &lwait);
|
||||||
|
|
||||||
|
DEBUGLOG("unlock_resource %s\n", resource);
|
||||||
|
status = lg_lock_state_req(gulm_if, resource, strlen(resource)+1,
|
||||||
|
0, 0, 0,
|
||||||
|
lg_lock_state_Unlock, 0, NULL, 0);
|
||||||
|
|
||||||
|
if (status)
|
||||||
|
{
|
||||||
|
DEBUGLOG("lg_lock_state(unlock) returned %d\n", status);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* When we are shutting down, don't wait for unlocks
|
||||||
|
to be acknowledged, just do it. */
|
||||||
|
if (in_shutdown)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
/* Wait for it to complete */
|
||||||
|
|
||||||
|
pthread_cond_wait(&lwait.cond, &lwait.mutex);
|
||||||
|
pthread_mutex_unlock(&lwait.mutex);
|
||||||
|
|
||||||
|
hash_remove(lock_hash, resource);
|
||||||
|
|
||||||
|
return gulm_to_errno(lwait.status);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* These two locking functions MUST be called in a seperate thread from
|
||||||
|
the clvmd main loop because they expect to be woken up by it.
|
||||||
|
|
||||||
|
These are abstractions around the real locking functions (above)
|
||||||
|
as we need to emulate the DLM's EX/PW/CW interaction with GULM using
|
||||||
|
two locks.
|
||||||
|
To aid unlocking, we store the lock mode in the lockid (as GULM
|
||||||
|
doesn't use this).
|
||||||
|
*/
|
||||||
|
static int _sync_lock(const char *resource, int mode, int flags, int *lockid)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
char lock1[strlen(resource)+3];
|
||||||
|
char lock2[strlen(resource)+3];
|
||||||
|
|
||||||
|
snprintf(lock1, sizeof(lock1), "%s-1", resource);
|
||||||
|
snprintf(lock2, sizeof(lock2), "%s-2", resource);
|
||||||
|
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case LCK_EXCL:
|
||||||
|
status = _lock_resource(lock1, lg_lock_state_Exclusive, flags, lockid);
|
||||||
|
if (status)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/* If we can't get this lock too then bail out */
|
||||||
|
status = _lock_resource(lock2, lg_lock_state_Exclusive, LCK_NONBLOCK, lockid);
|
||||||
|
if (status == lg_err_TryFailed)
|
||||||
|
{
|
||||||
|
_unlock_resource(lock1, *lockid);
|
||||||
|
status = -1;
|
||||||
|
errno = EAGAIN;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LCK_READ:
|
||||||
|
status = _lock_resource(lock1, lg_lock_state_Shared, flags, lockid);
|
||||||
|
if (status)
|
||||||
|
goto out;
|
||||||
|
status = _unlock_resource(lock2, *lockid);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LCK_WRITE:
|
||||||
|
status = _lock_resource(lock2, lg_lock_state_Exclusive, flags, lockid);
|
||||||
|
if (status)
|
||||||
|
goto out;
|
||||||
|
status = _unlock_resource(lock1, *lockid);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
status = -1;
|
||||||
|
errno = EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
*lockid = mode;
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _sync_unlock(const char *resource, int lockid)
|
||||||
|
{
|
||||||
|
int status = 0;
|
||||||
|
char lock1[strlen(resource)+3];
|
||||||
|
char lock2[strlen(resource)+3];
|
||||||
|
|
||||||
|
snprintf(lock1, sizeof(lock1), "%s-1", resource);
|
||||||
|
snprintf(lock2, sizeof(lock2), "%s-2", resource);
|
||||||
|
|
||||||
|
/* The held lock mode is in the lock id */
|
||||||
|
assert(lockid == LCK_EXCL ||
|
||||||
|
lockid == LCK_READ ||
|
||||||
|
lockid == LCK_WRITE);
|
||||||
|
|
||||||
|
status = _unlock_resource(lock1, lockid);
|
||||||
|
if (!status)
|
||||||
|
status = _unlock_resource(lock2, lockid);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _is_quorate()
|
||||||
|
{
|
||||||
|
return gulm_quorate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get all the cluster node names & IPs from CCS and
|
||||||
|
add them to our node list so we know who to talk to.
|
||||||
|
Called when we start up and if we get sent SIGHUP.
|
||||||
|
*/
|
||||||
|
static int get_all_cluster_nodes()
|
||||||
|
{
|
||||||
|
int ctree;
|
||||||
|
char *nodename;
|
||||||
|
int error;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Open the config file */
|
||||||
|
ctree = ccs_force_connect(NULL, 1);
|
||||||
|
if (ctree < 0)
|
||||||
|
{
|
||||||
|
log_error("Error connecting to CCS");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=1;;i++)
|
||||||
|
{
|
||||||
|
char nodekey[256];
|
||||||
|
char nodeip[GULM_MAX_CSID_LEN];
|
||||||
|
int clvmflag = 1;
|
||||||
|
char *clvmflagstr;
|
||||||
|
char key[256];
|
||||||
|
|
||||||
|
sprintf(nodekey, "//cluster/clusternodes/clusternode[%d]/@name", i);
|
||||||
|
error = ccs_get(ctree, nodekey, &nodename);
|
||||||
|
if (error)
|
||||||
|
break;
|
||||||
|
|
||||||
|
sprintf(key, "//cluster/clusternodes/clusternode[@name=\"%s\"]/clvm", nodename);
|
||||||
|
if (!ccs_get(ctree, key, &clvmflagstr))
|
||||||
|
{
|
||||||
|
clvmflag = atoi(clvmflagstr);
|
||||||
|
free(clvmflagstr);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUGLOG("Got node %s from ccs(clvmflag = %d)\n", nodename, clvmflag);
|
||||||
|
if ((get_ip_address(nodename, nodeip) == 0) && clvmflag)
|
||||||
|
{
|
||||||
|
struct node_info *ninfo;
|
||||||
|
|
||||||
|
/* If it's not in the list, then add it */
|
||||||
|
ninfo = hash_lookup_binary(node_hash, nodeip, GULM_MAX_CSID_LEN);
|
||||||
|
if (!ninfo)
|
||||||
|
{
|
||||||
|
ninfo = malloc(sizeof(struct node_info));
|
||||||
|
if (!ninfo)
|
||||||
|
{
|
||||||
|
syslog(LOG_ERR, "Cannot alloc memory for node info\n");
|
||||||
|
ccs_disconnect(ctree);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
strcpy(ninfo->name, nodename);
|
||||||
|
|
||||||
|
ninfo->state = NODE_DOWN;
|
||||||
|
hash_insert_binary(node_hash, nodeip, GULM_MAX_CSID_LEN, ninfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DEBUGLOG("node %s has clvm disabled\n", nodename);
|
||||||
|
}
|
||||||
|
free(nodename);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Finished with config file */
|
||||||
|
ccs_disconnect(ctree);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _get_main_cluster_fd(void)
|
||||||
|
{
|
||||||
|
return get_main_gulm_cluster_fd();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _cluster_fd_callback(struct local_client *fd, char *buf, int len, char *csid, struct local_client **new_client)
|
||||||
|
{
|
||||||
|
return cluster_fd_gulm_callback(fd, buf, len, csid, new_client);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _cluster_send_message(void *buf, int msglen, char *csid, const char *errtext)
|
||||||
|
{
|
||||||
|
return gulm_cluster_send_message(buf, msglen, csid, errtext);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct cluster_ops _cluster_gulm_ops = {
|
||||||
|
.cluster_init_completed = NULL,
|
||||||
|
.cluster_send_message = _cluster_send_message,
|
||||||
|
.name_from_csid = gulm_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 = gulm_add_up_node,
|
||||||
|
.reread_config = _reread_config,
|
||||||
|
.cluster_closedown = _cluster_closedown,
|
||||||
|
.sync_lock = _sync_lock,
|
||||||
|
.sync_unlock = _sync_unlock,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cluster_ops *init_gulm_cluster(void)
|
||||||
|
{
|
||||||
|
if (!_init_cluster())
|
||||||
|
return &_cluster_gulm_ops;
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
12
daemons/clvmd/clvmd-gulm.h
Normal file
12
daemons/clvmd/clvmd-gulm.h
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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(char *node, char *addr);
|
||||||
|
extern void tcp_remove_client(char *csid);
|
||||||
|
extern int alloc_client(int fd, char *csid, struct local_client **new_client);
|
||||||
|
|
||||||
|
void gulm_add_up_node(char *csid);
|
||||||
|
int gulm_name_from_csid(char *csid, char *name);
|
||||||
1853
daemons/clvmd/clvmd.c
Normal file
1853
daemons/clvmd/clvmd.c
Normal file
File diff suppressed because it is too large
Load Diff
124
daemons/clvmd/clvmd.h
Normal file
124
daemons/clvmd/clvmd.h
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
|
||||||
|
* Copyright (C) 2004 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _CLVMD_H
|
||||||
|
#define _CLVMD_H
|
||||||
|
|
||||||
|
#define CLVMD_MAJOR_VERSION 0
|
||||||
|
#define CLVMD_MINOR_VERSION 2
|
||||||
|
#define CLVMD_PATCH_VERSION 1
|
||||||
|
|
||||||
|
/* Name of the cluster LVM admin lock */
|
||||||
|
#define ADMIN_LOCK_NAME "CLVMD_ADMIN"
|
||||||
|
|
||||||
|
/* Default time (in seconds) we will wait for all remote commands to execute
|
||||||
|
before declaring them dead */
|
||||||
|
#define DEFAULT_CMD_TIMEOUT 60
|
||||||
|
|
||||||
|
/* One of these for each reply we get from command execution on a node */
|
||||||
|
struct node_reply {
|
||||||
|
char node[MAX_CLUSTER_MEMBER_NAME_LEN];
|
||||||
|
char *replymsg;
|
||||||
|
int status;
|
||||||
|
struct node_reply *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These exist for the use of local sockets only when we are
|
||||||
|
* collecting responses from all cluster nodes
|
||||||
|
*/
|
||||||
|
struct localsock_bits {
|
||||||
|
struct node_reply *replies;
|
||||||
|
int num_replies;
|
||||||
|
int expected_replies;
|
||||||
|
time_t sent_time; /* So we can check for timeouts */
|
||||||
|
int in_progress; /* Only execute one cmd at a time per client */
|
||||||
|
int sent_out; /* Flag to indicate that a command was sent
|
||||||
|
to remote nodes */
|
||||||
|
void *private; /* Private area for command processor use */
|
||||||
|
void *cmd; /* Whole command as passed down local socket */
|
||||||
|
int cmd_len; /* Length of above */
|
||||||
|
int pipe; /* Pipe to send PRE completion status down */
|
||||||
|
int finished; /* Flag to tell subthread to exit */
|
||||||
|
int all_success; /* Set to 0 if any node (or the pre_command)
|
||||||
|
failed */
|
||||||
|
struct local_client *pipe_client;
|
||||||
|
pthread_t threadid;
|
||||||
|
enum { PRE_COMMAND, POST_COMMAND, QUIT } state;
|
||||||
|
pthread_mutex_t mutex; /* Main thread and worker synchronisation */
|
||||||
|
pthread_cond_t cond;
|
||||||
|
|
||||||
|
pthread_mutex_t reply_mutex; /* Protect reply structure */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Entries for PIPE clients */
|
||||||
|
struct pipe_bits {
|
||||||
|
struct local_client *client; /* Actual (localsock) client */
|
||||||
|
pthread_t threadid; /* Our own copy of the thread id */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Entries for Network socket clients */
|
||||||
|
struct netsock_bits {
|
||||||
|
void *private;
|
||||||
|
int flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef int (*fd_callback_t) (struct local_client * fd, char *buf, int len,
|
||||||
|
char *csid, struct local_client ** new_client);
|
||||||
|
|
||||||
|
/* One of these for each fd we are listening on */
|
||||||
|
struct local_client {
|
||||||
|
int fd;
|
||||||
|
enum { CLUSTER_MAIN_SOCK, CLUSTER_DATA_SOCK, LOCAL_RENDEZVOUS,
|
||||||
|
LOCAL_SOCK, THREAD_PIPE, CLUSTER_INTERNAL } type;
|
||||||
|
struct local_client *next;
|
||||||
|
unsigned short xid;
|
||||||
|
fd_callback_t callback;
|
||||||
|
uint8_t removeme;
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct localsock_bits localsock;
|
||||||
|
struct pipe_bits pipe;
|
||||||
|
struct netsock_bits net;
|
||||||
|
} bits;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
#define DEBUGLOG(fmt, args...) {time_t P; time(&P); fprintf(stderr, "CLVMD[%x]: %.15s ", (int)pthread_self(), ctime(&P)+4 ); fprintf(stderr, fmt, ## args);}
|
||||||
|
#else
|
||||||
|
#define DEBUGLOG(fmt, args...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef max
|
||||||
|
#define max(a,b) ((a)>(b)?(a):(b))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The real command processor is in clvmd-command.c */
|
||||||
|
extern int do_command(struct local_client *client, struct clvm_header *msg,
|
||||||
|
int msglen, char **buf, int buflen, int *retlen);
|
||||||
|
|
||||||
|
/* Pre and post command routines are called only on the local node */
|
||||||
|
extern int do_pre_command(struct local_client *client);
|
||||||
|
extern int do_post_command(struct local_client *client);
|
||||||
|
extern void cmd_client_cleanup(struct local_client *client);
|
||||||
|
extern int add_client(struct local_client *new_client);
|
||||||
|
|
||||||
|
extern void clvmd_cluster_init_completed(void);
|
||||||
|
extern void process_message(struct local_client *client, char *buf, int len, char *csid);
|
||||||
|
|
||||||
|
int sync_lock(const char *resource, int mode, int flags, int *lockid);
|
||||||
|
int sync_unlock(const char *resource, int lockid);
|
||||||
|
|
||||||
|
#endif
|
||||||
226
daemons/clvmd/cnxman-socket.h
Normal file
226
daemons/clvmd/cnxman-socket.h
Normal file
@@ -0,0 +1,226 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
*******************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
|
||||||
|
** Copyright (C) 2004 Red Hat, Inc. All rights reserved.
|
||||||
|
**
|
||||||
|
** This copyrighted material is made available to anyone wishing to use,
|
||||||
|
** modify, copy, or redistribute it subject to the terms and conditions
|
||||||
|
** of the GNU General Public License v.2.
|
||||||
|
**
|
||||||
|
*******************************************************************************
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/* CMAN socket interface header,
|
||||||
|
may be include by user or kernel code */
|
||||||
|
|
||||||
|
#ifndef __CNXMAN_SOCKET_H
|
||||||
|
#define __CNXMAN_SOCKET_H
|
||||||
|
|
||||||
|
/* A currently unused number. TIPC also uses this number and you're unlikely
|
||||||
|
to be using both.
|
||||||
|
*/
|
||||||
|
#define AF_CLUSTER 30
|
||||||
|
#define PF_CLUSTER AF_CLUSTER
|
||||||
|
|
||||||
|
/* Protocol(socket) types */
|
||||||
|
#define CLPROTO_MASTER 2
|
||||||
|
#define CLPROTO_CLIENT 3
|
||||||
|
|
||||||
|
/* ioctls -- should register these properly */
|
||||||
|
#define SIOCCLUSTER_NOTIFY _IOW('x', 0x01, int)
|
||||||
|
#define SIOCCLUSTER_REMOVENOTIFY _IO( 'x', 0x02)
|
||||||
|
#define SIOCCLUSTER_GETMEMBERS _IOR('x', 0x03, struct cl_cluster_nodelist)
|
||||||
|
#define SIOCCLUSTER_SETEXPECTED_VOTES _IOW('x', 0x04, int)
|
||||||
|
#define SIOCCLUSTER_ISQUORATE _IO( 'x', 0x05)
|
||||||
|
#define SIOCCLUSTER_ISLISTENING _IOW('x', 0x06, struct cl_listen_request)
|
||||||
|
#define SIOCCLUSTER_GETALLMEMBERS _IOR('x', 0x07, struct cl_cluster_nodelist)
|
||||||
|
#define SIOCCLUSTER_SET_VOTES _IOW('x', 0x08, int)
|
||||||
|
#define SIOCCLUSTER_GET_VERSION _IOR('x', 0x09, struct cl_version)
|
||||||
|
#define SIOCCLUSTER_SET_VERSION _IOW('x', 0x0a, struct cl_version)
|
||||||
|
#define SIOCCLUSTER_ISACTIVE _IO( 'x', 0x0b)
|
||||||
|
#define SIOCCLUSTER_KILLNODE _IOW('x', 0x0c, int)
|
||||||
|
#define SIOCCLUSTER_GET_JOINCOUNT _IO( 'x', 0x0d)
|
||||||
|
#define SIOCCLUSTER_SERVICE_REGISTER _IOW('x', 0x0e, char)
|
||||||
|
#define SIOCCLUSTER_SERVICE_UNREGISTER _IO('x', 0x0f)
|
||||||
|
#define SIOCCLUSTER_SERVICE_JOIN _IO( 'x', 0x10)
|
||||||
|
#define SIOCCLUSTER_SERVICE_LEAVE _IO( 'x', 0x20)
|
||||||
|
#define SIOCCLUSTER_SERVICE_SETSIGNAL _IOW('x', 0x30, int)
|
||||||
|
#define SIOCCLUSTER_SERVICE_STARTDONE _IOW('x', 0x40, unsigned int)
|
||||||
|
#define SIOCCLUSTER_SERVICE_GETEVENT _IOR('x', 0x50, struct cl_service_event)
|
||||||
|
#define SIOCCLUSTER_SERVICE_GETMEMBERS _IOR('x', 0x60, struct cl_cluster_nodelist)
|
||||||
|
#define SIOCCLUSTER_SERVICE_GLOBALID _IOR('x', 0x70, uint32_t)
|
||||||
|
#define SIOCCLUSTER_SERVICE_SETLEVEL _IOR('x', 0x80, int)
|
||||||
|
#define SIOCCLUSTER_GETNODE _IOWR('x', 0x90, struct cl_cluster_node)
|
||||||
|
#define SIOCCLUSTER_BARRIER _IOW('x', 0x0a0, struct cl_barrier_info)
|
||||||
|
|
||||||
|
/* These were setsockopts */
|
||||||
|
#define SIOCCLUSTER_PASS_SOCKET _IOW('x', 0x0b0, struct cl_passed_sock)
|
||||||
|
#define SIOCCLUSTER_SET_NODENAME _IOW('x', 0x0b1, char *)
|
||||||
|
#define SIOCCLUSTER_SET_NODEID _IOW('x', 0x0b2, int)
|
||||||
|
#define SIOCCLUSTER_JOIN_CLUSTER _IOW('x', 0x0b3, struct cl_join_cluster_info)
|
||||||
|
#define SIOCCLUSTER_LEAVE_CLUSTER _IOW('x', 0x0b4, int)
|
||||||
|
|
||||||
|
|
||||||
|
/* Maximum size of a cluster message */
|
||||||
|
#define CMAN_MAX_CLUSTER_MESSAGE 1500
|
||||||
|
#define CMAN_MAX_CLUSTER_MEMBER_NAME_LEN 255
|
||||||
|
#define MAX_BARRIER_NAME_LEN 33
|
||||||
|
#define MAX_SA_ADDR_LEN 12
|
||||||
|
#define MAX_CLUSTER_NAME_LEN 16
|
||||||
|
|
||||||
|
/* Well-known cluster port numbers */
|
||||||
|
#define CLUSTER_PORT_MEMBERSHIP 1 /* Mustn't block during cluster
|
||||||
|
* transitions! */
|
||||||
|
#define CLUSTER_PORT_SERVICES 2
|
||||||
|
#define CLUSTER_PORT_SYSMAN 10 /* Remote execution daemon */
|
||||||
|
#define CLUSTER_PORT_CLVMD 11 /* Cluster LVM daemon */
|
||||||
|
#define CLUSTER_PORT_SLM 12 /* LVM SLM (simple lock manager) */
|
||||||
|
|
||||||
|
/* Port numbers above this will be blocked when the cluster is inquorate or in
|
||||||
|
* transition */
|
||||||
|
#define HIGH_PROTECTED_PORT 9
|
||||||
|
|
||||||
|
/* Reasons for leaving the cluster */
|
||||||
|
#define CLUSTER_LEAVEFLAG_DOWN 0 /* Normal shutdown */
|
||||||
|
#define CLUSTER_LEAVEFLAG_KILLED 1
|
||||||
|
#define CLUSTER_LEAVEFLAG_PANIC 2
|
||||||
|
#define CLUSTER_LEAVEFLAG_REMOVED 3 /* This one can reduce quorum */
|
||||||
|
#define CLUSTER_LEAVEFLAG_REJECTED 4 /* Not allowed into the cluster in the
|
||||||
|
* first place */
|
||||||
|
#define CLUSTER_LEAVEFLAG_INCONSISTENT 5 /* Our view of the cluster is
|
||||||
|
* in a minority */
|
||||||
|
#define CLUSTER_LEAVEFLAG_DEAD 6 /* Discovered to be dead */
|
||||||
|
#define CLUSTER_LEAVEFLAG_FORCE 0x10 /* Forced by command-line */
|
||||||
|
|
||||||
|
/* OOB messages sent to a local socket */
|
||||||
|
#define CLUSTER_OOB_MSG_PORTCLOSED 1
|
||||||
|
#define CLUSTER_OOB_MSG_STATECHANGE 2
|
||||||
|
#define CLUSTER_OOB_MSG_SERVICEEVENT 3
|
||||||
|
|
||||||
|
/* Sendmsg flags, these are above the normal sendmsg flags so they don't
|
||||||
|
* interfere */
|
||||||
|
#define MSG_NOACK 0x010000 /* Don't need an ACK for this message */
|
||||||
|
#define MSG_QUEUE 0x020000 /* Queue the message for sending later */
|
||||||
|
#define MSG_MULTICAST 0x080000 /* Message was sent to all nodes in the cluster
|
||||||
|
*/
|
||||||
|
#define MSG_ALLINT 0x100000 /* Send out of all interfaces */
|
||||||
|
#define MSG_REPLYEXP 0x200000 /* Reply is expected */
|
||||||
|
|
||||||
|
typedef enum { NODESTATE_REMOTEMEMBER, NODESTATE_JOINING, NODESTATE_MEMBER,
|
||||||
|
NODESTATE_DEAD } nodestate_t;
|
||||||
|
|
||||||
|
|
||||||
|
struct sockaddr_cl {
|
||||||
|
unsigned short scl_family;
|
||||||
|
unsigned char scl_flags;
|
||||||
|
unsigned char scl_port;
|
||||||
|
int scl_nodeid;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is how we pass the multicast & receive sockets into kernel space.
|
||||||
|
*/
|
||||||
|
struct cl_passed_sock {
|
||||||
|
int fd; /* FD of master socket to do multicast on */
|
||||||
|
int number; /* Socket number, to match up recvonly & bcast
|
||||||
|
* sockets */
|
||||||
|
int multicast; /* Is it multicast or receive ? */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Cluster configuration info passed when we join the cluster */
|
||||||
|
struct cl_join_cluster_info {
|
||||||
|
unsigned char votes;
|
||||||
|
unsigned int expected_votes;
|
||||||
|
unsigned int two_node;
|
||||||
|
unsigned int config_version;
|
||||||
|
|
||||||
|
char cluster_name[17];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* This is the structure, per node, returned from the membership ioctl */
|
||||||
|
struct cl_cluster_node {
|
||||||
|
unsigned int size;
|
||||||
|
unsigned int node_id;
|
||||||
|
unsigned int us;
|
||||||
|
unsigned int leave_reason;
|
||||||
|
unsigned int incarnation;
|
||||||
|
nodestate_t state;
|
||||||
|
char name[CMAN_MAX_CLUSTER_MEMBER_NAME_LEN];
|
||||||
|
unsigned char votes;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The struct passed to the membership ioctls */
|
||||||
|
struct cl_cluster_nodelist {
|
||||||
|
uint32_t max_members;
|
||||||
|
struct cl_cluster_node *nodes;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Structure passed to SIOCCLUSTER_ISLISTENING */
|
||||||
|
struct cl_listen_request {
|
||||||
|
unsigned char port;
|
||||||
|
int nodeid;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* A Cluster PORTCLOSED message - received by a local user as an OOB message */
|
||||||
|
struct cl_portclosed_oob {
|
||||||
|
unsigned char cmd; /* CLUSTER_OOB_MSG_PORTCLOSED */
|
||||||
|
unsigned char port;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Get all version numbers or set the config version */
|
||||||
|
struct cl_version {
|
||||||
|
unsigned int major;
|
||||||
|
unsigned int minor;
|
||||||
|
unsigned int patch;
|
||||||
|
unsigned int config;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* structure passed to barrier ioctls */
|
||||||
|
struct cl_barrier_info {
|
||||||
|
char cmd;
|
||||||
|
char name[MAX_BARRIER_NAME_LEN];
|
||||||
|
unsigned int flags;
|
||||||
|
unsigned long arg;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum { SERVICE_EVENT_STOP, SERVICE_EVENT_START, SERVICE_EVENT_FINISH,
|
||||||
|
SERVICE_EVENT_LEAVEDONE } service_event_t;
|
||||||
|
|
||||||
|
typedef enum { SERVICE_START_FAILED, SERVICE_START_JOIN, SERVICE_START_LEAVE }
|
||||||
|
service_start_t;
|
||||||
|
|
||||||
|
struct cl_service_event {
|
||||||
|
service_event_t type;
|
||||||
|
service_start_t start_type;
|
||||||
|
unsigned int event_id;
|
||||||
|
unsigned int last_stop;
|
||||||
|
unsigned int last_start;
|
||||||
|
unsigned int last_finish;
|
||||||
|
unsigned int node_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Commands to the barrier ioctl */
|
||||||
|
#define BARRIER_IOCTL_REGISTER 1
|
||||||
|
#define BARRIER_IOCTL_CHANGE 2
|
||||||
|
#define BARRIER_IOCTL_DELETE 3
|
||||||
|
#define BARRIER_IOCTL_WAIT 4
|
||||||
|
|
||||||
|
/* Attributes of a barrier - bitmask */
|
||||||
|
#define BARRIER_ATTR_AUTODELETE 1
|
||||||
|
#define BARRIER_ATTR_MULTISTEP 2
|
||||||
|
#define BARRIER_ATTR_MANUAL 4
|
||||||
|
#define BARRIER_ATTR_ENABLED 8
|
||||||
|
#define BARRIER_ATTR_CALLBACK 16
|
||||||
|
|
||||||
|
/* Attribute setting commands */
|
||||||
|
#define BARRIER_SETATTR_AUTODELETE 1
|
||||||
|
#define BARRIER_SETATTR_MULTISTEP 2
|
||||||
|
#define BARRIER_SETATTR_ENABLED 3
|
||||||
|
#define BARRIER_SETATTR_NODES 4
|
||||||
|
#define BARRIER_SETATTR_CALLBACK 5
|
||||||
|
#define BARRIER_SETATTR_TIMEOUT 6
|
||||||
|
|
||||||
|
#endif
|
||||||
532
daemons/clvmd/lvm-functions.c
Normal file
532
daemons/clvmd/lvm-functions.c
Normal file
@@ -0,0 +1,532 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
|
||||||
|
* Copyright (C) 2004 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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 <stdint.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "libdlm.h"
|
||||||
|
#include "clvm.h"
|
||||||
|
#include "clvmd-comms.h"
|
||||||
|
#include "clvmd.h"
|
||||||
|
#include "lvm-functions.h"
|
||||||
|
|
||||||
|
/* LVM2 headers */
|
||||||
|
#include "toolcontext.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "activate.h"
|
||||||
|
#include "hash.h"
|
||||||
|
#include "locking.h"
|
||||||
|
|
||||||
|
static struct cmd_context *cmd = NULL;
|
||||||
|
static struct hash_table *lv_hash = NULL;
|
||||||
|
static pthread_mutex_t lv_hash_lock;
|
||||||
|
|
||||||
|
struct lv_info {
|
||||||
|
int lock_id;
|
||||||
|
int lock_mode;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Return the mode a lock is currently held at (or -1 if not held) */
|
||||||
|
static int get_current_lock(char *resource)
|
||||||
|
{
|
||||||
|
struct lv_info *lvi;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&lv_hash_lock);
|
||||||
|
lvi = hash_lookup(lv_hash, resource);
|
||||||
|
pthread_mutex_unlock(&lv_hash_lock);
|
||||||
|
if (lvi) {
|
||||||
|
return lvi->lock_mode;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Called at shutdown to tidy the lockspace */
|
||||||
|
void unlock_all()
|
||||||
|
{
|
||||||
|
struct hash_node *v;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&lv_hash_lock);
|
||||||
|
hash_iterate(v, lv_hash) {
|
||||||
|
struct lv_info *lvi = hash_get_data(lv_hash, v);
|
||||||
|
|
||||||
|
sync_unlock(hash_get_key(lv_hash, v), lvi->lock_id);
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&lv_hash_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Gets a real lock and keeps the info in the hash table */
|
||||||
|
int hold_lock(char *resource, int mode, int flags)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
int saved_errno;
|
||||||
|
struct lv_info *lvi;
|
||||||
|
|
||||||
|
flags &= LKF_NOQUEUE; /* Only LKF_NOQUEUE is valid here */
|
||||||
|
|
||||||
|
pthread_mutex_lock(&lv_hash_lock);
|
||||||
|
lvi = hash_lookup(lv_hash, resource);
|
||||||
|
pthread_mutex_unlock(&lv_hash_lock);
|
||||||
|
if (lvi) {
|
||||||
|
/* Already exists - convert it */
|
||||||
|
status =
|
||||||
|
sync_lock(resource, mode, LKF_CONVERT | flags,
|
||||||
|
&lvi->lock_id);
|
||||||
|
saved_errno = errno;
|
||||||
|
if (!status)
|
||||||
|
lvi->lock_mode = mode;
|
||||||
|
|
||||||
|
if (status) {
|
||||||
|
DEBUGLOG("hold_lock. convert to %d failed: %s\n", mode,
|
||||||
|
strerror(errno));
|
||||||
|
}
|
||||||
|
errno = saved_errno;
|
||||||
|
} else {
|
||||||
|
lvi = malloc(sizeof(struct lv_info));
|
||||||
|
if (!lvi)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
lvi->lock_mode = mode;
|
||||||
|
status = sync_lock(resource, mode, flags, &lvi->lock_id);
|
||||||
|
saved_errno = errno;
|
||||||
|
if (status) {
|
||||||
|
free(lvi);
|
||||||
|
DEBUGLOG("hold_lock. lock at %d failed: %s\n", mode,
|
||||||
|
strerror(errno));
|
||||||
|
} else {
|
||||||
|
pthread_mutex_lock(&lv_hash_lock);
|
||||||
|
hash_insert(lv_hash, resource, lvi);
|
||||||
|
pthread_mutex_unlock(&lv_hash_lock);
|
||||||
|
}
|
||||||
|
errno = saved_errno;
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unlock and remove it from the hash table */
|
||||||
|
int hold_unlock(char *resource)
|
||||||
|
{
|
||||||
|
struct lv_info *lvi;
|
||||||
|
int status;
|
||||||
|
int saved_errno;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&lv_hash_lock);
|
||||||
|
lvi = hash_lookup(lv_hash, resource);
|
||||||
|
pthread_mutex_unlock(&lv_hash_lock);
|
||||||
|
if (!lvi) {
|
||||||
|
DEBUGLOG("hold_unlock, lock not already held\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = sync_unlock(resource, lvi->lock_id);
|
||||||
|
saved_errno = errno;
|
||||||
|
if (!status) {
|
||||||
|
pthread_mutex_lock(&lv_hash_lock);
|
||||||
|
hash_remove(lv_hash, resource);
|
||||||
|
pthread_mutex_unlock(&lv_hash_lock);
|
||||||
|
free(lvi);
|
||||||
|
} else {
|
||||||
|
DEBUGLOG("hold_unlock. unlock failed(%d): %s\n", status,
|
||||||
|
strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
errno = saved_errno;
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Watch the return codes here.
|
||||||
|
liblvm API functions return 1(true) for success, 0(false) for failure and don't set errno.
|
||||||
|
libdlm API functions return 0 for success, -1 for failure and do set errno.
|
||||||
|
These functions here return 0 for success or >0 for failure (where the retcode is errno)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Activate LV exclusive or non-exclusive */
|
||||||
|
static int do_activate_lv(char *resource, int mode)
|
||||||
|
{
|
||||||
|
int oldmode;
|
||||||
|
int status;
|
||||||
|
int activate_lv;
|
||||||
|
struct lvinfo lvi;
|
||||||
|
|
||||||
|
/* Is it already open ? */
|
||||||
|
oldmode = get_current_lock(resource);
|
||||||
|
if (oldmode == mode) {
|
||||||
|
return 0; /* Nothing to do */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Does the config file want us to activate this LV ? */
|
||||||
|
if (!lv_activation_filter(cmd, resource, &activate_lv))
|
||||||
|
return EIO;
|
||||||
|
|
||||||
|
if (!activate_lv)
|
||||||
|
return 0; /* Success, we did nothing! */
|
||||||
|
|
||||||
|
/* Do we need to activate exclusively? */
|
||||||
|
if (activate_lv == 2)
|
||||||
|
mode = LKM_EXMODE;
|
||||||
|
|
||||||
|
/* OK, try to get the lock */
|
||||||
|
status = hold_lock(resource, mode, LKF_NOQUEUE);
|
||||||
|
if (status)
|
||||||
|
return errno;
|
||||||
|
|
||||||
|
/* If it's suspended then resume it */
|
||||||
|
if (!lv_info_by_lvid(cmd, resource, &lvi, 0))
|
||||||
|
return EIO;
|
||||||
|
|
||||||
|
if (lvi.suspended)
|
||||||
|
if (!lv_resume(cmd, resource))
|
||||||
|
return EIO;
|
||||||
|
|
||||||
|
/* Now activate it */
|
||||||
|
if (!lv_activate(cmd, resource))
|
||||||
|
return EIO;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Resume the LV if it was active */
|
||||||
|
static int do_resume_lv(char *resource)
|
||||||
|
{
|
||||||
|
int oldmode;
|
||||||
|
|
||||||
|
/* Is it open ? */
|
||||||
|
oldmode = get_current_lock(resource);
|
||||||
|
if (oldmode == -1) {
|
||||||
|
DEBUGLOG("do_deactivate_lock, lock not already held\n");
|
||||||
|
return 0; /* We don't need to do anything */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lv_resume_if_active(cmd, resource))
|
||||||
|
return EIO;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Suspend the device if active */
|
||||||
|
static int do_suspend_lv(char *resource)
|
||||||
|
{
|
||||||
|
int oldmode;
|
||||||
|
struct lvinfo lvi;
|
||||||
|
|
||||||
|
/* Is it open ? */
|
||||||
|
oldmode = get_current_lock(resource);
|
||||||
|
if (oldmode == -1) {
|
||||||
|
DEBUGLOG("do_suspend_lv, lock held at %d\n", oldmode);
|
||||||
|
return 0; /* Not active, so it's OK */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Only suspend it if it exists */
|
||||||
|
if (!lv_info_by_lvid(cmd, resource, &lvi, 0))
|
||||||
|
return EIO;
|
||||||
|
|
||||||
|
if (lvi.exists) {
|
||||||
|
if (!lv_suspend_if_active(cmd, resource)) {
|
||||||
|
return EIO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int do_deactivate_lv(char *resource)
|
||||||
|
{
|
||||||
|
int oldmode;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
/* Is it open ? */
|
||||||
|
oldmode = get_current_lock(resource);
|
||||||
|
if (oldmode == -1) {
|
||||||
|
DEBUGLOG("do_deactivate_lock, lock not already held\n");
|
||||||
|
return 0; /* We don't need to do anything */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lv_deactivate(cmd, resource))
|
||||||
|
return EIO;
|
||||||
|
|
||||||
|
status = hold_unlock(resource);
|
||||||
|
if (status)
|
||||||
|
return errno;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is the LOCK_LV part that happens on all nodes in the cluster -
|
||||||
|
it is responsible for the interaction with device-mapper and LVM */
|
||||||
|
int do_lock_lv(unsigned char command, unsigned char lock_flags, char *resource)
|
||||||
|
{
|
||||||
|
int status = 0;
|
||||||
|
|
||||||
|
DEBUGLOG("do_lock_lv: resource '%s', cmd = 0x%x, flags = %d\n",
|
||||||
|
resource, command, lock_flags);
|
||||||
|
|
||||||
|
if (!cmd->config_valid || config_files_changed(cmd)) {
|
||||||
|
/* Reinitialise various settings inc. logging, filters */
|
||||||
|
if (!refresh_toolcontext(cmd)) {
|
||||||
|
log_error("Updated config file invalid. Aborting.");
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (command) {
|
||||||
|
case LCK_LV_EXCLUSIVE:
|
||||||
|
status = do_activate_lv(resource, LKM_EXMODE);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LCK_LV_SUSPEND:
|
||||||
|
status = do_suspend_lv(resource);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LCK_UNLOCK:
|
||||||
|
case LCK_LV_RESUME: /* if active */
|
||||||
|
status = do_resume_lv(resource);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LCK_LV_ACTIVATE:
|
||||||
|
status = do_activate_lv(resource, LKM_CRMODE);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LCK_LV_DEACTIVATE:
|
||||||
|
status = do_deactivate_lv(resource);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
DEBUGLOG("Invalid LV command 0x%x\n", command);
|
||||||
|
status = EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* clean the pool for another command */
|
||||||
|
pool_empty(cmd->mem);
|
||||||
|
|
||||||
|
DEBUGLOG("Command return is %d\n", status);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Functions to do on the local node only BEFORE the cluster-wide stuff above happens */
|
||||||
|
int pre_lock_lv(unsigned char command, unsigned char lock_flags, char *resource)
|
||||||
|
{
|
||||||
|
/* Nearly all the stuff happens cluster-wide. Apart from SUSPEND. Here we get the
|
||||||
|
lock out on this node (because we are the node modifying the metadata)
|
||||||
|
before suspending cluster-wide.
|
||||||
|
*/
|
||||||
|
if (command == LCK_LV_SUSPEND) {
|
||||||
|
DEBUGLOG("pre_lock_lv: resource '%s', cmd = 0x%x, flags = %d\n",
|
||||||
|
resource, command, lock_flags);
|
||||||
|
|
||||||
|
if (hold_lock(resource, LKM_PWMODE, LKF_NOQUEUE))
|
||||||
|
return errno;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Functions to do on the local node only AFTER the cluster-wide stuff above happens */
|
||||||
|
int post_lock_lv(unsigned char command, unsigned char lock_flags,
|
||||||
|
char *resource)
|
||||||
|
{
|
||||||
|
/* Opposite of above, done on resume after a metadata update */
|
||||||
|
if (command == LCK_LV_RESUME) {
|
||||||
|
int oldmode;
|
||||||
|
|
||||||
|
DEBUGLOG
|
||||||
|
("post_lock_lv: resource '%s', cmd = 0x%x, flags = %d\n",
|
||||||
|
resource, command, lock_flags);
|
||||||
|
|
||||||
|
/* If the lock state is PW then restore it to what it was */
|
||||||
|
oldmode = get_current_lock(resource);
|
||||||
|
if (oldmode == LKM_PWMODE) {
|
||||||
|
struct lvinfo lvi;
|
||||||
|
|
||||||
|
if (!lv_info_by_lvid(cmd, resource, &lvi, 0))
|
||||||
|
return EIO;
|
||||||
|
|
||||||
|
if (lvi.exists) {
|
||||||
|
if (hold_lock(resource, LKM_CRMODE, 0))
|
||||||
|
return errno;
|
||||||
|
} else {
|
||||||
|
if (hold_unlock(resource))
|
||||||
|
return errno;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if a VG is un use by LVM1 so we don't stomp on it */
|
||||||
|
int do_check_lvm1(char *vgname)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
|
||||||
|
status = check_lvm1_vg_inactive(cmd, vgname);
|
||||||
|
|
||||||
|
return status == 1 ? 0 : EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Only called at gulm startup. Drop any leftover VG or P_orphan locks
|
||||||
|
that might be hanging around if we died for any reason
|
||||||
|
*/
|
||||||
|
static void drop_vg_locks()
|
||||||
|
{
|
||||||
|
char vg[128];
|
||||||
|
char line[255];
|
||||||
|
FILE *vgs =
|
||||||
|
popen
|
||||||
|
("lvm pvs --nolocking --noheadings -o vg_name", "r");
|
||||||
|
|
||||||
|
sync_unlock("P_orphans", LCK_EXCL);
|
||||||
|
|
||||||
|
if (!vgs)
|
||||||
|
return;
|
||||||
|
|
||||||
|
while (fgets(line, sizeof(line), vgs)) {
|
||||||
|
char *vgend;
|
||||||
|
char *vgstart;
|
||||||
|
|
||||||
|
if (line[strlen(line)-1] == '\n')
|
||||||
|
line[strlen(line)-1] = '\0';
|
||||||
|
|
||||||
|
vgstart = line + strspn(line, " ");
|
||||||
|
vgend = vgstart + strcspn(vgstart, " ");
|
||||||
|
*vgend = '\0';
|
||||||
|
|
||||||
|
if (strncmp(vgstart, "WARNING:", 8) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
sprintf(vg, "V_%s", vgstart);
|
||||||
|
sync_unlock(vg, LCK_EXCL);
|
||||||
|
|
||||||
|
}
|
||||||
|
fclose(vgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ideally, clvmd should be started before any LVs are active
|
||||||
|
* but this may not be the case...
|
||||||
|
* I suppose this also comes in handy if clvmd crashes, not that it would!
|
||||||
|
*/
|
||||||
|
static void *get_initial_state()
|
||||||
|
{
|
||||||
|
char lv[64], vg[64], flags[25];
|
||||||
|
char uuid[65];
|
||||||
|
char line[255];
|
||||||
|
FILE *lvs =
|
||||||
|
popen
|
||||||
|
("lvm lvs --nolocking --noheadings -o vg_uuid,lv_uuid,lv_attr",
|
||||||
|
"r");
|
||||||
|
|
||||||
|
if (!lvs)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
while (fgets(line, sizeof(line), lvs)) {
|
||||||
|
if (sscanf(line, "%s %s %s\n", vg, lv, flags) == 3) {
|
||||||
|
|
||||||
|
/* States: s:suspended a:active S:dropped snapshot I:invalid snapshot */
|
||||||
|
if (strlen(vg) == 38 && /* is is a valid UUID ? */
|
||||||
|
(flags[4] == 'a' || flags[4] == 's')) { /* is it active or suspended? */
|
||||||
|
/* Convert hyphen-separated UUIDs into one */
|
||||||
|
memcpy(&uuid[0], &vg[0], 6);
|
||||||
|
memcpy(&uuid[6], &vg[7], 4);
|
||||||
|
memcpy(&uuid[10], &vg[12], 4);
|
||||||
|
memcpy(&uuid[14], &vg[17], 4);
|
||||||
|
memcpy(&uuid[18], &vg[22], 4);
|
||||||
|
memcpy(&uuid[22], &vg[27], 4);
|
||||||
|
memcpy(&uuid[26], &vg[32], 6);
|
||||||
|
memcpy(&uuid[32], &lv[0], 6);
|
||||||
|
memcpy(&uuid[38], &lv[7], 4);
|
||||||
|
memcpy(&uuid[42], &lv[12], 4);
|
||||||
|
memcpy(&uuid[46], &lv[17], 4);
|
||||||
|
memcpy(&uuid[50], &lv[22], 4);
|
||||||
|
memcpy(&uuid[54], &lv[27], 4);
|
||||||
|
memcpy(&uuid[58], &lv[32], 6);
|
||||||
|
uuid[64] = '\0';
|
||||||
|
|
||||||
|
DEBUGLOG("getting initial lock for %s\n", uuid);
|
||||||
|
hold_lock(uuid, LKM_CRMODE, LKF_NOQUEUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(lvs);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This checks some basic cluster-LVM configuration stuff */
|
||||||
|
static void check_config()
|
||||||
|
{
|
||||||
|
int locking_type;
|
||||||
|
|
||||||
|
locking_type = find_config_int(cmd->cft->root, "global/locking_type", 1);
|
||||||
|
|
||||||
|
if (locking_type == 3) /* compiled-in cluster support */
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (locking_type == 2) { /* External library, check name */
|
||||||
|
const char *libname;
|
||||||
|
|
||||||
|
libname = find_config_str(cmd->cft->root, "global/locking_library",
|
||||||
|
"");
|
||||||
|
if (strstr(libname, "liblvm2clusterlock.so"))
|
||||||
|
return;
|
||||||
|
|
||||||
|
log_error("Incorrect LVM locking library specified in lvm.conf, cluster operations may not work.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
log_error("locking_type not set correctly in lvm.conf, cluster operations will not work.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_lvhash()
|
||||||
|
{
|
||||||
|
/* Create hash table for keeping LV locks & status */
|
||||||
|
lv_hash = hash_create(100);
|
||||||
|
pthread_mutex_init(&lv_hash_lock, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Called to initialise the LVM context of the daemon */
|
||||||
|
int init_lvm(int using_gulm)
|
||||||
|
{
|
||||||
|
if (!(cmd = create_toolcontext(NULL))) {
|
||||||
|
log_error("Failed to allocate command context");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Use LOG_DAEMON for syslog messages instead of LOG_USER */
|
||||||
|
init_syslog(LOG_DAEMON);
|
||||||
|
init_debug(_LOG_ERR);
|
||||||
|
|
||||||
|
/* Check lvm.conf is setup for cluster-LVM */
|
||||||
|
check_config();
|
||||||
|
|
||||||
|
/* Remove any non-LV locks that may have been left around */
|
||||||
|
if (using_gulm)
|
||||||
|
drop_vg_locks();
|
||||||
|
|
||||||
|
get_initial_state();
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
35
daemons/clvmd/lvm-functions.h
Normal file
35
daemons/clvmd/lvm-functions.h
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
|
||||||
|
* Copyright (C) 2004 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Functions in lvm-functions.c */
|
||||||
|
|
||||||
|
#ifndef _LVM_FUNCTIONS_H
|
||||||
|
#define _LVM_FUNCTIONS_H
|
||||||
|
|
||||||
|
extern int pre_lock_lv(unsigned char lock_cmd, unsigned char lock_flags,
|
||||||
|
char *resource);
|
||||||
|
extern int do_lock_lv(unsigned char lock_cmd, unsigned char lock_flags,
|
||||||
|
char *resource);
|
||||||
|
extern int post_lock_lv(unsigned char lock_cmd, unsigned char lock_flags,
|
||||||
|
char *resource);
|
||||||
|
extern int do_check_lvm1(char *vgname);
|
||||||
|
extern int init_lvm(int using_gulm);
|
||||||
|
extern void init_lvhash(void);
|
||||||
|
|
||||||
|
extern int hold_unlock(char *resource);
|
||||||
|
extern int hold_lock(char *resource, int mode, int flags);
|
||||||
|
extern void unlock_all(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
371
daemons/clvmd/system-lv.c
Normal file
371
daemons/clvmd/system-lv.c
Normal file
@@ -0,0 +1,371 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
|
||||||
|
* Copyright (C) 2004 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Routines dealing with the System LV */
|
||||||
|
|
||||||
|
#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/mount.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 <dirent.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <mntent.h>
|
||||||
|
|
||||||
|
#include "libdlm.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "list.h"
|
||||||
|
#include "locking.h"
|
||||||
|
#include "system-lv.h"
|
||||||
|
#include "clvm.h"
|
||||||
|
#include "clvmd-comms.h"
|
||||||
|
#include "clvmd.h"
|
||||||
|
#ifdef HAVE_CCS
|
||||||
|
#include "ccs.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SYSTEM_LV_FILESYSTEM "ext2"
|
||||||
|
#define SYSTEM_LV_MOUNTPOINT "/tmp/.clvmd-XXXXXX"
|
||||||
|
|
||||||
|
extern char *config_filename(void);
|
||||||
|
|
||||||
|
static char system_lv_name[PATH_MAX] = { '\0' };
|
||||||
|
static char mount_point[PATH_MAX] = { '\0' };
|
||||||
|
static int mounted = 0;
|
||||||
|
static int mounted_rw = 0;
|
||||||
|
static int lockid;
|
||||||
|
static const char *lock_name = "CLVM_SYSTEM_LV";
|
||||||
|
|
||||||
|
/* Look in /proc/mounts or (as a last resort) /etc/mtab to
|
||||||
|
see if the system-lv is mounted. If it is mounted and we
|
||||||
|
think it's not then abort because we don't have the right
|
||||||
|
lock status and we don't know what other processes are doing with it.
|
||||||
|
|
||||||
|
Returns 1 for mounted, 0 for not mounted so it matches the condition
|
||||||
|
of the "mounted" static variable above.
|
||||||
|
*/
|
||||||
|
static int is_really_mounted(void)
|
||||||
|
{
|
||||||
|
FILE *mountfile;
|
||||||
|
struct mntent *ment;
|
||||||
|
|
||||||
|
mountfile = setmntent("/proc/mounts", "r");
|
||||||
|
if (!mountfile) {
|
||||||
|
mountfile = setmntent("/etc/mtab", "r");
|
||||||
|
if (!mountfile) {
|
||||||
|
log_error("Unable to open /proc/mounts or /etc/mtab");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Look for system LV name in the file */
|
||||||
|
do {
|
||||||
|
ment = getmntent(mountfile);
|
||||||
|
if (ment) {
|
||||||
|
if (strcmp(ment->mnt_fsname, system_lv_name) == 0) {
|
||||||
|
endmntent(mountfile);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (ment);
|
||||||
|
|
||||||
|
endmntent(mountfile);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the system LV name from the config file */
|
||||||
|
static int find_system_lv(void)
|
||||||
|
{
|
||||||
|
if (system_lv_name[0] == '\0') {
|
||||||
|
#ifdef HAVE_CCS
|
||||||
|
int error;
|
||||||
|
ccs_node_t *ctree;
|
||||||
|
|
||||||
|
/* Read the cluster config file */
|
||||||
|
/* Open the config file */
|
||||||
|
error = open_ccs_file(&ctree, "clvm.ccs");
|
||||||
|
if (error) {
|
||||||
|
perror("reading config file");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(system_lv_name, find_ccs_str(ctree,
|
||||||
|
"cluster/systemlv", '/',
|
||||||
|
"/dev/vg/system_lv"));
|
||||||
|
|
||||||
|
/* Finished with config file */
|
||||||
|
close_ccs_file(ctree);
|
||||||
|
#else
|
||||||
|
if (getenv("CLVMD_SYSTEM_LV"))
|
||||||
|
strcpy(system_lv_name, getenv("CLVMD_SYSTEM_LV"));
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* See if it has been mounted outside our control */
|
||||||
|
if (is_really_mounted() != mounted) {
|
||||||
|
log_error
|
||||||
|
("The system LV state has been mounted/umounted outside the control of clvmd\n"
|
||||||
|
"it cannot not be used for cluster communications until this is fixed.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No prizes */
|
||||||
|
int system_lv_umount(void)
|
||||||
|
{
|
||||||
|
if (!mounted)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (umount(mount_point) < 0) {
|
||||||
|
log_error("umount of system LV (%s) failed: %m\n",
|
||||||
|
system_lv_name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sync_unlock(lock_name, lockid);
|
||||||
|
mounted = 0;
|
||||||
|
|
||||||
|
/* Remove the mount point */
|
||||||
|
rmdir(mount_point);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int system_lv_mount(int readwrite)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
int saved_errno;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
if (find_system_lv()) {
|
||||||
|
errno = EBUSY;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Is it already mounted suitably? */
|
||||||
|
if (mounted) {
|
||||||
|
if (!readwrite || (readwrite && mounted_rw)) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
/* Mounted RO and we need RW */
|
||||||
|
if (system_lv_umount() < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Randomize the mount point */
|
||||||
|
strcpy(mount_point, SYSTEM_LV_MOUNTPOINT);
|
||||||
|
fd = mkstemp(mount_point);
|
||||||
|
if (fd < 0) {
|
||||||
|
log_error("mkstemp for system LV mount point failed: %m\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Race condition here but there's no mkstemp for directories */
|
||||||
|
close(fd);
|
||||||
|
unlink(mount_point);
|
||||||
|
mkdir(mount_point, 0600);
|
||||||
|
|
||||||
|
/* Make sure we have a system-lv lock */
|
||||||
|
status =
|
||||||
|
sync_lock(lock_name, (readwrite) ? LKM_EXMODE : LKM_CRMODE, 0,
|
||||||
|
&lockid);
|
||||||
|
if (status < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Mount it */
|
||||||
|
if (mount(system_lv_name, mount_point, SYSTEM_LV_FILESYSTEM,
|
||||||
|
MS_MGC_VAL | MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_SYNCHRONOUS
|
||||||
|
| (readwrite ? 0 : MS_RDONLY), NULL) < 0) {
|
||||||
|
/* mount(2) returns EINVAL if the volume has no FS on it. So, if we want to
|
||||||
|
write to it we try to make a filesystem in it and retry the mount */
|
||||||
|
if (errno == EINVAL && readwrite) {
|
||||||
|
char cmd[256];
|
||||||
|
|
||||||
|
log_error("Attempting mkfs on system LV device %s\n",
|
||||||
|
system_lv_name);
|
||||||
|
snprintf(cmd, sizeof(cmd), "/sbin/mkfs -t %s %s",
|
||||||
|
SYSTEM_LV_FILESYSTEM, system_lv_name);
|
||||||
|
system(cmd);
|
||||||
|
|
||||||
|
if (mount
|
||||||
|
(system_lv_name, mount_point, SYSTEM_LV_FILESYSTEM,
|
||||||
|
MS_MGC_VAL | MS_NOSUID | MS_NODEV | MS_NOEXEC |
|
||||||
|
MS_SYNCHRONOUS | (readwrite ? 0 : MS_RDONLY),
|
||||||
|
NULL) == 0)
|
||||||
|
goto mounted;
|
||||||
|
}
|
||||||
|
|
||||||
|
saved_errno = errno;
|
||||||
|
log_error("mount of system LV (%s, %s, %s) failed: %m\n",
|
||||||
|
system_lv_name, mount_point, SYSTEM_LV_FILESYSTEM);
|
||||||
|
sync_unlock(lock_name, lockid);
|
||||||
|
errno = saved_errno;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
mounted:
|
||||||
|
/* Set the internal flags */
|
||||||
|
mounted = 1;
|
||||||
|
mounted_rw = readwrite;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Erase *all* files in the root directory of the system LV.
|
||||||
|
This *MUST* be called with an appropriate lock held!
|
||||||
|
The LV is left mounted RW because it is assumed that the
|
||||||
|
caller wants to write something here after clearing some space */
|
||||||
|
int system_lv_eraseall(void)
|
||||||
|
{
|
||||||
|
DIR *dir;
|
||||||
|
struct dirent *ent;
|
||||||
|
char fname[PATH_MAX];
|
||||||
|
|
||||||
|
/* Must be mounted R/W */
|
||||||
|
system_lv_mount(1);
|
||||||
|
|
||||||
|
dir = opendir(mount_point);
|
||||||
|
if (!dir)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
while ((ent = readdir(dir))) {
|
||||||
|
struct stat st;
|
||||||
|
snprintf(fname, sizeof(fname), "%s/%s", mount_point,
|
||||||
|
ent->d_name);
|
||||||
|
|
||||||
|
if (stat(fname, &st)) {
|
||||||
|
if (S_ISREG(st.st_mode))
|
||||||
|
unlink(fname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closedir(dir);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is a "high-level" routine - it mounts the system LV, writes
|
||||||
|
the data into a file named after this node and then umounts the LV
|
||||||
|
again */
|
||||||
|
int system_lv_write_data(char *data, ssize_t len)
|
||||||
|
{
|
||||||
|
struct utsname nodeinfo;
|
||||||
|
char fname[PATH_MAX];
|
||||||
|
int outfile;
|
||||||
|
ssize_t thiswrite;
|
||||||
|
ssize_t written;
|
||||||
|
|
||||||
|
if (system_lv_mount(1))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Build the file name we are goingto use. */
|
||||||
|
uname(&nodeinfo);
|
||||||
|
snprintf(fname, sizeof(fname), "%s/%s", mount_point, nodeinfo.nodename);
|
||||||
|
|
||||||
|
/* Open the file for output */
|
||||||
|
outfile = open(fname, O_RDWR | O_CREAT | O_TRUNC, 0600);
|
||||||
|
if (outfile < 0) {
|
||||||
|
int saved_errno = errno;
|
||||||
|
system_lv_umount();
|
||||||
|
errno = saved_errno;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
written = 0;
|
||||||
|
do {
|
||||||
|
thiswrite = write(outfile, data + written, len - written);
|
||||||
|
if (thiswrite > 0)
|
||||||
|
written += thiswrite;
|
||||||
|
|
||||||
|
} while (written < len && thiswrite > 0);
|
||||||
|
|
||||||
|
close(outfile);
|
||||||
|
|
||||||
|
system_lv_umount();
|
||||||
|
return (thiswrite < 0) ? -1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is a "high-level" routine - it mounts the system LV, reads
|
||||||
|
the data from a named file and then umounts the LV
|
||||||
|
again */
|
||||||
|
int system_lv_read_data(char *fname_base, char *data, ssize_t *len)
|
||||||
|
{
|
||||||
|
char fname[PATH_MAX];
|
||||||
|
int outfile;
|
||||||
|
struct stat st;
|
||||||
|
ssize_t filesize;
|
||||||
|
ssize_t thisread;
|
||||||
|
ssize_t readbytes;
|
||||||
|
|
||||||
|
if (system_lv_mount(0))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Build the file name we are going to use. */
|
||||||
|
snprintf(fname, sizeof(fname), "%s/%s", mount_point, fname_base);
|
||||||
|
|
||||||
|
/* Get the file size and stuff. Actually we only need the file size but
|
||||||
|
this will also check that the file exists */
|
||||||
|
if (stat(fname, &st) < 0) {
|
||||||
|
int saved_errno = errno;
|
||||||
|
|
||||||
|
log_error("stat of file %s on system LV failed: %m\n", fname);
|
||||||
|
system_lv_umount();
|
||||||
|
errno = saved_errno;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
filesize = st.st_size;
|
||||||
|
|
||||||
|
outfile = open(fname, O_RDONLY);
|
||||||
|
if (outfile < 0) {
|
||||||
|
int saved_errno = errno;
|
||||||
|
|
||||||
|
log_error("open of file %s on system LV failed: %m\n", fname);
|
||||||
|
system_lv_umount();
|
||||||
|
errno = saved_errno;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
readbytes = 0;
|
||||||
|
do {
|
||||||
|
thisread =
|
||||||
|
read(outfile, data + readbytes, filesize - readbytes);
|
||||||
|
if (thisread > 0)
|
||||||
|
readbytes += thisread;
|
||||||
|
|
||||||
|
} while (readbytes < filesize && thisread > 0);
|
||||||
|
|
||||||
|
close(outfile);
|
||||||
|
|
||||||
|
system_lv_umount();
|
||||||
|
|
||||||
|
*len = readbytes;
|
||||||
|
return (thisread < 0) ? -1 : 0;
|
||||||
|
}
|
||||||
30
daemons/clvmd/system-lv.h
Normal file
30
daemons/clvmd/system-lv.h
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
|
||||||
|
* Copyright (C) 2004 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _CLVM_SYSTEM_LV_H
|
||||||
|
#define _CLVM_SYSTEM_LV_H
|
||||||
|
|
||||||
|
/* Prototypes for System-LV functions */
|
||||||
|
|
||||||
|
/* "low-level" functions */
|
||||||
|
extern int system_lv_umount(void);
|
||||||
|
extern int system_lv_mount(int readwrite);
|
||||||
|
extern int system_lv_eraseall(void);
|
||||||
|
|
||||||
|
/* "high-level" functions */
|
||||||
|
extern int system_lv_write_data(char *data, ssize_t len);
|
||||||
|
extern int system_lv_read_data(char *fname_base, char *data, ssize_t *len);
|
||||||
|
|
||||||
|
#endif
|
||||||
484
daemons/clvmd/tcp-comms.c
Normal file
484
daemons/clvmd/tcp-comms.c
Normal file
@@ -0,0 +1,484 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
*******************************************************************************
|
||||||
|
**
|
||||||
|
** 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 "clvm.h"
|
||||||
|
#include "clvmd-comms.h"
|
||||||
|
#include "clvmd.h"
|
||||||
|
#include "clvmd-gulm.h"
|
||||||
|
#include "hash.h"
|
||||||
|
|
||||||
|
#define DEFAULT_TCP_PORT 21064
|
||||||
|
|
||||||
|
static int listen_fd = -1;
|
||||||
|
static int tcp_port;
|
||||||
|
struct 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 = hash_create(100);
|
||||||
|
tcp_port = 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(char *csid)
|
||||||
|
{
|
||||||
|
struct local_client *client;
|
||||||
|
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 */
|
||||||
|
client = hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
|
||||||
|
if (client)
|
||||||
|
{
|
||||||
|
hash_remove_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
|
||||||
|
client->removeme = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Look for a mangled one too */
|
||||||
|
csid[0] ^= 0x80;
|
||||||
|
|
||||||
|
client = hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
|
||||||
|
if (client)
|
||||||
|
{
|
||||||
|
hash_remove_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
|
||||||
|
client->removeme = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Put it back as we found it */
|
||||||
|
csid[0] ^= 0x80;
|
||||||
|
}
|
||||||
|
|
||||||
|
int alloc_client(int fd, char *csid, struct local_client **new_client)
|
||||||
|
{
|
||||||
|
struct local_client *client;
|
||||||
|
|
||||||
|
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 (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 (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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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, 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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 = 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 = 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;
|
||||||
|
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(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, unsigned 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 = 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, 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(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(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(char *);
|
||||||
|
int get_main_gulm_cluster_fd(void);
|
||||||
|
int cluster_fd_gulm_callback(struct local_client *fd, char *buf, int len, char *csid, struct local_client **new_client);
|
||||||
|
int gulm_cluster_send_message(void *buf, int msglen, char *csid, const char *errtext);
|
||||||
|
void get_our_gulm_csid(char *csid);
|
||||||
|
int gulm_connect_csid(char *csid, struct local_client **newclient);
|
||||||
1
daemons/cmirrord/.gitignore
vendored
1
daemons/cmirrord/.gitignore
vendored
@@ -1 +0,0 @@
|
|||||||
cmirrord
|
|
||||||
@@ -1,43 +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
srcdir = @srcdir@
|
|
||||||
top_srcdir = @top_srcdir@
|
|
||||||
top_builddir = @top_builddir@
|
|
||||||
|
|
||||||
CPG_LIBS = @CPG_LIBS@
|
|
||||||
CPG_CFLAGS = @CPG_CFLAGS@
|
|
||||||
|
|
||||||
SOURCES = clogd.c cluster.c compat.c functions.c link_mon.c local.c logging.c
|
|
||||||
|
|
||||||
TARGETS = cmirrord
|
|
||||||
|
|
||||||
CFLOW_SOURCES = $(addprefix $(srcdir)/, $(SOURCES))
|
|
||||||
CFLOW_TARGET := $(TARGETS)
|
|
||||||
|
|
||||||
include $(top_builddir)/make.tmpl
|
|
||||||
|
|
||||||
LMLIBS += $(CPG_LIBS)
|
|
||||||
CFLAGS += $(CPG_CFLAGS) $(EXTRA_EXEC_CFLAGS)
|
|
||||||
LDFLAGS += $(EXTRA_EXEC_LDFLAGS) $(ELDFLAGS)
|
|
||||||
|
|
||||||
cmirrord: $(OBJECTS)
|
|
||||||
@echo " [CC] $@"
|
|
||||||
$(Q) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJECTS) \
|
|
||||||
$(LMLIBS) -L$(top_builddir)/libdm -ldevmapper $(LIBS)
|
|
||||||
|
|
||||||
install_cluster: $(TARGETS)
|
|
||||||
@echo " [INSTALL] $<"
|
|
||||||
$(Q) $(INSTALL_PROGRAM) -D $< $(usrsbindir)/$(<F)
|
|
||||||
|
|
||||||
install: install_cluster
|
|
||||||
@@ -1,293 +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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);
|
|
||||||
/* coverity[leaked_handle] devnull cannot leak here */
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
#ifndef _LVM_CLOG_CLUSTER_H
|
|
||||||
#define _LVM_CLOG_CLUSTER_H
|
|
||||||
|
|
||||||
#include "libdm/libdevmapper.h"
|
|
||||||
#include "libdm/misc/dm-log-userspace.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 version_u {
|
|
||||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 "lib/mm/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,35 +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
#ifndef _LVM_CLOG_FUNCTIONS_H
|
|
||||||
#define _LVM_CLOG_FUNCTIONS_H
|
|
||||||
|
|
||||||
#include "libdm/libdevmapper.h"
|
|
||||||
#include "libdm/misc/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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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,73 +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _LVM_CLOG_LOGGING_H
|
|
||||||
#define _LVM_CLOG_LOGGING_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,3 @@
|
|||||||
init_fifos
|
process_event
|
||||||
fini_fifos
|
register_device
|
||||||
daemon_talk
|
unregister_device
|
||||||
dm_event_get_version
|
|
||||||
1
daemons/dmeventd/.gitignore
vendored
1
daemons/dmeventd/.gitignore
vendored
@@ -1 +0,0 @@
|
|||||||
dmeventd
|
|
||||||
@@ -1,116 +1,51 @@
|
|||||||
#
|
#
|
||||||
# Copyright (C) 2005-2011 Red Hat, Inc. All rights reserved.
|
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||||
|
# Copyright (C) 2004 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.
|
||||||
#
|
#
|
||||||
# This copyrighted material is made available to anyone wishing to use,
|
# This copyrighted material is made available to anyone wishing to use,
|
||||||
# modify, copy, or redistribute it subject to the terms and conditions
|
# modify, copy, or redistribute it subject to the terms and conditions
|
||||||
# of the GNU Lesser General Public License v.2.1.
|
# of the GNU General Public License v.2.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program; if not, write to the Free Software Foundation,
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
srcdir = @srcdir@
|
srcdir = @srcdir@
|
||||||
top_srcdir = @top_srcdir@
|
top_srcdir = @top_srcdir@
|
||||||
top_builddir = @top_builddir@
|
VPATH = @srcdir@
|
||||||
abs_srcdir = @abs_srcdir@
|
|
||||||
|
|
||||||
SOURCES = libdevmapper-event.c
|
TARGETS = dmevent dmeventd
|
||||||
SOURCES2 = dmeventd.c
|
INSTALL_TYPE = install_dynamic
|
||||||
|
|
||||||
TARGETS = dmeventd
|
SOURCES = noop.c
|
||||||
CFLOW_SOURCES = $(addprefix $(srcdir)/, $(SOURCES) $(SOURCES2) \
|
CLEAN_TARGETS = dmevent.o dmeventd.o
|
||||||
plugins/lvm2/dmeventd_lvm.c \
|
|
||||||
plugins/mirror/dmeventd_mirror.c \
|
|
||||||
plugins/raid/dmeventd_raid.c \
|
|
||||||
plugins/snapshot/dmeventd_snapshot.c \
|
|
||||||
plugins/thin/dmeventd_thin.c \
|
|
||||||
plugins/vdo/dmeventd_vdo.c \
|
|
||||||
)
|
|
||||||
CFLOW_TARGET := $(TARGETS)
|
|
||||||
|
|
||||||
.PHONY: install_lib_dynamic install_lib_static install_include \
|
ifeq ("@LIB_SUFFIX@","dylib")
|
||||||
install_pkgconfig install_dmeventd_dynamic install_dmeventd_static \
|
LIB_SHARED = libdmeventdnoop.dylib
|
||||||
install_lib install_dmeventd
|
else
|
||||||
|
LIB_SHARED = libdmeventdnoop.so
|
||||||
INSTALL_DMEVENTD_TARGETS = install_dmeventd_dynamic
|
|
||||||
INSTALL_LIB_TARGETS = install_lib_dynamic
|
|
||||||
|
|
||||||
LIB_NAME = libdevmapper-event
|
|
||||||
ifeq ("@STATIC_LINK@", "yes")
|
|
||||||
LIB_STATIC = $(LIB_NAME).a
|
|
||||||
TARGETS += $(LIB_STATIC) dmeventd.static
|
|
||||||
INSTALL_DMEVENTD_TARGETS += install_dmeventd_static
|
|
||||||
INSTALL_LIB_TARGETS += install_lib_static
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
LIB_VERSION = $(LIB_VERSION_DM)
|
LDFLAGS += -ldl -ldevmapper -lpthread
|
||||||
LIB_SHARED = $(LIB_NAME).$(LIB_SUFFIX)
|
|
||||||
LIBS = $(PTHREAD_LIBS) -L$(interfacebuilddir) -ldevmapper
|
|
||||||
|
|
||||||
CLEAN_TARGETS = dmeventd.static $(LIB_NAME).a
|
include ../make.tmpl
|
||||||
|
|
||||||
ifneq ($(MAKECMDGOALS),device-mapper)
|
libdmeventdnoop.so: noop.o
|
||||||
SUBDIRS+=plugins
|
|
||||||
endif
|
|
||||||
|
|
||||||
CFLOW_LIST = $(SOURCES)
|
dmevent: dmevent.o $(interfacedir)/libdevmapper.$(LIB_SUFFIX) $(top_srcdir)/lib/event/libdmevent.$(LIB_SUFFIX)
|
||||||
CFLOW_LIST_TARGET = $(LIB_NAME).cflow
|
$(CC) -o $@ dmevent.o $(LDFLAGS) \
|
||||||
|
-L$(interfacedir) -L$(DESTDIR)/lib -L$(top_srcdir)/lib/event -L$(top_srcdir)/multilog -ldmevent $(LIBS)
|
||||||
|
|
||||||
EXPORTED_HEADER = $(srcdir)/libdevmapper-event.h
|
dmeventd: dmeventd.o $(interfacedir)/libdevmapper.$(LIB_SUFFIX) $(top_srcdir)/lib/event/libdmevent.$(LIB_SUFFIX)
|
||||||
EXPORTED_FN_PREFIX = dm_event
|
$(CC) -o $@ dmeventd.o $(LDFLAGS) \
|
||||||
|
-L$(interfacedir) -L$(DESTDIR)/lib -L$(top_srcdir)/lib/event -L$(top_srcdir)/multilog -ldmevent $(LIBS)
|
||||||
|
|
||||||
include $(top_builddir)/make.tmpl
|
install: $(INSTALL_TYPE)
|
||||||
|
|
||||||
all: device-mapper
|
.PHONY: install_dynamic
|
||||||
device-mapper: $(TARGETS)
|
|
||||||
plugins.device-mapper: $(LIB_SHARED)
|
|
||||||
|
|
||||||
CFLAGS_dmeventd.o += $(EXTRA_EXEC_CFLAGS)
|
install_dynamic: dmeventd
|
||||||
|
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) dmeventd $(sbindir)/dmeventd
|
||||||
|
|
||||||
dmeventd: $(LIB_SHARED) dmeventd.o
|
|
||||||
@echo " [CC] $@"
|
|
||||||
$(Q) $(CC) $(CFLAGS) $(LDFLAGS) $(EXTRA_EXEC_LDFLAGS) $(ELDFLAGS) dmeventd.o \
|
|
||||||
-o $@ $(DL_LIBS) $(DMEVENT_LIBS) $(LIBS)
|
|
||||||
|
|
||||||
dmeventd.static: $(LIB_STATIC) dmeventd.o
|
|
||||||
@echo " [CC] $@"
|
|
||||||
$(Q) $(CC) $(CFLAGS) $(LDFLAGS) -static dmeventd.o \
|
|
||||||
-o $@ $(DL_LIBS) $(DMEVENT_LIBS) $(LIBS) $(STATIC_LIBS)
|
|
||||||
|
|
||||||
ifeq ("@PKGCONFIG@", "yes")
|
|
||||||
INSTALL_LIB_TARGETS += install_pkgconfig
|
|
||||||
endif
|
|
||||||
|
|
||||||
install_include: $(srcdir)/libdevmapper-event.h
|
|
||||||
@echo " [INSTALL] $(<F)"
|
|
||||||
$(Q) $(INSTALL_DATA) -D $< $(includedir)/$(<F)
|
|
||||||
|
|
||||||
install_pkgconfig: libdevmapper-event.pc
|
|
||||||
@echo " [INSTALL] $<"
|
|
||||||
$(Q) $(INSTALL_DATA) -D $< $(pkgconfigdir)/devmapper-event.pc
|
|
||||||
|
|
||||||
install_lib_dynamic: install_lib_shared
|
|
||||||
|
|
||||||
install_lib_static: $(LIB_STATIC)
|
|
||||||
@echo " [INSTALL] $<"
|
|
||||||
$(Q) $(INSTALL_DATA) -D $< $(usrlibdir)/$(<F)
|
|
||||||
|
|
||||||
install_lib: $(INSTALL_LIB_TARGETS)
|
|
||||||
|
|
||||||
install_dmeventd_dynamic: dmeventd
|
|
||||||
@echo " [INSTALL] $<"
|
|
||||||
$(Q) $(INSTALL_PROGRAM) -D $< $(sbindir)/$(<F)
|
|
||||||
|
|
||||||
install_dmeventd_static: dmeventd.static
|
|
||||||
@echo " [INSTALL] $<"
|
|
||||||
$(Q) $(INSTALL_PROGRAM) -D $< $(staticdir)/$(<F)
|
|
||||||
|
|
||||||
install_dmeventd: $(INSTALL_DMEVENTD_TARGETS)
|
|
||||||
|
|
||||||
install: install_include install_lib install_dmeventd
|
|
||||||
|
|
||||||
install_device-mapper: install_include install_lib install_dmeventd
|
|
||||||
|
|
||||||
DISTCLEAN_TARGETS += libdevmapper-event.pc
|
|
||||||
|
|||||||
165
daemons/dmeventd/dmevent.c
Normal file
165
daemons/dmeventd/dmevent.c
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005 Red Hat, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* This file is part of the device-mapper userspace tools.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use,
|
||||||
|
* modify, copy, or redistribute it subject to the terms and conditions
|
||||||
|
* of the GNU Lesser General Public License v.2.1.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "libdevmapper.h"
|
||||||
|
#include "libdm-event.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/file.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
static enum event_type events = ALL_ERRORS; /* All until we can distinguish. */
|
||||||
|
static char default_dso_name[] = "noop"; /* default DSO is noop */
|
||||||
|
static int default_reg = 1; /* default action is register */
|
||||||
|
|
||||||
|
/* Display help. */
|
||||||
|
static void print_usage(char *name)
|
||||||
|
{
|
||||||
|
char *cmd = strrchr(name, '/');
|
||||||
|
|
||||||
|
cmd = cmd ? cmd + 1 : name;
|
||||||
|
printf("Usage::\n"
|
||||||
|
"%s [options] <device>\n"
|
||||||
|
"\n"
|
||||||
|
"Options:\n"
|
||||||
|
" -d <dso> Specify the DSO to use.\n"
|
||||||
|
" -h Print this usage.\n"
|
||||||
|
" -l List registered devices.\n"
|
||||||
|
" -r Register for event (default).\n"
|
||||||
|
" -u Unregister for event.\n"
|
||||||
|
"\n", cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse command line arguments. */
|
||||||
|
static int parse_argv(int argc, char **argv,
|
||||||
|
char **dso_name, char **device, int *reg, int *list)
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
const char *options = "d:hlru";
|
||||||
|
|
||||||
|
while ((c = getopt(argc, argv, options)) != -1) {
|
||||||
|
switch (c) {
|
||||||
|
case 'd':
|
||||||
|
if (!(*dso_name = strdup(optarg)))
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
print_usage(argv[0]);
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
case 'l':
|
||||||
|
*list = 1;
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
*reg = 1;
|
||||||
|
break;
|
||||||
|
case 'u':
|
||||||
|
*reg = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "Unknown option '%c'.\n"
|
||||||
|
"Try '-h' for help.\n", c);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!*dso_name && !(*dso_name = strdup(default_dso_name)))
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
if (optind >= argc) {
|
||||||
|
if (!*list) {
|
||||||
|
fprintf(stderr, "You need to specify a device.\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} else if (!(*device = strdup(argv[optind])))
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int list = 0, next = 0, ret, reg = default_reg;
|
||||||
|
char *device = NULL, *device_arg, *dso_name = NULL, *dso_name_arg;
|
||||||
|
|
||||||
|
if (!parse_argv(argc, argv, &dso_name, &device, ®, &list))
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
device_arg = device;
|
||||||
|
dso_name_arg = dso_name;
|
||||||
|
|
||||||
|
if (list) {
|
||||||
|
do {
|
||||||
|
if (!(ret= dm_get_registered_device(&dso_name,
|
||||||
|
&device,
|
||||||
|
&events, next))) {
|
||||||
|
printf("%s %s 0x%x\n",
|
||||||
|
dso_name, device, events);
|
||||||
|
|
||||||
|
if (device_arg)
|
||||||
|
break;
|
||||||
|
|
||||||
|
next = 1;
|
||||||
|
}
|
||||||
|
} while (!ret);
|
||||||
|
|
||||||
|
if (dso_name)
|
||||||
|
free(dso_name);
|
||||||
|
|
||||||
|
if (device)
|
||||||
|
free(device);
|
||||||
|
|
||||||
|
ret = (ret && device_arg) ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ret = reg ? dm_register_for_event(dso_name, device, events) :
|
||||||
|
dm_unregister_for_event(dso_name, device, events))) {
|
||||||
|
fprintf(stderr, "Failed to %sregister %s: %s\n",
|
||||||
|
reg ? "": "un", device, strerror(-ret));
|
||||||
|
ret = EXIT_FAILURE;
|
||||||
|
} else {
|
||||||
|
printf("%s %sregistered successfully.\n",
|
||||||
|
device, reg ? "" : "un");
|
||||||
|
ret = EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (device_arg)
|
||||||
|
free(device_arg);
|
||||||
|
|
||||||
|
if (dso_name_arg)
|
||||||
|
free(dso_name_arg);
|
||||||
|
|
||||||
|
exit(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Overrides for Emacs so that we follow Linus's tabbing style.
|
||||||
|
* Emacs will notice this stuff at the end of the file and automatically
|
||||||
|
* adjust the settings for this buffer only. This must remain at the end
|
||||||
|
* of the file.
|
||||||
|
* ---------------------------------------------------------------------------
|
||||||
|
* Local variables:
|
||||||
|
* c-file-style: "linux"
|
||||||
|
* End:
|
||||||
|
*/
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,76 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* This file is part of the device-mapper userspace tools.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use,
|
|
||||||
* modify, copy, or redistribute it subject to the terms and conditions
|
|
||||||
* of the GNU Lesser General Public License v.2.1.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this program; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __DMEVENTD_DOT_H__
|
|
||||||
#define __DMEVENTD_DOT_H__
|
|
||||||
|
|
||||||
/* FIXME This stuff must be configurable. */
|
|
||||||
|
|
||||||
#define DM_EVENT_FIFO_CLIENT DEFAULT_DM_RUN_DIR "/dmeventd-client"
|
|
||||||
#define DM_EVENT_FIFO_SERVER DEFAULT_DM_RUN_DIR "/dmeventd-server"
|
|
||||||
|
|
||||||
#define DM_EVENT_DEFAULT_TIMEOUT 10
|
|
||||||
|
|
||||||
/* Commands for the daemon passed in the message below. */
|
|
||||||
enum dm_event_command {
|
|
||||||
DM_EVENT_CMD_ACTIVE = 1,
|
|
||||||
DM_EVENT_CMD_REGISTER_FOR_EVENT,
|
|
||||||
DM_EVENT_CMD_UNREGISTER_FOR_EVENT,
|
|
||||||
DM_EVENT_CMD_GET_REGISTERED_DEVICE,
|
|
||||||
DM_EVENT_CMD_GET_NEXT_REGISTERED_DEVICE,
|
|
||||||
DM_EVENT_CMD_SET_TIMEOUT,
|
|
||||||
DM_EVENT_CMD_GET_TIMEOUT,
|
|
||||||
DM_EVENT_CMD_HELLO,
|
|
||||||
DM_EVENT_CMD_DIE,
|
|
||||||
DM_EVENT_CMD_GET_STATUS,
|
|
||||||
DM_EVENT_CMD_GET_PARAMETERS,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Message passed between client and daemon. */
|
|
||||||
struct dm_event_daemon_message {
|
|
||||||
uint32_t cmd;
|
|
||||||
uint32_t size;
|
|
||||||
char *data;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* FIXME Is this meant to be exported? I can't see where the
|
|
||||||
interface uses it. */
|
|
||||||
/* Fifos for client/daemon communication. */
|
|
||||||
struct dm_event_fifos {
|
|
||||||
int client;
|
|
||||||
int server;
|
|
||||||
const char *client_path;
|
|
||||||
const char *server_path;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* EXIT_SUCCESS 0 -- stdlib.h */
|
|
||||||
/* EXIT_FAILURE 1 -- stdlib.h */
|
|
||||||
/* EXIT_LOCKFILE_INUSE 2 -- obsoleted */
|
|
||||||
#define EXIT_DESC_CLOSE_FAILURE 3
|
|
||||||
#define EXIT_DESC_OPEN_FAILURE 4
|
|
||||||
/* EXIT_OPEN_PID_FAILURE 5 -- obsoleted */
|
|
||||||
#define EXIT_FIFO_FAILURE 6
|
|
||||||
#define EXIT_CHDIR_FAILURE 7
|
|
||||||
|
|
||||||
/* Implemented in libdevmapper-event.c, but not part of public API. */
|
|
||||||
// FIXME misuse of bitmask as enum
|
|
||||||
int daemon_talk(struct dm_event_fifos *fifos,
|
|
||||||
struct dm_event_daemon_message *msg, int cmd,
|
|
||||||
const char *dso_name, const char *dev_name,
|
|
||||||
enum dm_event_mask evmask, uint32_t timeout);
|
|
||||||
int init_fifos(struct dm_event_fifos *fifos);
|
|
||||||
void fini_fifos(struct dm_event_fifos *fifos);
|
|
||||||
int dm_event_get_version(struct dm_event_fifos *fifos, int *version);
|
|
||||||
|
|
||||||
#endif /* __DMEVENTD_DOT_H__ */
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,136 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2005-2015 Red Hat, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* This file is part of the device-mapper userspace tools.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use,
|
|
||||||
* modify, copy, or redistribute it subject to the terms and conditions
|
|
||||||
* of the GNU Lesser General Public License v.2.1.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this program; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Note that this file is released only as part of a technology preview
|
|
||||||
* and its contents may change in future updates in ways that do not
|
|
||||||
* preserve compatibility.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef LIB_DMEVENT_H
|
|
||||||
#define LIB_DMEVENT_H
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Event library interface.
|
|
||||||
*/
|
|
||||||
|
|
||||||
enum dm_event_mask {
|
|
||||||
DM_EVENT_SETTINGS_MASK = 0x0000FF,
|
|
||||||
DM_EVENT_SINGLE = 0x000001, /* Report multiple errors just once. */
|
|
||||||
DM_EVENT_MULTI = 0x000002, /* Report all of them. */
|
|
||||||
|
|
||||||
DM_EVENT_ERROR_MASK = 0x00FF00,
|
|
||||||
DM_EVENT_SECTOR_ERROR = 0x000100, /* Failure on a particular sector. */
|
|
||||||
DM_EVENT_DEVICE_ERROR = 0x000200, /* Device failure. */
|
|
||||||
DM_EVENT_PATH_ERROR = 0x000400, /* Failure on an io path. */
|
|
||||||
DM_EVENT_ADAPTOR_ERROR = 0x000800, /* Failure of a host adaptor. */
|
|
||||||
|
|
||||||
DM_EVENT_STATUS_MASK = 0xFF0000,
|
|
||||||
DM_EVENT_SYNC_STATUS = 0x010000, /* Mirror synchronization completed/failed. */
|
|
||||||
DM_EVENT_TIMEOUT = 0x020000, /* Timeout has occured */
|
|
||||||
|
|
||||||
DM_EVENT_REGISTRATION_PENDING = 0x1000000, /* Monitor thread is setting-up/shutting-down */
|
|
||||||
};
|
|
||||||
|
|
||||||
#define DM_EVENT_ALL_ERRORS DM_EVENT_ERROR_MASK
|
|
||||||
#define DM_EVENT_PROTOCOL_VERSION 2
|
|
||||||
|
|
||||||
struct dm_task;
|
|
||||||
struct dm_event_handler;
|
|
||||||
|
|
||||||
struct dm_event_handler *dm_event_handler_create(void);
|
|
||||||
void dm_event_handler_destroy(struct dm_event_handler *dmevh);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Path of shared library to handle events.
|
|
||||||
*
|
|
||||||
* All of dmeventd, dso, device_name and uuid strings are duplicated so
|
|
||||||
* you do not need to keep the pointers valid after the call succeeds.
|
|
||||||
* They may return -ENOMEM though.
|
|
||||||
*/
|
|
||||||
int dm_event_handler_set_dso(struct dm_event_handler *dmevh, const char *path);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Path of dmeventd binary.
|
|
||||||
*/
|
|
||||||
int dm_event_handler_set_dmeventd_path(struct dm_event_handler *dmevh, const char *dmeventd_path);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Identify the device to monitor by exactly one of device_name, uuid or
|
|
||||||
* device number. String arguments are duplicated, see above.
|
|
||||||
*/
|
|
||||||
int dm_event_handler_set_dev_name(struct dm_event_handler *dmevh, const char *device_name);
|
|
||||||
|
|
||||||
int dm_event_handler_set_uuid(struct dm_event_handler *dmevh, const char *uuid);
|
|
||||||
|
|
||||||
void dm_event_handler_set_major(struct dm_event_handler *dmevh, int major);
|
|
||||||
void dm_event_handler_set_minor(struct dm_event_handler *dmevh, int minor);
|
|
||||||
void dm_event_handler_set_timeout(struct dm_event_handler *dmevh, int timeout);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Specify mask for events to monitor.
|
|
||||||
*/
|
|
||||||
// FIXME misuse of bitmask as enum
|
|
||||||
void dm_event_handler_set_event_mask(struct dm_event_handler *dmevh,
|
|
||||||
enum dm_event_mask evmask);
|
|
||||||
|
|
||||||
const char *dm_event_handler_get_dso(const struct dm_event_handler *dmevh);
|
|
||||||
const char *dm_event_handler_get_dev_name(const struct dm_event_handler *dmevh);
|
|
||||||
const char *dm_event_handler_get_uuid(const struct dm_event_handler *dmevh);
|
|
||||||
int dm_event_handler_get_major(const struct dm_event_handler *dmevh);
|
|
||||||
int dm_event_handler_get_minor(const struct dm_event_handler *dmevh);
|
|
||||||
int dm_event_handler_get_timeout(const struct dm_event_handler *dmevh);
|
|
||||||
// FIXME misuse of bitmask as enum
|
|
||||||
enum dm_event_mask dm_event_handler_get_event_mask(const struct dm_event_handler *dmevh);
|
|
||||||
|
|
||||||
/* FIXME Review interface (what about this next thing?) */
|
|
||||||
int dm_event_get_registered_device(struct dm_event_handler *dmevh, int next);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initiate monitoring using dmeventd.
|
|
||||||
*/
|
|
||||||
int dm_event_register_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_log_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
|
|
||||||
detailed descriptions. */
|
|
||||||
// FIXME misuse of bitmask as enum
|
|
||||||
void process_event(struct dm_task *dmt, enum dm_event_mask evmask, void **user);
|
|
||||||
int register_device(const char *device_name, const char *uuid, int major, int minor, void **user);
|
|
||||||
int unregister_device(const char *device_name, const char *uuid, int major,
|
|
||||||
int minor, void **user);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
prefix=@prefix@
|
|
||||||
exec_prefix=@exec_prefix@
|
|
||||||
libdir=@libdir@
|
|
||||||
includedir=@includedir@
|
|
||||||
|
|
||||||
Name: devmapper-event
|
|
||||||
Description: device-mapper event library
|
|
||||||
Version: @DM_LIB_PATCHLEVEL@
|
|
||||||
Cflags: -I${includedir}
|
|
||||||
Libs: -L${libdir} -ldevmapper-event
|
|
||||||
12
daemons/dmeventd/mktestdevices
Normal file
12
daemons/dmeventd/mktestdevices
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# Create test devices for dmeventd
|
||||||
|
#
|
||||||
|
|
||||||
|
trap "rm -f /tmp/tmp.$$" 0 1 2 3 15
|
||||||
|
|
||||||
|
echo "0 1024 zero" > /tmp/tmp.$$
|
||||||
|
dmsetup create test /tmp/tmp.$$
|
||||||
|
dmsetup create test1 /tmp/tmp.$$
|
||||||
|
|
||||||
|
kill -15 $$
|
||||||
39
daemons/dmeventd/noop.c
Normal file
39
daemons/dmeventd/noop.c
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005 Red Hat, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* This file is part of the device-mapper userspace tools.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use,
|
||||||
|
* modify, copy, or redistribute it subject to the terms and conditions
|
||||||
|
* of the GNU Lesser General Public License v.2.1.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "libdm-event.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void process_event(char *device, enum event_type event)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "[%s] %s(%d) - Device: %s, Event %d\n",
|
||||||
|
__FILE__, __func__, __LINE__, device, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
int register_device(char *device)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "[%s] %s(%d) - Device: %s\n",
|
||||||
|
__FILE__, __func__, __LINE__, device);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int unregister_device(char *device)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "[%s] %s(%d) - Device: %s\n",
|
||||||
|
__FILE__, __func__, __LINE__, device);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
@@ -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,30 +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
srcdir = @srcdir@
|
|
||||||
top_srcdir = @top_srcdir@
|
|
||||||
top_builddir = @top_builddir@
|
|
||||||
|
|
||||||
CLDFLAGS += -L$(top_builddir)/tools
|
|
||||||
LIBS += $(DMEVENT_LIBS) $(PTHREAD_LIBS) @LVM2CMD_LIB@
|
|
||||||
|
|
||||||
SOURCES = dmeventd_lvm.c
|
|
||||||
|
|
||||||
LIB_SHARED = libdevmapper-event-lvm2.$(LIB_SUFFIX)
|
|
||||||
LIB_VERSION = $(LIB_VERSION_LVM)
|
|
||||||
|
|
||||||
include $(top_builddir)/make.tmpl
|
|
||||||
|
|
||||||
install_lvm2: install_lib_shared
|
|
||||||
|
|
||||||
install: install_lvm2
|
|
||||||
@@ -1,192 +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "lib/misc/lib.h"
|
|
||||||
#include "dmeventd_lvm.h"
|
|
||||||
#include "daemons/dmeventd/libdevmapper-event.h"
|
|
||||||
#include "tools/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;
|
|
||||||
static DM_LIST_INIT(_env_registry);
|
|
||||||
|
|
||||||
struct env_data {
|
|
||||||
struct dm_list list;
|
|
||||||
const char *cmd;
|
|
||||||
const char *data;
|
|
||||||
};
|
|
||||||
|
|
||||||
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_threaded()))
|
|
||||||
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;
|
|
||||||
dm_list_init(&_env_registry);
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
static char _internal_prefix[] = "_dmeventd_";
|
|
||||||
char *vg = NULL, *lv = NULL, *layer;
|
|
||||||
int r;
|
|
||||||
struct env_data *env_data;
|
|
||||||
const char *env = NULL;
|
|
||||||
|
|
||||||
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';
|
|
||||||
|
|
||||||
if (!strncmp(cmd, _internal_prefix, sizeof(_internal_prefix) - 1)) {
|
|
||||||
/* check if ENVVAR wasn't already resolved */
|
|
||||||
dm_list_iterate_items(env_data, &_env_registry)
|
|
||||||
if (!strcmp(cmd, env_data->cmd)) {
|
|
||||||
env = env_data->data;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!env) {
|
|
||||||
/* run lvm2 command to find out setting value */
|
|
||||||
dmeventd_lvm2_lock();
|
|
||||||
if (!dmeventd_lvm2_run(cmd) ||
|
|
||||||
!(env = getenv(cmd))) {
|
|
||||||
dmeventd_lvm2_unlock();
|
|
||||||
log_error("Unable to find configured command.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/* output of internal command passed via env var */
|
|
||||||
env = dm_pool_strdup(_mem_pool, env); /* copy with lock */
|
|
||||||
dmeventd_lvm2_unlock();
|
|
||||||
if (!env ||
|
|
||||||
!(env_data = dm_pool_zalloc(_mem_pool, sizeof(*env_data))) ||
|
|
||||||
!(env_data->cmd = dm_pool_strdup(_mem_pool, cmd))) {
|
|
||||||
log_error("Unable to allocate env memory.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
env_data->data = env;
|
|
||||||
/* add to ENVVAR registry */
|
|
||||||
dm_list_add(&_env_registry, &env_data->list);
|
|
||||||
}
|
|
||||||
cmd = env;
|
|
||||||
}
|
|
||||||
|
|
||||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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,3 +0,0 @@
|
|||||||
process_event
|
|
||||||
register_device
|
|
||||||
unregister_device
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
#
|
|
||||||
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
|
||||||
# Copyright (C) 2004-2005, 2008-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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
srcdir = @srcdir@
|
|
||||||
top_srcdir = @top_srcdir@
|
|
||||||
top_builddir = @top_builddir@
|
|
||||||
|
|
||||||
CLDFLAGS += -L$(top_builddir)/daemons/dmeventd/plugins/lvm2
|
|
||||||
LIBS += -ldevmapper-event-lvm2
|
|
||||||
|
|
||||||
SOURCES = dmeventd_mirror.c
|
|
||||||
|
|
||||||
LIB_NAME = libdevmapper-event-lvm2mirror
|
|
||||||
LIB_SHARED = $(LIB_NAME).$(LIB_SUFFIX)
|
|
||||||
LIB_VERSION = $(LIB_VERSION_LVM)
|
|
||||||
|
|
||||||
include $(top_builddir)/make.tmpl
|
|
||||||
|
|
||||||
install_lvm2: install_dm_plugin
|
|
||||||
|
|
||||||
install: install_lvm2
|
|
||||||
@@ -1,211 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2005-2017 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "lib/misc/lib.h"
|
|
||||||
#include "daemons/dmeventd/plugins/lvm2/dmeventd_lvm.h"
|
|
||||||
#include "daemons/dmeventd/libdevmapper-event.h"
|
|
||||||
#include "lib/activate/activate.h"
|
|
||||||
|
|
||||||
/* FIXME Reformat to 80 char lines. */
|
|
||||||
|
|
||||||
#define ME_IGNORE 0
|
|
||||||
#define ME_INSYNC 1
|
|
||||||
#define ME_FAILURE 2
|
|
||||||
|
|
||||||
struct dso_state {
|
|
||||||
struct dm_pool *mem;
|
|
||||||
char cmd_lvconvert[512];
|
|
||||||
};
|
|
||||||
|
|
||||||
DM_EVENT_LOG_FN("mirr")
|
|
||||||
|
|
||||||
static void _process_status_code(dm_status_mirror_health_t health,
|
|
||||||
uint32_t major, uint32_t minor,
|
|
||||||
const char *dev_type, int *r)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* A => Alive - No failures
|
|
||||||
* D => Dead - A write failure occurred leaving mirror out-of-sync
|
|
||||||
* F => Flush failed.
|
|
||||||
* S => Sync - A sychronization failure occurred, mirror out-of-sync
|
|
||||||
* R => Read - A read failure occurred, mirror data unaffected
|
|
||||||
* U => Unclassified failure (bug)
|
|
||||||
*/
|
|
||||||
switch (health) {
|
|
||||||
case DM_STATUS_MIRROR_ALIVE:
|
|
||||||
return;
|
|
||||||
case DM_STATUS_MIRROR_FLUSH_FAILED:
|
|
||||||
log_error("%s device %u:%u flush failed.",
|
|
||||||
dev_type, major, minor);
|
|
||||||
*r = ME_FAILURE;
|
|
||||||
break;
|
|
||||||
case DM_STATUS_MIRROR_SYNC_FAILED:
|
|
||||||
log_error("%s device %u:%u sync failed.",
|
|
||||||
dev_type, major, minor);
|
|
||||||
break;
|
|
||||||
case DM_STATUS_MIRROR_READ_FAILED:
|
|
||||||
log_error("%s device %u:%u read failed.",
|
|
||||||
dev_type, major, minor);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
log_error("%s device %u:%u has failed (%c).",
|
|
||||||
dev_type, major, minor, (char)health);
|
|
||||||
*r = ME_FAILURE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _get_mirror_event(struct dso_state *state, char *params)
|
|
||||||
{
|
|
||||||
int r = ME_INSYNC;
|
|
||||||
unsigned i;
|
|
||||||
struct dm_status_mirror *ms;
|
|
||||||
|
|
||||||
if (!dm_get_status_mirror(state->mem, params, &ms)) {
|
|
||||||
log_error("Unable to parse mirror status string.");
|
|
||||||
return ME_IGNORE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check for bad mirror devices */
|
|
||||||
for (i = 0; i < ms->dev_count; ++i)
|
|
||||||
_process_status_code(ms->devs[i].health,
|
|
||||||
ms->devs[i].major, ms->devs[i].minor,
|
|
||||||
i ? "Secondary mirror" : "Primary mirror", &r);
|
|
||||||
|
|
||||||
/* Check for bad disk log device */
|
|
||||||
for (i = 0; i < ms->log_count; ++i)
|
|
||||||
_process_status_code(ms->logs[i].health,
|
|
||||||
ms->logs[i].major, ms->logs[i].minor,
|
|
||||||
"Log", &r);
|
|
||||||
|
|
||||||
/* Ignore if not in-sync */
|
|
||||||
if ((r == ME_INSYNC) && (ms->insync_regions != ms->total_regions))
|
|
||||||
r = ME_IGNORE;
|
|
||||||
|
|
||||||
dm_pool_free(state->mem, ms);
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _remove_failed_devices(const char *cmd_lvconvert, const char *device)
|
|
||||||
{
|
|
||||||
/* if repair goes OK, report success even if lvscan has failed */
|
|
||||||
if (!dmeventd_lvm2_run_with_lock(cmd_lvconvert)) {
|
|
||||||
log_error("Repair of mirrored device %s failed.", device);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
log_info("Repair of mirrored device %s finished successfully.", device);
|
|
||||||
|
|
||||||
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, TARGET_NAME_MIRROR)) {
|
|
||||||
log_info("%s has unmirrored portion.", device);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(_get_mirror_event(state, params)) {
|
|
||||||
case ME_INSYNC:
|
|
||||||
/* FIXME: all we really know is that this
|
|
||||||
_part_ of the device is in sync
|
|
||||||
Also, this is not an error
|
|
||||||
*/
|
|
||||||
log_notice("%s is now in-sync.", device);
|
|
||||||
break;
|
|
||||||
case ME_FAILURE:
|
|
||||||
log_error("Device failure in %s.", device);
|
|
||||||
if (!_remove_failed_devices(state->cmd_lvconvert, device))
|
|
||||||
/* FIXME Why are all the error return codes unused? Get rid of them? */
|
|
||||||
log_error("Failed to remove faulty devices in %s.",
|
|
||||||
device);
|
|
||||||
/* Should check before warning user that device is now linear
|
|
||||||
else
|
|
||||||
log_notice("%s is now a linear device.",
|
|
||||||
device);
|
|
||||||
*/
|
|
||||||
break;
|
|
||||||
case ME_IGNORE:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* FIXME Provide value then! */
|
|
||||||
log_warn("WARNING: %s received unknown event.", 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("mirror_state", state))
|
|
||||||
goto_bad;
|
|
||||||
|
|
||||||
/* CANNOT use --config as this disables cached content */
|
|
||||||
if (!dmeventd_lvm2_command(state->mem, state->cmd_lvconvert, sizeof(state->cmd_lvconvert),
|
|
||||||
"lvconvert --repair --use-policies", device))
|
|
||||||
goto_bad;
|
|
||||||
|
|
||||||
*user = state;
|
|
||||||
|
|
||||||
log_info("Monitoring mirror device %s for events.", device);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
bad:
|
|
||||||
log_error("Failed to monitor mirror %s.", device);
|
|
||||||
|
|
||||||
if (state)
|
|
||||||
dmeventd_lvm2_exit_with_pool(state);
|
|
||||||
|
|
||||||
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 mirror device %s for events.",
|
|
||||||
device);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
process_event
|
|
||||||
register_device
|
|
||||||
unregister_device
|
|
||||||
@@ -1,31 +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
srcdir = @srcdir@
|
|
||||||
top_srcdir = @top_srcdir@
|
|
||||||
top_builddir = @top_builddir@
|
|
||||||
|
|
||||||
CLDFLAGS += -L$(top_builddir)/daemons/dmeventd/plugins/lvm2
|
|
||||||
LIBS += -ldevmapper-event-lvm2
|
|
||||||
|
|
||||||
SOURCES = dmeventd_raid.c
|
|
||||||
|
|
||||||
LIB_NAME = libdevmapper-event-lvm2raid
|
|
||||||
LIB_SHARED = $(LIB_NAME).$(LIB_SUFFIX)
|
|
||||||
LIB_VERSION = $(LIB_VERSION_LVM)
|
|
||||||
|
|
||||||
include $(top_builddir)/make.tmpl
|
|
||||||
|
|
||||||
install_lvm2: install_dm_plugin
|
|
||||||
|
|
||||||
install: install_lvm2
|
|
||||||
@@ -1,189 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2005-2017 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "lib/misc/lib.h"
|
|
||||||
#include "daemons/dmeventd/plugins/lvm2/dmeventd_lvm.h"
|
|
||||||
#include "daemons/dmeventd/libdevmapper-event.h"
|
|
||||||
#include "lib/config/defaults.h"
|
|
||||||
|
|
||||||
/* Hold enough elements for the mximum number of RAID images */
|
|
||||||
#define RAID_DEVS_ELEMS ((DEFAULT_RAID_MAX_IMAGES + 63) / 64)
|
|
||||||
|
|
||||||
struct dso_state {
|
|
||||||
struct dm_pool *mem;
|
|
||||||
char cmd_lvconvert[512];
|
|
||||||
uint64_t raid_devs[RAID_DEVS_ELEMS];
|
|
||||||
int failed;
|
|
||||||
int warned;
|
|
||||||
};
|
|
||||||
|
|
||||||
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;
|
|
||||||
int dead = 0, r = 1;
|
|
||||||
uint32_t dev;
|
|
||||||
|
|
||||||
if (!dm_get_status_raid(state->mem, params, &status)) {
|
|
||||||
log_error("Failed to process status line for %s.", device);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
d = status->dev_health;
|
|
||||||
while ((d = strchr(d, 'D'))) {
|
|
||||||
dev = (uint32_t)(d - status->dev_health);
|
|
||||||
|
|
||||||
if (!(state->raid_devs[dev / 64] & (UINT64_C(1) << (dev % 64)))) {
|
|
||||||
state->raid_devs[dev / 64] |= (UINT64_C(1) << (dev % 64));
|
|
||||||
log_warn("WARNING: Device #%u of %s array, %s, has failed.",
|
|
||||||
dev, status->raid_type, device);
|
|
||||||
}
|
|
||||||
|
|
||||||
d++;
|
|
||||||
dead = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* if we are converting from non-RAID to RAID (e.g. linear -> raid1)
|
|
||||||
* and too many original devices die, such that we cannot continue
|
|
||||||
* the "recover" operation, the sync action will go to "idle", the
|
|
||||||
* unsynced devs will remain at 'a', and the original devices will
|
|
||||||
* NOT SWITCH TO 'D', but will remain at 'A' - hoping to be revived.
|
|
||||||
*
|
|
||||||
* This is simply the way the kernel works...
|
|
||||||
*/
|
|
||||||
if (!strcmp(status->sync_action, "idle") &&
|
|
||||||
(status->dev_health[0] == 'a') &&
|
|
||||||
(status->insync_regions < status->total_regions)) {
|
|
||||||
log_error("Primary sources for new RAID, %s, have failed.",
|
|
||||||
device);
|
|
||||||
dead = 1; /* run it through LVM repair */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dead) {
|
|
||||||
/*
|
|
||||||
* Use the first event to run a repair ignoring any additional ones.
|
|
||||||
*
|
|
||||||
* We presume lvconvert to do pre-repair
|
|
||||||
* checks to avoid bloat in this plugin.
|
|
||||||
*/
|
|
||||||
if (!state->warned && status->insync_regions < status->total_regions) {
|
|
||||||
state->warned = 1;
|
|
||||||
log_warn("WARNING: waiting for resynchronization to finish "
|
|
||||||
"before initiating repair on RAID device %s.", device);
|
|
||||||
/* Fall through to allow lvconvert to run. */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state->failed)
|
|
||||||
goto out; /* already reported */
|
|
||||||
|
|
||||||
state->failed = 1;
|
|
||||||
|
|
||||||
/* if repair goes OK, report success even if lvscan has failed */
|
|
||||||
if (!dmeventd_lvm2_run_with_lock(state->cmd_lvconvert)) {
|
|
||||||
log_error("Repair of RAID device %s failed.", device);
|
|
||||||
r = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
state->failed = 0;
|
|
||||||
if (status->insync_regions == status->total_regions)
|
|
||||||
memset(&state->raid_devs, 0, sizeof(state->raid_devs));
|
|
||||||
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 r;
|
|
||||||
}
|
|
||||||
|
|
||||||
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_lvconvert, sizeof(state->cmd_lvconvert),
|
|
||||||
"lvconvert --repair --use-policies", device))
|
|
||||||
goto_bad;
|
|
||||||
|
|
||||||
*user = state;
|
|
||||||
|
|
||||||
log_info("Monitoring RAID device %s for events.", device);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
bad:
|
|
||||||
log_error("Failed to monitor RAID %s.", device);
|
|
||||||
|
|
||||||
if (state)
|
|
||||||
dmeventd_lvm2_exit_with_pool(state);
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user