mirror of
git://sourceware.org/git/lvm2.git
synced 2025-11-30 04:23:48 +03:00
Compare commits
801 Commits
dev-bmr-dm
...
v2_02_141
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d05d7d974c | ||
|
|
bc8f8ac0fa | ||
|
|
136fd8f2f6 | ||
|
|
c0912af310 | ||
|
|
1f5dfb7369 | ||
|
|
d090d6574e | ||
|
|
dc388e0c7a | ||
|
|
55056c2d16 | ||
|
|
22810155a6 | ||
|
|
347575df1d | ||
|
|
c701d9cc8c | ||
|
|
fcbef05aae | ||
|
|
cc53a23d82 | ||
|
|
3e09f916b4 | ||
|
|
640c45d5a4 | ||
|
|
43b436398e | ||
|
|
21028a7903 | ||
|
|
7b5a8f61a7 | ||
|
|
b64703401d | ||
|
|
ca878a3426 | ||
|
|
178cbb580a | ||
|
|
4b9ae55a8d | ||
|
|
c99ca6f430 | ||
|
|
2da7525c83 | ||
|
|
509410bbbc | ||
|
|
2304286f68 | ||
|
|
c812c2dbc7 | ||
|
|
7f6a1e6bba | ||
|
|
2a4ef78c4a | ||
|
|
acf1e84e8c | ||
|
|
1341f83554 | ||
|
|
fccb1bb276 | ||
|
|
b160b73800 | ||
|
|
2ed324648e | ||
|
|
48f270970f | ||
|
|
6b3e402298 | ||
|
|
a3f484f812 | ||
|
|
6d7dc87cb3 | ||
|
|
5cd4d46f30 | ||
|
|
06346eab84 | ||
|
|
95ead96004 | ||
|
|
54b41dcd53 | ||
|
|
1ee6af344b | ||
|
|
7f62777041 | ||
|
|
0faa27d4f5 | ||
|
|
7559af2334 | ||
|
|
1752f5c31e | ||
|
|
e710bac03d | ||
|
|
b82d5ee092 | ||
|
|
6d09c8c2c4 | ||
|
|
88400b599e | ||
|
|
278c5509ee | ||
|
|
c9a813bff8 | ||
|
|
7d2b7f2bd8 | ||
|
|
2567d03e95 | ||
|
|
4310dfd4e1 | ||
|
|
ebcfd09ba9 | ||
|
|
753a496348 | ||
|
|
8857b22764 | ||
|
|
43897239b3 | ||
|
|
526297296f | ||
|
|
01228b692b | ||
|
|
9e9c757541 | ||
|
|
1b1f42b490 | ||
|
|
be1b1f3d89 | ||
|
|
63d59254d9 | ||
|
|
04d1a8a5e4 | ||
|
|
939d296525 | ||
|
|
9a81881965 | ||
|
|
1417ed304b | ||
|
|
d2d5c5e6c9 | ||
|
|
efab21b411 | ||
|
|
c66a83fdc3 | ||
|
|
84a9f750fe | ||
|
|
293abbb8d2 | ||
|
|
53b355a24b | ||
|
|
e168b5de75 | ||
|
|
7f74a99502 | ||
|
|
f1fe7af014 | ||
|
|
42fcbc1fd4 | ||
|
|
cdbf76b2f0 | ||
|
|
d50cd9d8d7 | ||
|
|
aae45a1f21 | ||
|
|
1bd83814ce | ||
|
|
9e336582f4 | ||
|
|
0c6946b4ce | ||
|
|
176b4aaebe | ||
|
|
1a3ee6402e | ||
|
|
d1e30ff0ba | ||
|
|
d09246a07d | ||
|
|
40701af969 | ||
|
|
d6cf83968c | ||
|
|
f03a21f5b8 | ||
|
|
a83d611a86 | ||
|
|
0dac4f09b4 | ||
|
|
04b82a8126 | ||
|
|
580c67486f | ||
|
|
8d11468ab2 | ||
|
|
4304a95dfd | ||
|
|
124b490fe6 | ||
|
|
796461a912 | ||
|
|
37bd35bc3d | ||
|
|
92e1422707 | ||
|
|
1be56e46c4 | ||
|
|
3e8126a66a | ||
|
|
4aa9e99a10 | ||
|
|
3e48354f2d | ||
|
|
07b9147ced | ||
|
|
7a4badc07f | ||
|
|
0688dbbc53 | ||
|
|
cd8e95d933 | ||
|
|
bf4b74c5eb | ||
|
|
dcb26b5f13 | ||
|
|
bdba4e7a93 | ||
|
|
dcd946e95a | ||
|
|
94dab390ef | ||
|
|
00bab9d9cd | ||
|
|
063b353b28 | ||
|
|
fedf15ffb0 | ||
|
|
748b8158b5 | ||
|
|
8b16efd17c | ||
|
|
45781161f4 | ||
|
|
c24d913c47 | ||
|
|
89418c1253 | ||
|
|
d2524315e6 | ||
|
|
e7978c5ab6 | ||
|
|
f40b3ba1e9 | ||
|
|
20acc66a23 | ||
|
|
20483ead5b | ||
|
|
c15c44a492 | ||
|
|
aec58c8620 | ||
|
|
3bbf89e9ec | ||
|
|
61573bd197 | ||
|
|
166adf0e1f | ||
|
|
67763a9bec | ||
|
|
5bbbd37f41 | ||
|
|
f7571eb287 | ||
|
|
ea74215fa1 | ||
|
|
3bcdf5d14b | ||
|
|
88cef47b18 | ||
|
|
1e43ec15ce | ||
|
|
aa4932674a | ||
|
|
4ff2583dc5 | ||
|
|
68e2ea11a3 | ||
|
|
86e7894ecc | ||
|
|
6336ef98d4 | ||
|
|
c717ea5fc0 | ||
|
|
fa87979004 | ||
|
|
46c8d6bb8a | ||
|
|
eb22f7c8f7 | ||
|
|
05ac836798 | ||
|
|
d3ca18e489 | ||
|
|
1f357532bb | ||
|
|
cd4d2cff97 | ||
|
|
b4a3aaf910 | ||
|
|
1fb8d746d6 | ||
|
|
ec647f1d43 | ||
|
|
4afe43e1a3 | ||
|
|
922fccc656 | ||
|
|
b7b59ad932 | ||
|
|
528695ec20 | ||
|
|
d582be43d4 | ||
|
|
1ea8afd3ca | ||
|
|
66c7fa4a44 | ||
|
|
4312b09635 | ||
|
|
d9faf85987 | ||
|
|
0285066e10 | ||
|
|
8d86c5db03 | ||
|
|
a220939d9e | ||
|
|
9243877ea1 | ||
|
|
5e50e5f0b4 | ||
|
|
6d6c233768 | ||
|
|
94c9453659 | ||
|
|
15be97d76b | ||
|
|
6ca5447e0c | ||
|
|
ddbf0075b1 | ||
|
|
fe64d3a2e2 | ||
|
|
c026846739 | ||
|
|
369bc264b0 | ||
|
|
da50f8bee6 | ||
|
|
795616a87b | ||
|
|
d1608345df | ||
|
|
6f002c29a5 | ||
|
|
2a23550cf3 | ||
|
|
0614c63579 | ||
|
|
0b2be60497 | ||
|
|
e2b00b0a89 | ||
|
|
0a2cadf6b8 | ||
|
|
7b11ef6de0 | ||
|
|
6167f5da10 | ||
|
|
83661c8f7f | ||
|
|
6e71d3fbde | ||
|
|
d8049dd17a | ||
|
|
011dd82050 | ||
|
|
121341e52c | ||
|
|
cad3568def | ||
|
|
51dfba002b | ||
|
|
931fede81b | ||
|
|
4d37db123d | ||
|
|
485d2ca945 | ||
|
|
d42cedae58 | ||
|
|
7d1c9e1d5a | ||
|
|
68c386cce7 | ||
|
|
4a984cabc4 | ||
|
|
920a281994 | ||
|
|
b6a45963e3 | ||
|
|
2a2487f02f | ||
|
|
5d4f5873a9 | ||
|
|
8ebf2b0611 | ||
|
|
0f4d96f1bd | ||
|
|
dccbc3b621 | ||
|
|
5a4676fea9 | ||
|
|
c3b292a4a9 | ||
|
|
193e7f5973 | ||
|
|
96d73dc6ea | ||
|
|
d4288c9bdf | ||
|
|
422c7474ca | ||
|
|
dd9a05b5ae | ||
|
|
376892ddf8 | ||
|
|
e31f4b76f4 | ||
|
|
d9295410e9 | ||
|
|
e425bce281 | ||
|
|
46193f4a59 | ||
|
|
970a428909 | ||
|
|
b2e13ac552 | ||
|
|
3089f5ab15 | ||
|
|
8d258c7df4 | ||
|
|
ea1814cea8 | ||
|
|
6dadebb1e4 | ||
|
|
1f2a42c7b7 | ||
|
|
70af08122e | ||
|
|
e0828e885b | ||
|
|
112c0592ad | ||
|
|
007be91e3d | ||
|
|
d74e1291cd | ||
|
|
0128770d6d | ||
|
|
43777b551d | ||
|
|
058725c721 | ||
|
|
1e729c47d2 | ||
|
|
b8779e706e | ||
|
|
f82e0210b7 | ||
|
|
6d0db97163 | ||
|
|
a45cc0fe14 | ||
|
|
59905100d1 | ||
|
|
fb59847a0f | ||
|
|
7ec61cd5b9 | ||
|
|
cd937efa77 | ||
|
|
d2d5191b78 | ||
|
|
a0cb92cbb1 | ||
|
|
6762eec88c | ||
|
|
45e749493c | ||
|
|
76b42901c0 | ||
|
|
b1215b7f8c | ||
|
|
d6767d753f | ||
|
|
c2d5cfbdb8 | ||
|
|
3db5ba08b1 | ||
|
|
6c331f3061 | ||
|
|
32762e2a9c | ||
|
|
e207ededd6 | ||
|
|
36ee367343 | ||
|
|
0b5a75c9af | ||
|
|
7103012754 | ||
|
|
ab4773671b | ||
|
|
e4c9b390ca | ||
|
|
84a9546869 | ||
|
|
5aae8de776 | ||
|
|
57c2a1ae8c | ||
|
|
846adadbcc | ||
|
|
22e19cb354 | ||
|
|
b1dab26be0 | ||
|
|
11151121aa | ||
|
|
c4c5635870 | ||
|
|
e262d5e596 | ||
|
|
9b9b5d0ea2 | ||
|
|
f6d2528f64 | ||
|
|
5ba219e87a | ||
|
|
04f76d9020 | ||
|
|
5c48ef993b | ||
|
|
2e04eee192 | ||
|
|
c542c18d2a | ||
|
|
07046e994f | ||
|
|
0c380c316c | ||
|
|
67b4761bc3 | ||
|
|
164d7e72bf | ||
|
|
4f8f8fcb52 | ||
|
|
856e11e11c | ||
|
|
fa1d730847 | ||
|
|
80c3fb786c | ||
|
|
3cadc1c87e | ||
|
|
84303dc17a | ||
|
|
f6c140e200 | ||
|
|
b1c4017743 | ||
|
|
18fd0bd20c | ||
|
|
b83a20b80a | ||
|
|
99def8f439 | ||
|
|
f66fe2c444 | ||
|
|
91bde0f4a1 | ||
|
|
297d6773af | ||
|
|
e90c5d2060 | ||
|
|
9df3069083 | ||
|
|
2c8d6f5c90 | ||
|
|
e1b111b02a | ||
|
|
8b857bfdc6 | ||
|
|
459b3db61e | ||
|
|
af6adec7cc | ||
|
|
a3f77ed4ba | ||
|
|
b9341e36f1 | ||
|
|
8096f2224c | ||
|
|
16780f6faa | ||
|
|
4103896ca0 | ||
|
|
d30105f471 | ||
|
|
19feda2c95 | ||
|
|
4e6377f5ba | ||
|
|
4b47ee5296 | ||
|
|
cf06d942b8 | ||
|
|
83d3cc76f3 | ||
|
|
89574055f7 | ||
|
|
7831a65091 | ||
|
|
15a97cc610 | ||
|
|
3f1c63c812 | ||
|
|
dd52721b68 | ||
|
|
7f125c1116 | ||
|
|
5b04eda93f | ||
|
|
77c31d0c39 | ||
|
|
baf320455b | ||
|
|
bb4d3fa7a7 | ||
|
|
3e18b101a0 | ||
|
|
df190dcfa5 | ||
|
|
e149fe7fdf | ||
|
|
77605457e7 | ||
|
|
0d5b1294f0 | ||
|
|
097d14e64e | ||
|
|
17196103e0 | ||
|
|
ccfc09f79b | ||
|
|
9a3b64e81a | ||
|
|
c2e88d1107 | ||
|
|
406d8ff332 | ||
|
|
00348c0a63 | ||
|
|
ccb8da404d | ||
|
|
28e54032c0 | ||
|
|
bca55c9b20 | ||
|
|
f104a81932 | ||
|
|
3720eb63be | ||
|
|
8b5525383f | ||
|
|
f58c634103 | ||
|
|
175119fdcd | ||
|
|
33a8a2febf | ||
|
|
f32f0bd2a7 | ||
|
|
99237f0908 | ||
|
|
099466939e | ||
|
|
b3c81d02c9 | ||
|
|
5886ff64eb | ||
|
|
a4418b34c1 | ||
|
|
65ec00ce20 | ||
|
|
6e1e0e8813 | ||
|
|
4159680a0e | ||
|
|
76cff10a73 | ||
|
|
1af2ab10d0 | ||
|
|
729f489009 | ||
|
|
5d76bdcdbd | ||
|
|
3b5939bbbb | ||
|
|
a2dd1f6e19 | ||
|
|
c301cc5d38 | ||
|
|
ba41ee1dc9 | ||
|
|
b702d67747 | ||
|
|
44ba862674 | ||
|
|
6624833839 | ||
|
|
b29593378f | ||
|
|
428ca9b120 | ||
|
|
f898cf7539 | ||
|
|
844b009584 | ||
|
|
9ef820a2a5 | ||
|
|
40eea582ae | ||
|
|
b780d329aa | ||
|
|
8f269697d2 | ||
|
|
98d81a43ea | ||
|
|
1a74171ca5 | ||
|
|
51735f09f7 | ||
|
|
3a42c13ccf | ||
|
|
8b965bd3d5 | ||
|
|
1a7bea0f0f | ||
|
|
b5b2a54834 | ||
|
|
21748a8630 | ||
|
|
e5b686d693 | ||
|
|
87a39d8bac | ||
|
|
cff1c728d8 | ||
|
|
2786cd27da | ||
|
|
1a2d0a0c72 | ||
|
|
b1319e0402 | ||
|
|
8be60e6a65 | ||
|
|
39cffa4e9b | ||
|
|
2af696c32f | ||
|
|
4284ba65eb | ||
|
|
aeec62ad19 | ||
|
|
12aa56d298 | ||
|
|
9156c5d088 | ||
|
|
466a1c72b7 | ||
|
|
81e9ab3156 | ||
|
|
15dbd4b56a | ||
|
|
e2ea2a8147 | ||
|
|
941c6354db | ||
|
|
02eb000f51 | ||
|
|
efc76ca33d | ||
|
|
590091a4fa | ||
|
|
9488cbdd0b | ||
|
|
fa9e41d2e3 | ||
|
|
6b0bc5b2d9 | ||
|
|
7ff5b03e5e | ||
|
|
91350f5c6a | ||
|
|
9c5c9e2355 | ||
|
|
cde12cbe9e | ||
|
|
ab6d16a8a5 | ||
|
|
09a62cca0c | ||
|
|
075f85dcb5 | ||
|
|
d2c4ce254b | ||
|
|
7b78d496bf | ||
|
|
19e272ba53 | ||
|
|
73e679f33f | ||
|
|
a0d819172f | ||
|
|
0aee04288e | ||
|
|
ef4d69f456 | ||
|
|
c15649b3af | ||
|
|
f67a52677b | ||
|
|
392248186e | ||
|
|
33465066c5 | ||
|
|
a5c4c4efbd | ||
|
|
83d475626a | ||
|
|
1ea7e2634d | ||
|
|
23d9b17a7b | ||
|
|
c3bfe07f2a | ||
|
|
508f0f5a21 | ||
|
|
df34fcdafd | ||
|
|
a6d1c8ac65 | ||
|
|
7c36d7c90c | ||
|
|
bbef4edd06 | ||
|
|
3f1a3b7090 | ||
|
|
a91fbe9d27 | ||
|
|
ccc39be053 | ||
|
|
0cf787a377 | ||
|
|
acc70de439 | ||
|
|
cf1c2da836 | ||
|
|
c4cc5eabfe | ||
|
|
8cc21354c2 | ||
|
|
2cb1f6eafe | ||
|
|
9322918406 | ||
|
|
83f00e9156 | ||
|
|
4f9e7f692e | ||
|
|
4b586ad3c2 | ||
|
|
256e432e78 | ||
|
|
51ff7d5ed8 | ||
|
|
49e11102c7 | ||
|
|
a11cd2ca2d | ||
|
|
f9926e7e6c | ||
|
|
76ea01dd20 | ||
|
|
362558cd66 | ||
|
|
09a8479cb7 | ||
|
|
0a633750f1 | ||
|
|
0e2261dbd1 | ||
|
|
842a7a17e3 | ||
|
|
f4fb97c850 | ||
|
|
8b9533f38f | ||
|
|
903e9af1b2 | ||
|
|
e261af52eb | ||
|
|
3f03d46fc1 | ||
|
|
0e27210308 | ||
|
|
13086c2523 | ||
|
|
42a9c8b4a6 | ||
|
|
e50583d721 | ||
|
|
c90363b585 | ||
|
|
915f0faac1 | ||
|
|
0641e3a5fd | ||
|
|
11a084cf42 | ||
|
|
d60794c3a3 | ||
|
|
1b1c01a27b | ||
|
|
72d700b064 | ||
|
|
86b04ebd19 | ||
|
|
7e1c08bb6a | ||
|
|
c7b4359ff4 | ||
|
|
5695c6aca6 | ||
|
|
5ac81657e5 | ||
|
|
5bd63df237 | ||
|
|
75420282e1 | ||
|
|
38df48d108 | ||
|
|
21a8ac0cd3 | ||
|
|
1f30ba6178 | ||
|
|
8733a8d890 | ||
|
|
5446d17756 | ||
|
|
c9ff5c8223 | ||
|
|
d99dd4086d | ||
|
|
09981afc1c | ||
|
|
3d03e504cd | ||
|
|
e04424e87e | ||
|
|
277dd0aa7a | ||
|
|
ded9452174 | ||
|
|
4b1cadbd87 | ||
|
|
2506275c3b | ||
|
|
5f7a94a03e | ||
|
|
df59db6048 | ||
|
|
b33d7586e7 | ||
|
|
fb957ef322 | ||
|
|
5e5d48348b | ||
|
|
26da6a3e10 | ||
|
|
4c2cc782aa | ||
|
|
05e7fdd5ce | ||
|
|
796e3fb7e4 | ||
|
|
867a36b419 | ||
|
|
a139275eca | ||
|
|
efcb3bbc8d | ||
|
|
309979d578 | ||
|
|
c805fa7c40 | ||
|
|
634bf8c953 | ||
|
|
be393f6722 | ||
|
|
d94ff20927 | ||
|
|
0173c260d8 | ||
|
|
9d815e5f5a | ||
|
|
7097663ddd | ||
|
|
eab099b221 | ||
|
|
3036620b48 | ||
|
|
d40830a2b1 | ||
|
|
028715b0f0 | ||
|
|
4a74e19f80 | ||
|
|
e773e71910 | ||
|
|
39a97d86f0 | ||
|
|
41fe225b0d | ||
|
|
1945a0f504 | ||
|
|
4e60e62444 | ||
|
|
96a6210198 | ||
|
|
192d9ad977 | ||
|
|
cb82919b0d | ||
|
|
28aff5d240 | ||
|
|
532b2d2d4e | ||
|
|
214e2cddf6 | ||
|
|
0ce150280e | ||
|
|
3a8a37187d | ||
|
|
629398d0f2 | ||
|
|
fd773dffb2 | ||
|
|
001f747963 | ||
|
|
2081071bee | ||
|
|
47f623d64b | ||
|
|
7e63364529 | ||
|
|
2e5bde4a77 | ||
|
|
cfe869692f | ||
|
|
a61f3c5316 | ||
|
|
ce80d73684 | ||
|
|
804c25a81a | ||
|
|
a54b4bba35 | ||
|
|
0a01c5aa36 | ||
|
|
f01b7afa19 | ||
|
|
ffa7b37b28 | ||
|
|
f61a394be4 | ||
|
|
c2ea5b3dee | ||
|
|
199697accf | ||
|
|
cb8f29d147 | ||
|
|
0e3042f488 | ||
|
|
f644431346 | ||
|
|
83a52c07b7 | ||
|
|
7d1dd5f52d | ||
|
|
330d584617 | ||
|
|
11d6f81316 | ||
|
|
f9c8cefd06 | ||
|
|
791e76ff70 | ||
|
|
e0d915a873 | ||
|
|
90ad817a43 | ||
|
|
5bc8c713e2 | ||
|
|
6c0b4a2769 | ||
|
|
afdae26c71 | ||
|
|
b5022102bb | ||
|
|
b7410c95cf | ||
|
|
fcfca57e2e | ||
|
|
0ac10bb23a | ||
|
|
a729b1aa29 | ||
|
|
548c09acfc | ||
|
|
2ce8ee0214 | ||
|
|
cee9ed2244 | ||
|
|
e7e15631dd | ||
|
|
ffeeb5c1e7 | ||
|
|
c356991fa8 | ||
|
|
e42ee69988 | ||
|
|
226e7d7b3c | ||
|
|
cd2e4310b3 | ||
|
|
fd3d795b93 | ||
|
|
729b035edd | ||
|
|
fda853b573 | ||
|
|
280a6275ce | ||
|
|
95b5d24f43 | ||
|
|
19443035a6 | ||
|
|
8b8103efef | ||
|
|
6bc3d72a65 | ||
|
|
854a559a49 | ||
|
|
18dfbbb150 | ||
|
|
0a26c20b88 | ||
|
|
0889cff5d5 | ||
|
|
9b8c876293 | ||
|
|
e94ab01940 | ||
|
|
54c982081f | ||
|
|
a631fa20d0 | ||
|
|
5911fa1d91 | ||
|
|
e1edb5676e | ||
|
|
3670f095c7 | ||
|
|
f11d690967 | ||
|
|
15ae237d2c | ||
|
|
36d16fed1f | ||
|
|
30e489db5e | ||
|
|
2296999cf6 | ||
|
|
d323acdfec | ||
|
|
81b0e9de7c | ||
|
|
587fd6a0e4 | ||
|
|
6cb7f21e38 | ||
|
|
8ff43c3705 | ||
|
|
026db90621 | ||
|
|
b77497cbd8 | ||
|
|
596ec5c74b | ||
|
|
0ec64370b2 | ||
|
|
d7f45ebca5 | ||
|
|
daa94eb792 | ||
|
|
5f990473e4 | ||
|
|
4bc7a86f3a | ||
|
|
ffbf12504d | ||
|
|
330cad1567 | ||
|
|
fa4d2ec241 | ||
|
|
acfc56957c | ||
|
|
3ba431e79e | ||
|
|
d62448cb45 | ||
|
|
1999e368f1 | ||
|
|
fc4f0d3fce | ||
|
|
9403edbb93 | ||
|
|
ab1b54c3e3 | ||
|
|
0f5933ecc1 | ||
|
|
e75b4bc2df | ||
|
|
36b09fd147 | ||
|
|
a26523330e | ||
|
|
2a022e9e6e | ||
|
|
fb12308416 | ||
|
|
f5a3b05c7a | ||
|
|
f868624f85 | ||
|
|
10ccbc5efa | ||
|
|
43d6b5b375 | ||
|
|
869c0bdeb8 | ||
|
|
c71af0895d | ||
|
|
b00ee99a21 | ||
|
|
55c13f3de4 | ||
|
|
9694854082 | ||
|
|
cdca2782d2 | ||
|
|
cebbb0feaf | ||
|
|
6240a7639d | ||
|
|
9e8b3d4a98 | ||
|
|
c27015368b | ||
|
|
5da497d0a8 | ||
|
|
dc261f17e9 | ||
|
|
ee8200f1c6 | ||
|
|
0a389691dc | ||
|
|
32d6ca9196 | ||
|
|
20e317cf92 | ||
|
|
2b9843c20b | ||
|
|
872ea3b987 | ||
|
|
df110bccbe | ||
|
|
a01eb9c451 | ||
|
|
81a9da8f61 | ||
|
|
a3c7e326c3 | ||
|
|
5ce334923f | ||
|
|
49b5022993 | ||
|
|
84d88cb2cf | ||
|
|
f09e4f7b10 | ||
|
|
0a73a5012a | ||
|
|
96dc03b337 | ||
|
|
d1d00fdeec | ||
|
|
00b610e542 | ||
|
|
fc35b6988d | ||
|
|
b86bd3b074 | ||
|
|
3414601788 | ||
|
|
d31c4e0bc1 | ||
|
|
031cd2bb0d | ||
|
|
3c0fc6f0da | ||
|
|
a0cf3d47f1 | ||
|
|
c4f3732c91 | ||
|
|
a9d954cb3c | ||
|
|
6e4f2da9b3 | ||
|
|
ab5df4bc5c | ||
|
|
7bbc128c3d | ||
|
|
cb57f4f89b | ||
|
|
8b6226997e | ||
|
|
f0b3e05add | ||
|
|
09b2649c5f | ||
|
|
cc17210bce | ||
|
|
e5d99cb9e6 | ||
|
|
3c1924c9c0 | ||
|
|
e4d5d05119 | ||
|
|
e3f1b1dccb | ||
|
|
fd238f3c0e | ||
|
|
58713d34dd | ||
|
|
32e22a0037 | ||
|
|
231b7df6cc | ||
|
|
521136181b | ||
|
|
fda19b55b1 | ||
|
|
de4db6a93b | ||
|
|
d797f4d590 | ||
|
|
a37fd93fbb | ||
|
|
8740b7cb77 | ||
|
|
746b1bcf2a | ||
|
|
34c956afc1 | ||
|
|
d0ff35c5a6 | ||
|
|
1307fafe0f | ||
|
|
9886fd236e | ||
|
|
a4fdfc098d | ||
|
|
cbe81ad393 | ||
|
|
8c09f12943 | ||
|
|
19ef3e0f31 | ||
|
|
463f59eca4 | ||
|
|
e4145ebc47 | ||
|
|
567189cc76 | ||
|
|
f4262026b6 | ||
|
|
82a27a85b5 | ||
|
|
ba898b9ab6 | ||
|
|
d827dd8b05 | ||
|
|
e53758c5f6 | ||
|
|
1f27c9f6a4 | ||
|
|
d310e1f907 | ||
|
|
81d4c4a84c | ||
|
|
1c811bfcd9 | ||
|
|
6d9e7d48fb | ||
|
|
c868609cff | ||
|
|
e4b9ac46d7 | ||
|
|
45f3e8bbef | ||
|
|
1fae121b22 | ||
|
|
180f92d3dc | ||
|
|
5476ee8655 | ||
|
|
3c396cf1e1 | ||
|
|
1ea1cb6dc9 | ||
|
|
8821cc416e | ||
|
|
92a4b5cc3c | ||
|
|
c0d6056870 | ||
|
|
23770214a9 | ||
|
|
386e91addb | ||
|
|
62a87c84ed | ||
|
|
ce2e60ab45 | ||
|
|
9c5a85ce24 | ||
|
|
c09dad71fb | ||
|
|
d08427030d | ||
|
|
7b570840cd | ||
|
|
c1bd76d6fc | ||
|
|
a7abade088 | ||
|
|
abb24370e9 | ||
|
|
6e1feb0f73 | ||
|
|
ef7264807f | ||
|
|
bc39506792 | ||
|
|
28b4fa3e27 | ||
|
|
b193809987 | ||
|
|
a8fd88463e | ||
|
|
3a3e17d603 | ||
|
|
40af31729f | ||
|
|
58f8f29c41 | ||
|
|
3d08a49790 | ||
|
|
55a9262bdb | ||
|
|
ba94d0f144 | ||
|
|
ae4db9f302 | ||
|
|
70db1d523d | ||
|
|
8e229cb7ea | ||
|
|
13d3eeb2ee | ||
|
|
dece918bc8 | ||
|
|
b091c37595 | ||
|
|
ca70770cfd | ||
|
|
5243a81c29 | ||
|
|
12acf852c5 | ||
|
|
074b5de771 | ||
|
|
69fa16048a | ||
|
|
b01e9651b0 | ||
|
|
8967776713 | ||
|
|
d1c65d1b28 | ||
|
|
be1db6b6c1 | ||
|
|
4227b2ebb4 | ||
|
|
15e20bb5c0 | ||
|
|
80bc87e377 | ||
|
|
77357081c8 | ||
|
|
4b28383b1c | ||
|
|
94c56559ca | ||
|
|
427d0a5e92 | ||
|
|
623b46a17d | ||
|
|
a606966029 | ||
|
|
79ea81b8a8 | ||
|
|
d4c024c836 | ||
|
|
b297d78367 | ||
|
|
4a6d5e2012 | ||
|
|
9d5cd4ca14 | ||
|
|
0b487802a0 | ||
|
|
f3891e90e3 | ||
|
|
0f3b81bb2e | ||
|
|
00ed523659 | ||
|
|
77fae3d852 | ||
|
|
16ff2d927f | ||
|
|
fc7a27bc3d | ||
|
|
666722324f | ||
|
|
bfb58b7e1c | ||
|
|
8852b25fc7 | ||
|
|
4d5b618d52 | ||
|
|
e6724f0303 | ||
|
|
37dd26e322 | ||
|
|
f10ad95c36 | ||
|
|
9b3dc72506 | ||
|
|
4534f0fbcf | ||
|
|
6a93206882 | ||
|
|
043fb32c4b |
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.
|
||||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|||||||
15
Makefile.in
15
Makefile.in
@@ -10,7 +10,7 @@
|
|||||||
#
|
#
|
||||||
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
srcdir = @srcdir@
|
srcdir = @srcdir@
|
||||||
top_srcdir = @top_srcdir@
|
top_srcdir = @top_srcdir@
|
||||||
@@ -131,6 +131,9 @@ rpm: dist
|
|||||||
generate: conf.generate
|
generate: conf.generate
|
||||||
$(MAKE) -C conf generate
|
$(MAKE) -C conf generate
|
||||||
|
|
||||||
|
all_man:
|
||||||
|
$(MAKE) -C man all_man
|
||||||
|
|
||||||
install_system_dirs:
|
install_system_dirs:
|
||||||
$(INSTALL_DIR) $(DESTDIR)$(DEFAULT_SYS_DIR)
|
$(INSTALL_DIR) $(DESTDIR)$(DEFAULT_SYS_DIR)
|
||||||
$(INSTALL_ROOT_DIR) $(DESTDIR)$(DEFAULT_ARCHIVE_DIR)
|
$(INSTALL_ROOT_DIR) $(DESTDIR)$(DEFAULT_ARCHIVE_DIR)
|
||||||
@@ -150,6 +153,9 @@ install_systemd_generators:
|
|||||||
install_systemd_units:
|
install_systemd_units:
|
||||||
$(MAKE) -C scripts install_systemd_units
|
$(MAKE) -C scripts install_systemd_units
|
||||||
|
|
||||||
|
install_all_man:
|
||||||
|
$(MAKE) -C man install_all_man
|
||||||
|
|
||||||
ifeq ("@PYTHON_BINDINGS@", "yes")
|
ifeq ("@PYTHON_BINDINGS@", "yes")
|
||||||
install_python_bindings:
|
install_python_bindings:
|
||||||
$(MAKE) -C liblvm/python install_python_bindings
|
$(MAKE) -C liblvm/python install_python_bindings
|
||||||
@@ -226,10 +232,9 @@ endif
|
|||||||
|
|
||||||
ifneq ($(shell which ctags),)
|
ifneq ($(shell which ctags),)
|
||||||
.PHONY: tags
|
.PHONY: tags
|
||||||
all: tags
|
|
||||||
tags:
|
tags:
|
||||||
test -z "$(shell find $(top_srcdir) -type f -name '*.[ch]' -newer tags | head -1)" || $(RM) tags
|
test -z "$(shell find $(top_srcdir) -type f -name '*.[ch]' -newer tags 2>/dev/null | head -1)" || $(RM) tags
|
||||||
test -f tags || find $(top_srcdir) -maxdepth 4 -type f -name '*.[ch]' -exec ctags -a '{}' +
|
test -f tags || find $(top_srcdir) -maxdepth 5 -type f -name '*.[ch]' -exec ctags -a '{}' +
|
||||||
|
|
||||||
DISTCLEAN_TARGETS += tags
|
CLEAN_TARGETS += tags
|
||||||
endif
|
endif
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
1.02.105-git (2015-08-10)
|
1.02.115-git (2016-01-25)
|
||||||
|
|||||||
172
WHATS_NEW
172
WHATS_NEW
@@ -1,9 +1,173 @@
|
|||||||
Version 2.02.128 -
|
Version 2.02.141 - 25th January 2016
|
||||||
|
====================================
|
||||||
|
Add metadata/check_pv_device_sizes switch to lvm.conf for device size checks.
|
||||||
|
Warn if device size is less than corresponding PV size in metadata.
|
||||||
|
Cache device sizes internally.
|
||||||
|
Restore support for command breaking in process_each_lv_in_vg() (2.02.118).
|
||||||
|
Use correct mempool when process_each_lv_in_vg() (2.02.118).
|
||||||
|
Fix lvm.8 man to show again prohibited suffixes.
|
||||||
|
Fix configure to set proper use_blkid_wiping if autodetected as disabled.
|
||||||
|
Initialise udev in clvmd for use in device scanning. (2.02.116)
|
||||||
|
Add seg_le_ranges report field for common format when displaying seg devices.
|
||||||
|
Honour report/list_item_separator for seg_metadata_le_ranges report field.
|
||||||
|
Don't mark hidden devs in -o devices,metadata_devices,seg_pe_ranges.(2.02.140)
|
||||||
|
Change LV sizes in seg_pe_ranges report field to match underlying devices.
|
||||||
|
Add kernel_cache_settings report field for cache LV settings used in kernel.
|
||||||
|
|
||||||
|
Version 2.02.140 - 16th January 2016
|
||||||
|
====================================
|
||||||
|
Fix lvm2app to return either 0 or 1 for lvm_vg_is_{clustered,exported}.
|
||||||
|
Add kernel_discards report field to display thin pool discard used in kernel.
|
||||||
|
Correct checking of target presence when driver access is disabled.
|
||||||
|
Eval poolmetadatasize arg earlier in lvresize.
|
||||||
|
Fix vgcfgrestore to respect allocatable attribute of PVs.
|
||||||
|
Add report/mark_hidden_devices to lvm.conf.
|
||||||
|
Use brackets consistently in report fields to mark hidden devices.
|
||||||
|
Restore background polling processing during auto-activation (2.02.119).
|
||||||
|
Fix invalid memory read when reporting cache LV policy_name (2.02.126).
|
||||||
|
|
||||||
|
Version 2.02.139 - 8th January 2016
|
||||||
===================================
|
===================================
|
||||||
|
Update lvmlockd with the new VG seqno before devices are suspended.
|
||||||
|
Rework vgrename to use the common processing code in toollib.
|
||||||
|
Make pvs show new devices on the system since the last .cache update.
|
||||||
|
Document F,D and M thin pool health status chars for lv_attr in lvs man page.
|
||||||
|
Also add lvm2-activation{-early,-net}.service systemd status for lvmdump -s.
|
||||||
|
|
||||||
|
Version 2.02.138 - 14th December 2015
|
||||||
|
=====================================
|
||||||
|
Support lvrename for hidden (used) cache pools.
|
||||||
|
Fix lvrename for stacked cache pools.
|
||||||
|
|
||||||
|
Version 2.02.137 - 5th December 2015
|
||||||
|
====================================
|
||||||
|
Restore archiving before changing metadata in vgextend (2.02.117).
|
||||||
|
Dropped internal usage of log_suppress(2).
|
||||||
|
Cleaned logging code for buffer size usage.
|
||||||
|
Added internal id_read_format_try() function to check and read valid UUID.
|
||||||
|
Change lvcreate, lvrename, lvresize to use process_each_vg.
|
||||||
|
Change process_each_vg to handle single VG as separate arg.
|
||||||
|
Issue error if ambiguous VG name is supplied in most commands.
|
||||||
|
Make process_each fns always work through full list of known VG names.
|
||||||
|
Use dm_get_status_mirror() instead of individual parsers.
|
||||||
|
Add mem pool arg for check_transient_status() target function.
|
||||||
|
Avoid misleading error with -m is omitted with lvconvert to raid types.
|
||||||
|
Add system_id to vginfo cache.
|
||||||
|
|
||||||
|
Version 2.02.136 - 28th November 2015
|
||||||
|
=====================================
|
||||||
|
Add new --sinceversion option for lvmconfig --type new.
|
||||||
|
Fix inactive table loaded for wrapping thin-pool when resizing it.
|
||||||
|
Extend the list of ignored libraries when locking memory.
|
||||||
|
|
||||||
|
Version 2.02.135 - 23rd November 2015
|
||||||
|
=====================================
|
||||||
|
Add a model file for Coverity.
|
||||||
|
Show correct error message for unsupported yet cache pool repair.
|
||||||
|
Allow lvconvert cache pools' data and metadata LV to raid.
|
||||||
|
Fix reading of old metadata with missing cache policy or mode settings.
|
||||||
|
Issue error if external_device_info_source=udev and udev db record incomplete.
|
||||||
|
Update lvmetad duplicate VG name handling to use hash function extensions.
|
||||||
|
Detect invalid vgrenames by vgid where the name is unchanged.
|
||||||
|
Fix passing of 32bit values through daemons (mostly lvmlockd).
|
||||||
|
Use local memory pool for whole alloc_handle manipulation.
|
||||||
|
Add missing pointer validation after dm_get_next_target().
|
||||||
|
Do not deref NULL pointer in debug message for _match_pv_tags().
|
||||||
|
Drop unneeded stat() call when checking for sysfs file.
|
||||||
|
Fix memory leak on error path of failing thin-pool percentage check.
|
||||||
|
Add missing test for failing node allocation in lvmetad.
|
||||||
|
Correct configure messages when enabling/disabling lvmlockd.
|
||||||
|
|
||||||
|
Version 2.02.134 - 9th November 2015
|
||||||
|
====================================
|
||||||
|
Refactor some lvmetad code and adjust some duplicate PV messages.
|
||||||
|
No longer repair/wipe VG/PVs if inaccessible because foreign or shared.
|
||||||
|
Pass correct data size to mirror log calc so log can be bigger than 1 extent.
|
||||||
|
|
||||||
|
Version 2.02.133 - 30th October 2015
|
||||||
|
====================================
|
||||||
|
Support repeated -o|--options for reporting commands.
|
||||||
|
Support -o- and -o# for reporting commands to remove and compact fields.
|
||||||
|
Fix missing PVs from pvs output if vgremove is run concurrently.
|
||||||
|
Remove unwanted error message when running pvs/vgs/lvs and vgremove at once.
|
||||||
|
Check newly created VG's metadata do not overlap in metadata ring buffer.
|
||||||
|
Check metadata area size is at least the minimum size defined for the format.
|
||||||
|
Thin pool targets uses low_water_mark from profile.
|
||||||
|
Dropping 'yet' from error of unsupported thick snapshot of snapshots.
|
||||||
|
Do not support unpartitioned DASD devices with CDL formatted with pvcreate.
|
||||||
|
For thins use flush for suspend only when volume size is reduced.
|
||||||
|
Enable code which detects the need of flush during suspend.
|
||||||
|
Ensure --use-policy will resize volume to fit below threshold.
|
||||||
|
Correct percentage evaluation when checking thin-pool over threshold.
|
||||||
|
Fix lvmcache to move PV from VG to orphans if VG is removed and lvmetad used.
|
||||||
|
Fix lvmcache to not cache even invalid info about PV which got removed.
|
||||||
|
Support checking of memlock daemon counter.
|
||||||
|
Allow all log levels to be used with the lvmetad -l option.
|
||||||
|
Add optional shutdown when idle support for lvmetad.
|
||||||
|
Fix missing in-sync progress info while lvconvert used with lvmpolld.
|
||||||
|
Add report/compact_output_cols to lvm.conf to define report cols to compact.
|
||||||
|
Do not change logging in lvm2 library when it's already set.
|
||||||
|
Check for enough space in thin-pool in command before creating new thin.
|
||||||
|
Make libblkid detect all copies of the same signature if use_blkid_wiping=1.
|
||||||
|
Fix vgimportclone with -n to not add number unnecessarily to base VG name.
|
||||||
|
Cleanup vgimportclone script and remove dependency on awk, grep, cut and tr.
|
||||||
|
Add vg_missing_pv_count report field to report number of missing PVs in a VG.
|
||||||
|
Properly identify internal LV holding sanlock locks within lv_role field.
|
||||||
|
Add metadata_devices and seg_metadata_le_ranges report fields for raid vols.
|
||||||
|
Fix lvm2-{activation,clvmd,cmirrord,monitor} service to exec before mounting.
|
||||||
|
|
||||||
|
Version 2.02.132 - 22nd September 2015
|
||||||
|
======================================
|
||||||
|
Fix lvmconf to set locking_type=2 if external locking library is requested.
|
||||||
|
Remove verbose message when rescanning an unchanged device. (2.02.119)
|
||||||
|
Add origin_uuid, mirror_log_uuid, move_pv_uuid, convert_lv_uuid report fields.
|
||||||
|
Add pool_lv_uuid, metadata_lv_uuid, data_lv_uuid reporting fields.
|
||||||
|
Fix PV label processing failure after pvcreate in lvm shell with lvmetad.
|
||||||
|
|
||||||
|
Version 2.02.131 - 15th September 2015
|
||||||
|
======================================
|
||||||
|
Rename 'make install_full_man' to install_all_man and add all_man target.
|
||||||
|
Fix vgimportclone cache_dir path name (2.02.115).
|
||||||
|
Swapping of LV identifiers handles more complex LVs.
|
||||||
|
Use passed list of PVS when allocating space in lvconvert --thinpool.
|
||||||
|
Disallow usage of --stripe and --stripesize when creating cache pool.
|
||||||
|
Warn user when caching raid or thin pool data LV.
|
||||||
|
When layering LV, move LV flags with segments.
|
||||||
|
Ignore persistent cache if configuration changed. (2.02.127)
|
||||||
|
Fix devices/filter to be applied before disk-accessing filters. (2.02.112)
|
||||||
|
Make tags only when requested via 'make tags'.
|
||||||
|
Configure supports --disable-dependency-tracking for one-time builds.
|
||||||
|
Fix usage of configure.h when building in srcdir != builddir.
|
||||||
|
|
||||||
|
Version 2.02.130 - 5th September 2015
|
||||||
|
=====================================
|
||||||
|
Fix use of uninitialized device status if reading outdated .cache record.
|
||||||
|
Restore support for --monitor option in lvcreate (2.02.112).
|
||||||
|
Read thin-pool data and metadata percent without flush.
|
||||||
|
Detect blocked thin-pool and avoid scanning their thin volumes.
|
||||||
|
Check if dm device is usable before checking its size (2.02.116).
|
||||||
|
Extend parsing of cache_check version in configure.
|
||||||
|
Make lvpoll error messages visible in lvmpolld's stderr and in syslog.
|
||||||
|
Add 'make install_full_man' to install all man pages regardless of config.
|
||||||
|
|
||||||
|
Version 2.02.129 - 26th August 2015
|
||||||
|
===================================
|
||||||
|
Drop error message when vgdisplay encounters an exported VG. (2.02.27)
|
||||||
|
Fix shared library generation to stop exporting internal functions.(2.02.120)
|
||||||
|
Accept --cachemode with lvconvert.
|
||||||
|
Fix and improve reporting properties of cache-pool.
|
||||||
|
Enable usage of --cachepolicy and --cachesetting with lvconvert.
|
||||||
|
Don't allow to reduce size of thin-pool metadata.
|
||||||
|
Fix debug buffer overflows in cmirrord logging.
|
||||||
|
Add --foreground and --help to cmirrord.
|
||||||
|
|
||||||
|
Version 2.02.128 - 17th August 2015
|
||||||
|
===================================
|
||||||
|
Allocation setting cache_pool_cachemode is replaced by cache_mode.
|
||||||
|
Don't attempt to close config file that couldn't be opened.
|
||||||
Check for valid cache mode in validation of cache segment.
|
Check for valid cache mode in validation of cache segment.
|
||||||
Enhance internal API cache_set_mode() and cache_set_policy().
|
Change internal interface handling cache mode and policy.
|
||||||
Enhance toollib's get_cache_params().
|
When no cache policy specified, prefer smq (if available) over mq.
|
||||||
Runtime detect presence of cache smq policy.
|
|
||||||
Add demo cache-mq and cache-smq profiles.
|
Add demo cache-mq and cache-smq profiles.
|
||||||
Add cmd profilable allocation/cache_policy,cache_settings,cache_mode.
|
Add cmd profilable allocation/cache_policy,cache_settings,cache_mode.
|
||||||
Require cache_check 0.5.4 for use of --clear-needs-check-flag.
|
Require cache_check 0.5.4 for use of --clear-needs-check-flag.
|
||||||
|
|||||||
104
WHATS_NEW_DM
104
WHATS_NEW_DM
@@ -1,5 +1,107 @@
|
|||||||
Version 1.02.105 -
|
Version 1.02.115 - 25th January 2016
|
||||||
|
====================================
|
||||||
|
Fix man page for dmsetup udevcreatecookie.
|
||||||
|
|
||||||
|
Version 1.02.114 - 14th December 2015
|
||||||
|
=====================================
|
||||||
|
Better support for dmsetup static linkage.
|
||||||
|
Extend validity checks on dmeventd client socket.
|
||||||
|
|
||||||
|
Version 1.02.113 - 5th December 2015
|
||||||
|
====================================
|
||||||
|
Mirror plugin in dmeventd uses dm_get_status_mirror().
|
||||||
|
Add dm_get_status_mirror() for parsing mirror status line.
|
||||||
|
|
||||||
|
Version 1.02.112 - 28th November 2015
|
||||||
|
=====================================
|
||||||
|
Show error message when trying to create unsupported raid type.
|
||||||
|
Improve preloading sequence of an active thin-pool target.
|
||||||
|
Drop extra space from cache target line to fix unneded table reloads.
|
||||||
|
|
||||||
|
Version 1.02.111 - 23rd November 2015
|
||||||
|
=====================================
|
||||||
|
Extend dm_hash to support multiple values with the same key.
|
||||||
|
Add missing check for allocation inside dm_split_lvm_name().
|
||||||
|
Test dm_task_get_message_response for !NULL in dm_stats_print_region().
|
||||||
|
Add checks for failing dm_stats_create() in dmsetup.
|
||||||
|
Add missing fifo close when failed to initialize client connection.
|
||||||
|
|
||||||
|
Version 1.02.110 - 30th October 2015
|
||||||
|
====================================
|
||||||
|
Disable thin monitoring plugin when it fails too often (>10 times).
|
||||||
|
Fix/restore parsing of empty field '-' when processing dmeventd event.
|
||||||
|
Enhance dm_tree_node_size_changed() to recognize size reduction.
|
||||||
|
Support exit on idle for dmenventd (1 hour).
|
||||||
|
Add support to allow unmonitor device from plugin itself.
|
||||||
|
New design for thread co-operation in dmeventd.
|
||||||
|
Dmeventd read device status with 'noflush'.
|
||||||
|
Dmeventd closes control device when no device is monitored.
|
||||||
|
Thin plugin for dmeventd improved percentage usage.
|
||||||
|
Snapshot plugin for dmeventd improved percentage usage.
|
||||||
|
Add dm_hold_control_dev to allow holding of control device open.
|
||||||
|
Add dm_report_compact_given_fields to remove given empty fields from report.
|
||||||
|
Use libdm status parsing and local mem raid dmeventd plugin.
|
||||||
|
Use local mem pool and lock only lvm2 execution for mirror dmeventd plugin.
|
||||||
|
Lock protect only lvm2 execution for snapshot and thin dmeventd plugin.
|
||||||
|
Use local mempool for raid and mirror plugins.
|
||||||
|
Reworked thread initialization for dmeventd plugins.
|
||||||
|
Dmeventd handles snapshot overflow for now equally as invalid.
|
||||||
|
Convert dmeventd to use common logging macro system from libdm.
|
||||||
|
Return -ENOMEM when device registration fails instead of 0 (=success).
|
||||||
|
Enforce writethrough mode for cleaner policy.
|
||||||
|
Add support for recognition and deactivation of MD devices to blkdeactivate.
|
||||||
|
Move target status functions out of libdm-deptree.
|
||||||
|
Correct use of max_write_behind parameter when generating raid target line.
|
||||||
|
Fix dm-event systemd service to make sure it is executed before mounting.
|
||||||
|
|
||||||
|
Version 1.02.109 - 22nd September 2016
|
||||||
|
======================================
|
||||||
|
Update man pages for dmsetup and dmstats.
|
||||||
|
Improve help text for dmsetup.
|
||||||
|
Use --noflush and --nolockfs when removing device with --force.
|
||||||
|
Parse new Overflow status string for snapshot target.
|
||||||
|
Check dir path components are valid if using dm_create_dir, error out if not.
|
||||||
|
Fix /dev/mapper handling to remove dangling entries if symlinks are found.
|
||||||
|
Make it possible to use blank value as selection for string list report field.
|
||||||
|
|
||||||
|
Version 1.02.108 - 15th September 2015
|
||||||
|
======================================
|
||||||
|
Do not check for full thin pool when activating without messages (1.02.107).
|
||||||
|
|
||||||
|
Version 1.02.107 - 5th September 2015
|
||||||
|
=====================================
|
||||||
|
Parse thin-pool status with one single routine internally.
|
||||||
|
Add --histogram to select default histogram fields for list and report.
|
||||||
|
Add report fields for displaying latency histogram configuration and data.
|
||||||
|
Add dmstats --bounds to specify histogram boundaries for a new region.
|
||||||
|
Add dm_histogram_to_string() to format histogram data in string form.
|
||||||
|
Add public methods to libdm to access numerical histogram config and data.
|
||||||
|
Parse and store histogram data in dm_stats_list() and dm_stats_populate().
|
||||||
|
Add an argument to specify histogram bounds to dm_stats_create_region().
|
||||||
|
Add dm_histogram_bounds_from_{string,uint64_t}() to parse histogram bounds.
|
||||||
|
Add dm_histogram handle type to represent a latency histogram and its bounds.
|
||||||
|
Fix devmapper.pc pkgconfig file to not reference non-existent rt.pc file.
|
||||||
|
Reinstate dm_task_get_info@Base to libdevmapper exports. (1.02.106)
|
||||||
|
|
||||||
|
Version 1.02.106 - 26th August 2015
|
||||||
===================================
|
===================================
|
||||||
|
Add 'precise' column to statistics reports.
|
||||||
|
Add --precise switch to 'dmstats create' to request nanosecond counters.
|
||||||
|
Add precise argument to dm_stats_create_region().
|
||||||
|
Add support to libdm-stats for precise_timestamps
|
||||||
|
|
||||||
|
Version 1.02.105 - 17th August 2015
|
||||||
|
===================================
|
||||||
|
Fix 'dmstats list -o all' segfault.
|
||||||
|
Separate dmstats statistics fields from region information fields.
|
||||||
|
Add interval and interval_ns fields to dmstats reports.
|
||||||
|
Do not include internal glibc headers in libdm-timestamp.c (1.02.104)
|
||||||
|
Exit immediately if no device is supplied to dmsetup wipe_table.
|
||||||
|
Suppress dmsetup report headings when no data is output. (1.02.104)
|
||||||
|
Adjust dmsetup usage/help output selection to match command invoked.
|
||||||
|
Fix dmsetup -o all to select correct fields in splitname report.
|
||||||
|
Restructure internal dmsetup argument handling across all commands.
|
||||||
|
Add dm_report_is_empty() to indicate there is no data awaiting output.
|
||||||
Add more arg validation for dm_tree_node_add_cache_target().
|
Add more arg validation for dm_tree_node_add_cache_target().
|
||||||
Add --alldevices switch to replace use of --force for stats create / delete.
|
Add --alldevices switch to replace use of --force for stats create / delete.
|
||||||
|
|
||||||
|
|||||||
2
aclocal.m4
vendored
2
aclocal.m4
vendored
@@ -29,7 +29,7 @@ m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun
|
|||||||
#
|
#
|
||||||
# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
#
|
#
|
||||||
# As a special exception to the GNU General Public License, if you
|
# As a special exception to the GNU General Public License, if you
|
||||||
# distribute this file as part of a program that contains a
|
# distribute this file as part of a program that contains a
|
||||||
|
|||||||
2
conf/.gitignore
vendored
2
conf/.gitignore
vendored
@@ -2,3 +2,5 @@ command_profile_template.profile
|
|||||||
example.conf
|
example.conf
|
||||||
lvmlocal.conf
|
lvmlocal.conf
|
||||||
metadata_profile_template.profile
|
metadata_profile_template.profile
|
||||||
|
configure.h
|
||||||
|
lvm-version.h
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
#
|
#
|
||||||
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
srcdir = @srcdir@
|
srcdir = @srcdir@
|
||||||
top_srcdir = @top_srcdir@
|
top_srcdir = @top_srcdir@
|
||||||
|
|||||||
@@ -11,14 +11,22 @@
|
|||||||
# Refer to 'man lvm.conf' for further information about profiles and
|
# Refer to 'man lvm.conf' for further information about profiles and
|
||||||
# general configuration file layout.
|
# general configuration file layout.
|
||||||
#
|
#
|
||||||
|
allocation {
|
||||||
|
cache_mode="writethrough"
|
||||||
|
cache_settings {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
global {
|
global {
|
||||||
units="h"
|
units="h"
|
||||||
si_unit_consistency=1
|
si_unit_consistency=1
|
||||||
suffix=1
|
suffix=1
|
||||||
lvdisplay_shows_full_device_path=0
|
lvdisplay_shows_full_device_path=0
|
||||||
}
|
}
|
||||||
|
|
||||||
report {
|
report {
|
||||||
compact_output=0
|
compact_output=0
|
||||||
|
compact_output_cols=""
|
||||||
aligned=1
|
aligned=1
|
||||||
buffered=1
|
buffered=1
|
||||||
headings=1
|
headings=1
|
||||||
@@ -28,6 +36,7 @@ report {
|
|||||||
quoted=1
|
quoted=1
|
||||||
colums_as_rows=0
|
colums_as_rows=0
|
||||||
binary_values_as_numeric=0
|
binary_values_as_numeric=0
|
||||||
|
time_format="%Y-%m-%d %T %z"
|
||||||
devtypes_sort="devtype_name"
|
devtypes_sort="devtype_name"
|
||||||
devtypes_cols="devtype_name,devtype_max_partitions,devtype_description"
|
devtypes_cols="devtype_name,devtype_max_partitions,devtype_description"
|
||||||
devtypes_cols_verbose="devtype_name,devtype_max_partitions,devtype_description"
|
devtypes_cols_verbose="devtype_name,devtype_max_partitions,devtype_description"
|
||||||
@@ -46,4 +55,5 @@ report {
|
|||||||
pvsegs_sort="pv_name,pvseg_start"
|
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="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"
|
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"
|
||||||
|
mark_hidden_devices=1
|
||||||
}
|
}
|
||||||
|
|||||||
1664
conf/example.conf.in
1664
conf/example.conf.in
File diff suppressed because it is too large
Load Diff
@@ -24,34 +24,33 @@ local {
|
|||||||
|
|
||||||
# Configuration option local/system_id.
|
# Configuration option local/system_id.
|
||||||
# Defines the local system ID for lvmlocal mode.
|
# Defines the local system ID for lvmlocal mode.
|
||||||
# This is used when global/system_id_source is set
|
# This is used when global/system_id_source is set to 'lvmlocal' in the
|
||||||
# to 'lvmlocal' in the main configuration file,
|
# main configuration file, e.g. lvm.conf. When used, it must be set to
|
||||||
# e.g. lvm.conf.
|
# a unique value among all hosts sharing access to the storage,
|
||||||
# When used, it must be set to a unique value
|
|
||||||
# among all hosts sharing access to the storage,
|
|
||||||
# e.g. a host name.
|
# e.g. a host name.
|
||||||
# Example:
|
#
|
||||||
# Set no system ID.
|
# Example
|
||||||
|
# Set no system ID:
|
||||||
# system_id = ""
|
# system_id = ""
|
||||||
# Example:
|
# Set the system_id to a specific name:
|
||||||
# Set the system_id to the string 'host1'.
|
|
||||||
# system_id = "host1"
|
# system_id = "host1"
|
||||||
|
#
|
||||||
|
# This configuration option has an automatic default value.
|
||||||
# system_id = ""
|
# system_id = ""
|
||||||
|
|
||||||
# Configuration option local/extra_system_ids.
|
# Configuration option local/extra_system_ids.
|
||||||
# A list of extra VG system IDs the local host can access.
|
# A list of extra VG system IDs the local host can access.
|
||||||
# VGs with the system IDs listed here (in addition
|
# VGs with the system IDs listed here (in addition to the host's own
|
||||||
# to the host's own system ID) can be fully accessed
|
# system ID) can be fully accessed by the local host. (These are
|
||||||
# by the local host. (These are system IDs that the
|
# system IDs that the host sees in VGs, not system IDs that identify
|
||||||
# host sees in VGs, not system IDs that identify the
|
# the local host, which is determined by system_id_source.)
|
||||||
# local host, which is determined by system_id_source.)
|
# Use this only after consulting 'man lvmsystemid' to be certain of
|
||||||
# Use this only after consulting 'man lvmsystemid'
|
# correct usage and possible dangers.
|
||||||
# to be certain of correct usage and possible dangers.
|
|
||||||
# This configuration option does not have a default value defined.
|
# This configuration option does not have a default value defined.
|
||||||
|
|
||||||
# Configuration option local/host_id.
|
# Configuration option local/host_id.
|
||||||
# The lvmlockd sanlock host_id.
|
# The lvmlockd sanlock host_id.
|
||||||
# This must be a unique among all hosts,
|
# This must be unique among all hosts, and must be between 1 and 2000.
|
||||||
# and must be between 1 and 2000.
|
# This configuration option has an automatic default value.
|
||||||
# host_id = 0
|
# host_id = 0
|
||||||
}
|
}
|
||||||
|
|||||||
160
configure
vendored
160
configure
vendored
@@ -643,6 +643,7 @@ LVMETAD_PIDFILE
|
|||||||
DMEVENTD_PIDFILE
|
DMEVENTD_PIDFILE
|
||||||
WRITE_INSTALL
|
WRITE_INSTALL
|
||||||
VALGRIND_POOL
|
VALGRIND_POOL
|
||||||
|
USE_TRACKING
|
||||||
UDEV_HAS_BUILTIN_BLKID
|
UDEV_HAS_BUILTIN_BLKID
|
||||||
UDEV_RULE_EXEC_DETECTION
|
UDEV_RULE_EXEC_DETECTION
|
||||||
UDEV_SYSTEMD_BACKGROUND_JOBS
|
UDEV_SYSTEMD_BACKGROUND_JOBS
|
||||||
@@ -659,12 +660,13 @@ SELINUX_PC
|
|||||||
SELINUX_LIBS
|
SELINUX_LIBS
|
||||||
REPLICATORS
|
REPLICATORS
|
||||||
READLINE_LIBS
|
READLINE_LIBS
|
||||||
RT_PC
|
RT_LIB
|
||||||
RAID
|
RAID
|
||||||
PYTHON_LIBDIRS
|
PYTHON_LIBDIRS
|
||||||
PYTHON_INCDIRS
|
PYTHON_INCDIRS
|
||||||
PYTHON_BINDINGS
|
PYTHON_BINDINGS
|
||||||
PTHREAD_LIBS
|
PTHREAD_LIBS
|
||||||
|
M_LIBS
|
||||||
POOL
|
POOL
|
||||||
PKGCONFIG
|
PKGCONFIG
|
||||||
OCFDIR
|
OCFDIR
|
||||||
@@ -692,7 +694,6 @@ BLKDEACTIVATE
|
|||||||
FSADM
|
FSADM
|
||||||
ELDFLAGS
|
ELDFLAGS
|
||||||
DM_LIB_PATCHLEVEL
|
DM_LIB_PATCHLEVEL
|
||||||
DM_LIB_VERSION
|
|
||||||
DMEVENTD_PATH
|
DMEVENTD_PATH
|
||||||
DMEVENTD
|
DMEVENTD
|
||||||
DL_LIBS
|
DL_LIBS
|
||||||
@@ -875,6 +876,7 @@ SHELL'
|
|||||||
ac_subst_files=''
|
ac_subst_files=''
|
||||||
ac_user_opts='
|
ac_user_opts='
|
||||||
enable_option_checking
|
enable_option_checking
|
||||||
|
enable_dependency_tracking
|
||||||
enable_static_link
|
enable_static_link
|
||||||
with_user
|
with_user
|
||||||
with_group
|
with_group
|
||||||
@@ -1633,6 +1635,8 @@ Optional Features:
|
|||||||
--disable-option-checking ignore unrecognized --enable/--with options
|
--disable-option-checking ignore unrecognized --enable/--with options
|
||||||
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
|
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
|
||||||
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
|
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
|
||||||
|
--disable-dependency-tracking
|
||||||
|
speeds up one-time build.
|
||||||
--enable-static_link use this to link the tools to their libraries
|
--enable-static_link use this to link the tools to their libraries
|
||||||
statically (default is dynamic linking
|
statically (default is dynamic linking
|
||||||
--enable-lvm1_fallback use this to fall back and use LVM1 binaries if
|
--enable-lvm1_fallback use this to fall back and use LVM1 binaries if
|
||||||
@@ -2965,7 +2969,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
ac_config_headers="$ac_config_headers lib/misc/configure.h"
|
ac_config_headers="$ac_config_headers include/configure.h"
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
@@ -3126,7 +3130,6 @@ case "$host_os" in
|
|||||||
DEVMAPPER=yes
|
DEVMAPPER=yes
|
||||||
LVMETAD=no
|
LVMETAD=no
|
||||||
LVMPOLLD=no
|
LVMPOLLD=no
|
||||||
LVMLOCKD=no
|
|
||||||
LOCKDSANLOCK=no
|
LOCKDSANLOCK=no
|
||||||
LOCKDDLM=no
|
LOCKDDLM=no
|
||||||
ODIRECT=yes
|
ODIRECT=yes
|
||||||
@@ -7631,6 +7634,19 @@ done
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable dependency tracking" >&5
|
||||||
|
$as_echo_n "checking whether to enable dependency tracking... " >&6; }
|
||||||
|
# Check whether --enable-dependency-tracking was given.
|
||||||
|
if test "${enable_dependency_tracking+set}" = set; then :
|
||||||
|
enableval=$enable_dependency_tracking; USE_TRACKING=$enableval
|
||||||
|
else
|
||||||
|
USE_TRACKING=yes
|
||||||
|
fi
|
||||||
|
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_TRACKING" >&5
|
||||||
|
$as_echo "$USE_TRACKING" >&6; }
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use static linking" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use static linking" >&5
|
||||||
$as_echo_n "checking whether to use static linking... " >&6; }
|
$as_echo_n "checking whether to use static linking... " >&6; }
|
||||||
@@ -8815,7 +8831,7 @@ $as_echo "$as_me: WARNING: cache_check not found in path $PATH" >&2;}
|
|||||||
if test "$CACHE_CHECK_NEEDS_CHECK" = yes; then
|
if test "$CACHE_CHECK_NEEDS_CHECK" = yes; then
|
||||||
$CACHE_CHECK_CMD -V 2>/dev/null >conftest.tmp
|
$CACHE_CHECK_CMD -V 2>/dev/null >conftest.tmp
|
||||||
read -r CACHE_CHECK_VSN < conftest.tmp
|
read -r CACHE_CHECK_VSN < conftest.tmp
|
||||||
IFS=. read -r CACHE_CHECK_VSN_MAJOR CACHE_CHECK_VSN_MINOR CACHE_CHECK_VSN_PATCH < conftest.tmp
|
IFS=.- read -r CACHE_CHECK_VSN_MAJOR CACHE_CHECK_VSN_MINOR CACHE_CHECK_VSN_PATCH LEFTOVER < conftest.tmp
|
||||||
rm -f conftest.tmp
|
rm -f conftest.tmp
|
||||||
|
|
||||||
# Require version >= 0.5.4 for --clear-needs-check-flag
|
# Require version >= 0.5.4 for --clear-needs-check-flag
|
||||||
@@ -11351,6 +11367,8 @@ $as_echo "$LVMPOLLD" >&6; }
|
|||||||
BUILD_LVMPOLLD=$LVMPOLLD
|
BUILD_LVMPOLLD=$LVMPOLLD
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
|
BUILD_LVMLOCKD=no
|
||||||
|
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build lockdsanlock" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build lockdsanlock" >&5
|
||||||
$as_echo_n "checking whether to build lockdsanlock... " >&6; }
|
$as_echo_n "checking whether to build lockdsanlock... " >&6; }
|
||||||
# Check whether --enable-lockd-sanlock was given.
|
# Check whether --enable-lockd-sanlock was given.
|
||||||
@@ -11365,13 +11383,6 @@ BUILD_LOCKDSANLOCK=$LOCKDSANLOCK
|
|||||||
|
|
||||||
if test "$BUILD_LOCKDSANLOCK" = yes; then
|
if test "$BUILD_LOCKDSANLOCK" = yes; then
|
||||||
|
|
||||||
$as_echo "#define LOCKDSANLOCK_SUPPORT 1" >>confdefs.h
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
if test "$BUILD_LOCKDSANLOCK" = yes; then
|
|
||||||
|
|
||||||
pkg_failed=no
|
pkg_failed=no
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LOCKD_SANLOCK" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LOCKD_SANLOCK" >&5
|
||||||
$as_echo_n "checking for LOCKD_SANLOCK... " >&6; }
|
$as_echo_n "checking for LOCKD_SANLOCK... " >&6; }
|
||||||
@@ -11442,6 +11453,9 @@ else
|
|||||||
$as_echo "yes" >&6; }
|
$as_echo "yes" >&6; }
|
||||||
HAVE_LOCKD_SANLOCK=yes
|
HAVE_LOCKD_SANLOCK=yes
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
$as_echo "#define LOCKDSANLOCK_SUPPORT 1" >>confdefs.h
|
||||||
|
|
||||||
BUILD_LVMLOCKD=yes
|
BUILD_LVMLOCKD=yes
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -11460,13 +11474,6 @@ BUILD_LOCKDDLM=$LOCKDDLM
|
|||||||
|
|
||||||
if test "$BUILD_LOCKDDLM" = yes; then
|
if test "$BUILD_LOCKDDLM" = yes; then
|
||||||
|
|
||||||
$as_echo "#define LOCKDDLM_SUPPORT 1" >>confdefs.h
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
if test "$BUILD_LOCKDDLM" = yes; then
|
|
||||||
|
|
||||||
pkg_failed=no
|
pkg_failed=no
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LOCKD_DLM" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LOCKD_DLM" >&5
|
||||||
$as_echo_n "checking for LOCKD_DLM... " >&6; }
|
$as_echo_n "checking for LOCKD_DLM... " >&6; }
|
||||||
@@ -11537,11 +11544,13 @@ else
|
|||||||
$as_echo "yes" >&6; }
|
$as_echo "yes" >&6; }
|
||||||
HAVE_LOCKD_DLM=yes
|
HAVE_LOCKD_DLM=yes
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
$as_echo "#define LOCKDDLM_SUPPORT 1" >>confdefs.h
|
||||||
|
|
||||||
BUILD_LVMLOCKD=yes
|
BUILD_LVMLOCKD=yes
|
||||||
fi
|
fi
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build lvmlockd" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build lvmlockd" >&5
|
||||||
$as_echo_n "checking whether to build lvmlockd... " >&6; }
|
$as_echo_n "checking whether to build lvmlockd... " >&6; }
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $BUILD_LVMLOCKD" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $BUILD_LVMLOCKD" >&5
|
||||||
@@ -11782,7 +11791,7 @@ fi
|
|||||||
$as_echo "#define BLKID_WIPING_SUPPORT 1" >>confdefs.h
|
$as_echo "#define BLKID_WIPING_SUPPORT 1" >>confdefs.h
|
||||||
|
|
||||||
else
|
else
|
||||||
DEFAULT_USE_BLKID_WIPING=1
|
DEFAULT_USE_BLKID_WIPING=0
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
DEFAULT_USE_BLKID_WIPING=0
|
DEFAULT_USE_BLKID_WIPING=0
|
||||||
@@ -11998,6 +12007,50 @@ fi
|
|||||||
|
|
||||||
$as_echo "#define UDEV_SYNC_SUPPORT 1" >>confdefs.h
|
$as_echo "#define UDEV_SYNC_SUPPORT 1" >>confdefs.h
|
||||||
|
|
||||||
|
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for udev_device_get_is_initialized in -ludev" >&5
|
||||||
|
$as_echo_n "checking for udev_device_get_is_initialized in -ludev... " >&6; }
|
||||||
|
if ${ac_cv_lib_udev_udev_device_get_is_initialized+:} false; then :
|
||||||
|
$as_echo_n "(cached) " >&6
|
||||||
|
else
|
||||||
|
ac_check_lib_save_LIBS=$LIBS
|
||||||
|
LIBS="-ludev $LIBS"
|
||||||
|
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||||
|
/* end confdefs.h. */
|
||||||
|
|
||||||
|
/* Override any GCC internal prototype to avoid an error.
|
||||||
|
Use char because int might match the return type of a GCC
|
||||||
|
builtin and then its argument prototype would still apply. */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
#endif
|
||||||
|
char udev_device_get_is_initialized ();
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
return udev_device_get_is_initialized ();
|
||||||
|
;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
_ACEOF
|
||||||
|
if ac_fn_c_try_link "$LINENO"; then :
|
||||||
|
ac_cv_lib_udev_udev_device_get_is_initialized=yes
|
||||||
|
else
|
||||||
|
ac_cv_lib_udev_udev_device_get_is_initialized=no
|
||||||
|
fi
|
||||||
|
rm -f core conftest.err conftest.$ac_objext \
|
||||||
|
conftest$ac_exeext conftest.$ac_ext
|
||||||
|
LIBS=$ac_check_lib_save_LIBS
|
||||||
|
fi
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_udev_udev_device_get_is_initialized" >&5
|
||||||
|
$as_echo "$ac_cv_lib_udev_udev_device_get_is_initialized" >&6; }
|
||||||
|
if test "x$ac_cv_lib_udev_udev_device_get_is_initialized" = xyes; then :
|
||||||
|
|
||||||
|
$as_echo "#define HAVE_LIBUDEV_UDEV_DEVICE_GET_IS_INITIALIZED 1" >>confdefs.h
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
LIBS=$ac_check_lib_save_LIBS
|
||||||
fi
|
fi
|
||||||
|
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable installation of udev rules required for synchronisation" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable installation of udev rules required for synchronisation" >&5
|
||||||
@@ -12569,6 +12622,50 @@ if [ \( "$LVM1" = shared -o "$POOL" = shared -o "$CLUSTER" = shared \
|
|||||||
as_fn_error $? "Features cannot be 'shared' when building statically" "$LINENO" 5
|
as_fn_error $? "Features cannot be 'shared' when building statically" "$LINENO" 5
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for log10 in -lm" >&5
|
||||||
|
$as_echo_n "checking for log10 in -lm... " >&6; }
|
||||||
|
if ${ac_cv_lib_m_log10+:} false; then :
|
||||||
|
$as_echo_n "(cached) " >&6
|
||||||
|
else
|
||||||
|
ac_check_lib_save_LIBS=$LIBS
|
||||||
|
LIBS="-lm $LIBS"
|
||||||
|
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||||
|
/* end confdefs.h. */
|
||||||
|
|
||||||
|
/* Override any GCC internal prototype to avoid an error.
|
||||||
|
Use char because int might match the return type of a GCC
|
||||||
|
builtin and then its argument prototype would still apply. */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
#endif
|
||||||
|
char log10 ();
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
return log10 ();
|
||||||
|
;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
_ACEOF
|
||||||
|
if ac_fn_c_try_link "$LINENO"; then :
|
||||||
|
ac_cv_lib_m_log10=yes
|
||||||
|
else
|
||||||
|
ac_cv_lib_m_log10=no
|
||||||
|
fi
|
||||||
|
rm -f core conftest.err conftest.$ac_objext \
|
||||||
|
conftest$ac_exeext conftest.$ac_ext
|
||||||
|
LIBS=$ac_check_lib_save_LIBS
|
||||||
|
fi
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_log10" >&5
|
||||||
|
$as_echo "$ac_cv_lib_m_log10" >&6; }
|
||||||
|
if test "x$ac_cv_lib_m_log10" = xyes; then :
|
||||||
|
M_LIBS="-lm"
|
||||||
|
else
|
||||||
|
hard_bailout
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_lock in -lpthread" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_lock in -lpthread" >&5
|
||||||
$as_echo_n "checking for pthread_mutex_lock in -lpthread... " >&6; }
|
$as_echo_n "checking for pthread_mutex_lock in -lpthread... " >&6; }
|
||||||
@@ -12802,13 +12899,11 @@ fi
|
|||||||
$as_echo "#define HAVE_REALTIME 1" >>confdefs.h
|
$as_echo "#define HAVE_REALTIME 1" >>confdefs.h
|
||||||
|
|
||||||
LIBS="-lrt $LIBS"
|
LIBS="-lrt $LIBS"
|
||||||
RT_PC="librt"
|
RT_LIB="-lrt"
|
||||||
else
|
else
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Disabling realtime clock" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Disabling realtime clock" >&5
|
||||||
$as_echo "$as_me: WARNING: Disabling realtime clock" >&2;}
|
$as_echo "$as_me: WARNING: Disabling realtime clock" >&2;}
|
||||||
fi
|
fi
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_REALTIME" >&5
|
|
||||||
$as_echo "$HAVE_REALTIME" >&6; }
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct stat has st_ctim." >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct stat has st_ctim." >&5
|
||||||
@@ -13825,7 +13920,6 @@ cat >>confdefs.h <<_ACEOF
|
|||||||
_ACEOF
|
_ACEOF
|
||||||
|
|
||||||
|
|
||||||
if test "$CLVMD" != none; then
|
|
||||||
clvmd_prefix=$ac_default_prefix
|
clvmd_prefix=$ac_default_prefix
|
||||||
test "$prefix" != NONE && clvmd_prefix=$prefix
|
test "$prefix" != NONE && clvmd_prefix=$prefix
|
||||||
CLVMD_PATH="$clvmd_prefix/sbin/clvmd"
|
CLVMD_PATH="$clvmd_prefix/sbin/clvmd"
|
||||||
@@ -13834,7 +13928,6 @@ cat >>confdefs.h <<_ACEOF
|
|||||||
#define CLVMD_PATH "$CLVMD_PATH"
|
#define CLVMD_PATH "$CLVMD_PATH"
|
||||||
_ACEOF
|
_ACEOF
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
if test "$BUILD_DMEVENTD" = yes; then
|
if test "$BUILD_DMEVENTD" = yes; then
|
||||||
@@ -13985,18 +14078,18 @@ test "$interface" != ioctl && as_fn_error $? "--with-interface=ioctl required. f
|
|||||||
$as_echo "$interface" >&6; }
|
$as_echo "$interface" >&6; }
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
DM_LIB_VERSION="\"`cat "$srcdir"/VERSION_DM 2>/dev/null || echo Unknown`\""
|
read DM_LIB_VERSION < "$srcdir"/VERSION_DM 2>/dev/null || DM_LIB_VERSION=Unknown
|
||||||
|
|
||||||
cat >>confdefs.h <<_ACEOF
|
cat >>confdefs.h <<_ACEOF
|
||||||
#define DM_LIB_VERSION $DM_LIB_VERSION
|
#define DM_LIB_VERSION "$DM_LIB_VERSION"
|
||||||
_ACEOF
|
_ACEOF
|
||||||
|
|
||||||
|
|
||||||
DM_LIB_PATCHLEVEL=`cat "$srcdir"/VERSION_DM | $AWK -F '[-. ]' '{printf "%s.%s.%s",$1,$2,$3}'`
|
DM_LIB_PATCHLEVEL=`cat "$srcdir"/VERSION_DM | $AWK -F '[-. ]' '{printf "%s.%s.%s",$1,$2,$3}'`
|
||||||
|
|
||||||
LVM_VERSION="\"`cat "$srcdir"/VERSION 2>/dev/null || echo Unknown`\""
|
read VER < "$srcdir"/VERSION 2>/dev/null || VER=Unknown
|
||||||
|
|
||||||
VER=`cat "$srcdir"/VERSION`
|
LVM_VERSION=\"$VER\"
|
||||||
LVM_RELEASE_DATE="\"`echo $VER | $SED 's/.* (//;s/).*//'`\""
|
LVM_RELEASE_DATE="\"`echo $VER | $SED 's/.* (//;s/).*//'`\""
|
||||||
VER=`echo "$VER" | $AWK '{print $1}'`
|
VER=`echo "$VER" | $AWK '{print $1}'`
|
||||||
LVM_RELEASE="\"`echo "$VER" | $AWK -F '-' '{print $2}'`\""
|
LVM_RELEASE="\"`echo "$VER" | $AWK -F '-' '{print $2}'`\""
|
||||||
@@ -14151,10 +14244,11 @@ LVM_LIBAPI=`echo "$VER" | $AWK -F '[()]' '{print $2}'`
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
ac_config_files="$ac_config_files Makefile make.tmpl daemons/Makefile daemons/clvmd/Makefile daemons/cmirrord/Makefile daemons/dmeventd/Makefile daemons/dmeventd/libdevmapper-event.pc daemons/dmeventd/plugins/Makefile daemons/dmeventd/plugins/lvm2/Makefile daemons/dmeventd/plugins/raid/Makefile daemons/dmeventd/plugins/mirror/Makefile daemons/dmeventd/plugins/snapshot/Makefile daemons/dmeventd/plugins/thin/Makefile daemons/lvmetad/Makefile daemons/lvmpolld/Makefile daemons/lvmlockd/Makefile conf/Makefile conf/example.conf conf/lvmlocal.conf conf/command_profile_template.profile conf/metadata_profile_template.profile include/.symlinks include/Makefile lib/Makefile lib/format1/Makefile lib/format_pool/Makefile lib/locking/Makefile lib/mirror/Makefile lib/replicator/Makefile lib/misc/lvm-version.h lib/raid/Makefile lib/snapshot/Makefile lib/thin/Makefile lib/cache_segtype/Makefile libdaemon/Makefile libdaemon/client/Makefile libdaemon/server/Makefile libdm/Makefile libdm/libdevmapper.pc liblvm/Makefile liblvm/liblvm2app.pc man/Makefile po/Makefile python/Makefile python/setup.py scripts/blkdeactivate.sh scripts/blk_availability_init_red_hat scripts/blk_availability_systemd_red_hat.service scripts/clvmd_init_red_hat scripts/cmirrord_init_red_hat scripts/dm_event_systemd_red_hat.service scripts/dm_event_systemd_red_hat.socket scripts/lvm2_cluster_activation_red_hat.sh scripts/lvm2_cluster_activation_systemd_red_hat.service scripts/lvm2_clvmd_systemd_red_hat.service scripts/lvm2_cmirrord_systemd_red_hat.service scripts/lvm2_lvmetad_init_red_hat scripts/lvm2_lvmetad_systemd_red_hat.service scripts/lvm2_lvmetad_systemd_red_hat.socket scripts/lvm2_lvmpolld_init_red_hat scripts/lvm2_lvmpolld_systemd_red_hat.service scripts/lvm2_lvmpolld_systemd_red_hat.socket scripts/lvm2_lvmlockd_systemd_red_hat.service scripts/lvm2_lvmlocking_systemd_red_hat.service scripts/lvm2_monitoring_init_red_hat scripts/lvm2_monitoring_systemd_red_hat.service scripts/lvm2_pvscan_systemd_red_hat@.service scripts/lvm2_tmpfiles_red_hat.conf scripts/Makefile test/Makefile test/api/Makefile test/unit/Makefile tools/Makefile udev/Makefile unit-tests/datastruct/Makefile unit-tests/regex/Makefile unit-tests/mm/Makefile"
|
ac_config_files="$ac_config_files Makefile make.tmpl daemons/Makefile daemons/clvmd/Makefile daemons/cmirrord/Makefile daemons/dmeventd/Makefile daemons/dmeventd/libdevmapper-event.pc daemons/dmeventd/plugins/Makefile daemons/dmeventd/plugins/lvm2/Makefile daemons/dmeventd/plugins/raid/Makefile daemons/dmeventd/plugins/mirror/Makefile daemons/dmeventd/plugins/snapshot/Makefile daemons/dmeventd/plugins/thin/Makefile daemons/lvmetad/Makefile daemons/lvmpolld/Makefile daemons/lvmlockd/Makefile conf/Makefile conf/example.conf conf/lvmlocal.conf conf/command_profile_template.profile conf/metadata_profile_template.profile include/.symlinks include/Makefile lib/Makefile lib/format1/Makefile lib/format_pool/Makefile lib/locking/Makefile lib/mirror/Makefile lib/replicator/Makefile include/lvm-version.h lib/raid/Makefile lib/snapshot/Makefile lib/thin/Makefile lib/cache_segtype/Makefile libdaemon/Makefile libdaemon/client/Makefile libdaemon/server/Makefile libdm/Makefile libdm/libdevmapper.pc liblvm/Makefile liblvm/liblvm2app.pc man/Makefile po/Makefile python/Makefile python/setup.py scripts/blkdeactivate.sh scripts/blk_availability_init_red_hat scripts/blk_availability_systemd_red_hat.service scripts/clvmd_init_red_hat scripts/cmirrord_init_red_hat scripts/dm_event_systemd_red_hat.service scripts/dm_event_systemd_red_hat.socket scripts/lvm2_cluster_activation_red_hat.sh scripts/lvm2_cluster_activation_systemd_red_hat.service scripts/lvm2_clvmd_systemd_red_hat.service scripts/lvm2_cmirrord_systemd_red_hat.service scripts/lvm2_lvmetad_init_red_hat scripts/lvm2_lvmetad_systemd_red_hat.service scripts/lvm2_lvmetad_systemd_red_hat.socket scripts/lvm2_lvmpolld_init_red_hat scripts/lvm2_lvmpolld_systemd_red_hat.service scripts/lvm2_lvmpolld_systemd_red_hat.socket scripts/lvm2_lvmlockd_systemd_red_hat.service scripts/lvm2_lvmlocking_systemd_red_hat.service scripts/lvm2_monitoring_init_red_hat scripts/lvm2_monitoring_systemd_red_hat.service scripts/lvm2_pvscan_systemd_red_hat@.service scripts/lvm2_tmpfiles_red_hat.conf scripts/Makefile test/Makefile test/api/Makefile test/unit/Makefile tools/Makefile udev/Makefile unit-tests/datastruct/Makefile unit-tests/regex/Makefile unit-tests/mm/Makefile"
|
||||||
|
|
||||||
cat >confcache <<\_ACEOF
|
cat >confcache <<\_ACEOF
|
||||||
# This file is a shell script that caches the results of configure
|
# This file is a shell script that caches the results of configure
|
||||||
@@ -14848,7 +14942,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
|||||||
for ac_config_target in $ac_config_targets
|
for ac_config_target in $ac_config_targets
|
||||||
do
|
do
|
||||||
case $ac_config_target in
|
case $ac_config_target in
|
||||||
"lib/misc/configure.h") CONFIG_HEADERS="$CONFIG_HEADERS lib/misc/configure.h" ;;
|
"include/configure.h") CONFIG_HEADERS="$CONFIG_HEADERS include/configure.h" ;;
|
||||||
"Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
|
"Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
|
||||||
"make.tmpl") CONFIG_FILES="$CONFIG_FILES make.tmpl" ;;
|
"make.tmpl") CONFIG_FILES="$CONFIG_FILES make.tmpl" ;;
|
||||||
"daemons/Makefile") CONFIG_FILES="$CONFIG_FILES daemons/Makefile" ;;
|
"daemons/Makefile") CONFIG_FILES="$CONFIG_FILES daemons/Makefile" ;;
|
||||||
@@ -14878,7 +14972,7 @@ do
|
|||||||
"lib/locking/Makefile") CONFIG_FILES="$CONFIG_FILES lib/locking/Makefile" ;;
|
"lib/locking/Makefile") CONFIG_FILES="$CONFIG_FILES lib/locking/Makefile" ;;
|
||||||
"lib/mirror/Makefile") CONFIG_FILES="$CONFIG_FILES lib/mirror/Makefile" ;;
|
"lib/mirror/Makefile") CONFIG_FILES="$CONFIG_FILES lib/mirror/Makefile" ;;
|
||||||
"lib/replicator/Makefile") CONFIG_FILES="$CONFIG_FILES lib/replicator/Makefile" ;;
|
"lib/replicator/Makefile") CONFIG_FILES="$CONFIG_FILES lib/replicator/Makefile" ;;
|
||||||
"lib/misc/lvm-version.h") CONFIG_FILES="$CONFIG_FILES lib/misc/lvm-version.h" ;;
|
"include/lvm-version.h") CONFIG_FILES="$CONFIG_FILES include/lvm-version.h" ;;
|
||||||
"lib/raid/Makefile") CONFIG_FILES="$CONFIG_FILES lib/raid/Makefile" ;;
|
"lib/raid/Makefile") CONFIG_FILES="$CONFIG_FILES lib/raid/Makefile" ;;
|
||||||
"lib/snapshot/Makefile") CONFIG_FILES="$CONFIG_FILES lib/snapshot/Makefile" ;;
|
"lib/snapshot/Makefile") CONFIG_FILES="$CONFIG_FILES lib/snapshot/Makefile" ;;
|
||||||
"lib/thin/Makefile") CONFIG_FILES="$CONFIG_FILES lib/thin/Makefile" ;;
|
"lib/thin/Makefile") CONFIG_FILES="$CONFIG_FILES lib/thin/Makefile" ;;
|
||||||
|
|||||||
61
configure.in
61
configure.in
@@ -8,7 +8,7 @@
|
|||||||
##
|
##
|
||||||
## 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
## Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
AC_PREREQ(2.61)
|
AC_PREREQ(2.61)
|
||||||
@@ -16,7 +16,7 @@ AC_PREREQ(2.61)
|
|||||||
dnl -- Process this file with autoconf to produce a configure script.
|
dnl -- Process this file with autoconf to produce a configure script.
|
||||||
AC_INIT
|
AC_INIT
|
||||||
AC_CONFIG_SRCDIR([lib/device/dev-cache.h])
|
AC_CONFIG_SRCDIR([lib/device/dev-cache.h])
|
||||||
AC_CONFIG_HEADERS([lib/misc/configure.h])
|
AC_CONFIG_HEADERS([include/configure.h])
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
dnl -- Setup the directory where autoconf has auxilary files
|
dnl -- Setup the directory where autoconf has auxilary files
|
||||||
@@ -39,7 +39,6 @@ case "$host_os" in
|
|||||||
DEVMAPPER=yes
|
DEVMAPPER=yes
|
||||||
LVMETAD=no
|
LVMETAD=no
|
||||||
LVMPOLLD=no
|
LVMPOLLD=no
|
||||||
LVMLOCKD=no
|
|
||||||
LOCKDSANLOCK=no
|
LOCKDSANLOCK=no
|
||||||
LOCKDDLM=no
|
LOCKDDLM=no
|
||||||
ODIRECT=yes
|
ODIRECT=yes
|
||||||
@@ -155,6 +154,15 @@ AC_FUNC_STAT
|
|||||||
AC_FUNC_STRTOD
|
AC_FUNC_STRTOD
|
||||||
AC_FUNC_VPRINTF
|
AC_FUNC_VPRINTF
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
dnl -- Disable dependency tracking
|
||||||
|
AC_MSG_CHECKING(whether to enable dependency tracking)
|
||||||
|
AC_ARG_ENABLE(dependency-tracking,
|
||||||
|
AC_HELP_STRING([--disable-dependency-tracking],
|
||||||
|
[speeds up one-time build.]),
|
||||||
|
USE_TRACKING=$enableval, USE_TRACKING=yes)
|
||||||
|
AC_MSG_RESULT($USE_TRACKING)
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
dnl -- Enables statically-linked tools
|
dnl -- Enables statically-linked tools
|
||||||
AC_MSG_CHECKING(whether to use static linking)
|
AC_MSG_CHECKING(whether to use static linking)
|
||||||
@@ -586,7 +594,7 @@ case "$CACHE" in
|
|||||||
if test "$CACHE_CHECK_NEEDS_CHECK" = yes; then
|
if test "$CACHE_CHECK_NEEDS_CHECK" = yes; then
|
||||||
$CACHE_CHECK_CMD -V 2>/dev/null >conftest.tmp
|
$CACHE_CHECK_CMD -V 2>/dev/null >conftest.tmp
|
||||||
read -r CACHE_CHECK_VSN < conftest.tmp
|
read -r CACHE_CHECK_VSN < conftest.tmp
|
||||||
IFS=. read -r CACHE_CHECK_VSN_MAJOR CACHE_CHECK_VSN_MINOR CACHE_CHECK_VSN_PATCH < conftest.tmp
|
IFS=.- read -r CACHE_CHECK_VSN_MAJOR CACHE_CHECK_VSN_MINOR CACHE_CHECK_VSN_PATCH LEFTOVER < conftest.tmp
|
||||||
rm -f conftest.tmp
|
rm -f conftest.tmp
|
||||||
|
|
||||||
# Require version >= 0.5.4 for --clear-needs-check-flag
|
# Require version >= 0.5.4 for --clear-needs-check-flag
|
||||||
@@ -1136,6 +1144,8 @@ AC_MSG_RESULT($LVMPOLLD)
|
|||||||
BUILD_LVMPOLLD=$LVMPOLLD
|
BUILD_LVMPOLLD=$LVMPOLLD
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
|
BUILD_LVMLOCKD=no
|
||||||
|
|
||||||
dnl -- Build lockdsanlock
|
dnl -- Build lockdsanlock
|
||||||
AC_MSG_CHECKING(whether to build lockdsanlock)
|
AC_MSG_CHECKING(whether to build lockdsanlock)
|
||||||
AC_ARG_ENABLE(lockd-sanlock,
|
AC_ARG_ENABLE(lockd-sanlock,
|
||||||
@@ -1146,14 +1156,10 @@ AC_MSG_RESULT($LOCKDSANLOCK)
|
|||||||
|
|
||||||
BUILD_LOCKDSANLOCK=$LOCKDSANLOCK
|
BUILD_LOCKDSANLOCK=$LOCKDSANLOCK
|
||||||
|
|
||||||
if test "$BUILD_LOCKDSANLOCK" = yes; then
|
|
||||||
AC_DEFINE([LOCKDSANLOCK_SUPPORT], 1, [Define to 1 to include code that uses lvmlockd sanlock option.])
|
|
||||||
fi
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
dnl -- Look for sanlock libraries
|
dnl -- Look for sanlock libraries
|
||||||
if test "$BUILD_LOCKDSANLOCK" = yes; then
|
if test "$BUILD_LOCKDSANLOCK" = yes; then
|
||||||
PKG_CHECK_MODULES(LOCKD_SANLOCK, libsanlock_client, [HAVE_LOCKD_SANLOCK=yes], $bailout)
|
PKG_CHECK_MODULES(LOCKD_SANLOCK, libsanlock_client, [HAVE_LOCKD_SANLOCK=yes], $bailout)
|
||||||
|
AC_DEFINE([LOCKDSANLOCK_SUPPORT], 1, [Define to 1 to include code that uses lvmlockd sanlock option.])
|
||||||
BUILD_LVMLOCKD=yes
|
BUILD_LVMLOCKD=yes
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -1168,20 +1174,15 @@ AC_MSG_RESULT($LOCKDDLM)
|
|||||||
|
|
||||||
BUILD_LOCKDDLM=$LOCKDDLM
|
BUILD_LOCKDDLM=$LOCKDDLM
|
||||||
|
|
||||||
if test "$BUILD_LOCKDDLM" = yes; then
|
|
||||||
AC_DEFINE([LOCKDDLM_SUPPORT], 1, [Define to 1 to include code that uses lvmlockd dlm option.])
|
|
||||||
fi
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
dnl -- Look for dlm libraries
|
dnl -- Look for dlm libraries
|
||||||
if test "$BUILD_LOCKDDLM" = yes; then
|
if test "$BUILD_LOCKDDLM" = yes; then
|
||||||
PKG_CHECK_MODULES(LOCKD_DLM, libdlm, [HAVE_LOCKD_DLM=yes], $bailout)
|
PKG_CHECK_MODULES(LOCKD_DLM, libdlm, [HAVE_LOCKD_DLM=yes], $bailout)
|
||||||
|
AC_DEFINE([LOCKDDLM_SUPPORT], 1, [Define to 1 to include code that uses lvmlockd dlm option.])
|
||||||
BUILD_LVMLOCKD=yes
|
BUILD_LVMLOCKD=yes
|
||||||
fi
|
fi
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
dnl -- Build lvmlockd
|
dnl -- Build lvmlockd
|
||||||
|
|
||||||
AC_MSG_CHECKING(whether to build lvmlockd)
|
AC_MSG_CHECKING(whether to build lvmlockd)
|
||||||
AC_MSG_RESULT($BUILD_LVMLOCKD)
|
AC_MSG_RESULT($BUILD_LVMLOCKD)
|
||||||
|
|
||||||
@@ -1290,7 +1291,7 @@ if test "$BLKID_WIPING" != no; then
|
|||||||
DEFAULT_USE_BLKID_WIPING=1
|
DEFAULT_USE_BLKID_WIPING=1
|
||||||
AC_DEFINE([BLKID_WIPING_SUPPORT], 1, [Define to 1 to use libblkid detection of signatures when wiping.])
|
AC_DEFINE([BLKID_WIPING_SUPPORT], 1, [Define to 1 to use libblkid detection of signatures when wiping.])
|
||||||
else
|
else
|
||||||
DEFAULT_USE_BLKID_WIPING=1
|
DEFAULT_USE_BLKID_WIPING=0
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
DEFAULT_USE_BLKID_WIPING=0
|
DEFAULT_USE_BLKID_WIPING=0
|
||||||
@@ -1333,6 +1334,10 @@ if test "$UDEV_SYNC" = yes; then
|
|||||||
pkg_config_init
|
pkg_config_init
|
||||||
PKG_CHECK_MODULES(UDEV, libudev >= 143, [UDEV_PC="libudev"])
|
PKG_CHECK_MODULES(UDEV, libudev >= 143, [UDEV_PC="libudev"])
|
||||||
AC_DEFINE([UDEV_SYNC_SUPPORT], 1, [Define to 1 to enable synchronisation with udev processing.])
|
AC_DEFINE([UDEV_SYNC_SUPPORT], 1, [Define to 1 to enable synchronisation with udev processing.])
|
||||||
|
|
||||||
|
AC_CHECK_LIB(udev, udev_device_get_is_initialized, AC_DEFINE([HAVE_LIBUDEV_UDEV_DEVICE_GET_IS_INITIALIZED], 1,
|
||||||
|
[Define to 1 if udev_device_get_is_initialized is available.]))
|
||||||
|
LIBS=$ac_check_lib_save_LIBS
|
||||||
fi
|
fi
|
||||||
|
|
||||||
dnl -- Enable udev rules
|
dnl -- Enable udev rules
|
||||||
@@ -1537,6 +1542,10 @@ if [[ \( "$LVM1" = shared -o "$POOL" = shared -o "$CLUSTER" = shared \
|
|||||||
AC_MSG_ERROR([Features cannot be 'shared' when building statically])
|
AC_MSG_ERROR([Features cannot be 'shared' when building statically])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
AC_CHECK_LIB(m, log10,
|
||||||
|
[M_LIBS="-lm"], hard_bailout)
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
AC_CHECK_LIB([pthread], [pthread_mutex_lock],
|
AC_CHECK_LIB([pthread], [pthread_mutex_lock],
|
||||||
[PTHREAD_LIBS="-lpthread"], hard_bailout)
|
[PTHREAD_LIBS="-lpthread"], hard_bailout)
|
||||||
@@ -1577,11 +1586,10 @@ if test "$REALTIME" = yes; then
|
|||||||
if test "$HAVE_REALTIME" = yes; then
|
if test "$HAVE_REALTIME" = yes; then
|
||||||
AC_DEFINE([HAVE_REALTIME], 1, [Define to 1 to include support for realtime clock.])
|
AC_DEFINE([HAVE_REALTIME], 1, [Define to 1 to include support for realtime clock.])
|
||||||
LIBS="-lrt $LIBS"
|
LIBS="-lrt $LIBS"
|
||||||
RT_PC="librt"
|
RT_LIB="-lrt"
|
||||||
else
|
else
|
||||||
AC_MSG_WARN(Disabling realtime clock)
|
AC_MSG_WARN(Disabling realtime clock)
|
||||||
fi
|
fi
|
||||||
AC_MSG_RESULT($HAVE_REALTIME)
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
dnl Check if the system has struct stat st_ctim.
|
dnl Check if the system has struct stat st_ctim.
|
||||||
@@ -1784,12 +1792,10 @@ test "$lvm_exec_prefix" = NONE && lvm_exec_prefix=$ac_default_prefix
|
|||||||
LVM_PATH="$lvm_exec_prefix/sbin/lvm"
|
LVM_PATH="$lvm_exec_prefix/sbin/lvm"
|
||||||
AC_DEFINE_UNQUOTED(LVM_PATH, ["$LVM_PATH"], [Path to lvm binary.])
|
AC_DEFINE_UNQUOTED(LVM_PATH, ["$LVM_PATH"], [Path to lvm binary.])
|
||||||
|
|
||||||
if test "$CLVMD" != none; then
|
|
||||||
clvmd_prefix=$ac_default_prefix
|
clvmd_prefix=$ac_default_prefix
|
||||||
test "$prefix" != NONE && clvmd_prefix=$prefix
|
test "$prefix" != NONE && clvmd_prefix=$prefix
|
||||||
CLVMD_PATH="$clvmd_prefix/sbin/clvmd"
|
CLVMD_PATH="$clvmd_prefix/sbin/clvmd"
|
||||||
AC_DEFINE_UNQUOTED(CLVMD_PATH, ["$CLVMD_PATH"], [Path to clvmd binary.])
|
AC_DEFINE_UNQUOTED(CLVMD_PATH, ["$CLVMD_PATH"], [Path to clvmd binary.])
|
||||||
fi
|
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
dnl -- dmeventd pidfile and executable path
|
dnl -- dmeventd pidfile and executable path
|
||||||
@@ -1878,14 +1884,14 @@ test "$interface" != ioctl && AC_MSG_ERROR([--with-interface=ioctl required. fs
|
|||||||
AC_MSG_RESULT($interface)
|
AC_MSG_RESULT($interface)
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
DM_LIB_VERSION="\"`cat "$srcdir"/VERSION_DM 2>/dev/null || echo Unknown`\""
|
read DM_LIB_VERSION < "$srcdir"/VERSION_DM 2>/dev/null || DM_LIB_VERSION=Unknown
|
||||||
AC_DEFINE_UNQUOTED(DM_LIB_VERSION, $DM_LIB_VERSION, [Library version])
|
AC_DEFINE_UNQUOTED(DM_LIB_VERSION, "$DM_LIB_VERSION", [Library version])
|
||||||
|
|
||||||
DM_LIB_PATCHLEVEL=`cat "$srcdir"/VERSION_DM | $AWK -F '[[-. ]]' '{printf "%s.%s.%s",$1,$2,$3}'`
|
DM_LIB_PATCHLEVEL=`cat "$srcdir"/VERSION_DM | $AWK -F '[[-. ]]' '{printf "%s.%s.%s",$1,$2,$3}'`
|
||||||
|
|
||||||
LVM_VERSION="\"`cat "$srcdir"/VERSION 2>/dev/null || echo Unknown`\""
|
read VER < "$srcdir"/VERSION 2>/dev/null || VER=Unknown
|
||||||
|
|
||||||
VER=`cat "$srcdir"/VERSION`
|
LVM_VERSION=\"$VER\"
|
||||||
LVM_RELEASE_DATE="\"`echo $VER | $SED 's/.* (//;s/).*//'`\""
|
LVM_RELEASE_DATE="\"`echo $VER | $SED 's/.* (//;s/).*//'`\""
|
||||||
VER=`echo "$VER" | $AWK '{print $1}'`
|
VER=`echo "$VER" | $AWK '{print $1}'`
|
||||||
LVM_RELEASE="\"`echo "$VER" | $AWK -F '-' '{print $2}'`\""
|
LVM_RELEASE="\"`echo "$VER" | $AWK -F '-' '{print $2}'`\""
|
||||||
@@ -1953,7 +1959,6 @@ AC_SUBST(DLM_LIBS)
|
|||||||
AC_SUBST(DL_LIBS)
|
AC_SUBST(DL_LIBS)
|
||||||
AC_SUBST(DMEVENTD)
|
AC_SUBST(DMEVENTD)
|
||||||
AC_SUBST(DMEVENTD_PATH)
|
AC_SUBST(DMEVENTD_PATH)
|
||||||
AC_SUBST(DM_LIB_VERSION)
|
|
||||||
AC_SUBST(DM_LIB_PATCHLEVEL)
|
AC_SUBST(DM_LIB_PATCHLEVEL)
|
||||||
AC_SUBST(ELDFLAGS)
|
AC_SUBST(ELDFLAGS)
|
||||||
AC_SUBST(FSADM)
|
AC_SUBST(FSADM)
|
||||||
@@ -1984,6 +1989,7 @@ AC_SUBST(OCF)
|
|||||||
AC_SUBST(OCFDIR)
|
AC_SUBST(OCFDIR)
|
||||||
AC_SUBST(PKGCONFIG)
|
AC_SUBST(PKGCONFIG)
|
||||||
AC_SUBST(POOL)
|
AC_SUBST(POOL)
|
||||||
|
AC_SUBST(M_LIBS)
|
||||||
AC_SUBST(PTHREAD_LIBS)
|
AC_SUBST(PTHREAD_LIBS)
|
||||||
AC_SUBST(PYTHON)
|
AC_SUBST(PYTHON)
|
||||||
AC_SUBST(PYTHON_BINDINGS)
|
AC_SUBST(PYTHON_BINDINGS)
|
||||||
@@ -1992,7 +1998,7 @@ AC_SUBST(PYTHON_LIBDIRS)
|
|||||||
AC_SUBST(QUORUM_CFLAGS)
|
AC_SUBST(QUORUM_CFLAGS)
|
||||||
AC_SUBST(QUORUM_LIBS)
|
AC_SUBST(QUORUM_LIBS)
|
||||||
AC_SUBST(RAID)
|
AC_SUBST(RAID)
|
||||||
AC_SUBST(RT_PC)
|
AC_SUBST(RT_LIB)
|
||||||
AC_SUBST(READLINE_LIBS)
|
AC_SUBST(READLINE_LIBS)
|
||||||
AC_SUBST(REPLICATORS)
|
AC_SUBST(REPLICATORS)
|
||||||
AC_SUBST(SACKPT_CFLAGS)
|
AC_SUBST(SACKPT_CFLAGS)
|
||||||
@@ -2021,6 +2027,7 @@ AC_SUBST(UDEV_SYNC)
|
|||||||
AC_SUBST(UDEV_SYSTEMD_BACKGROUND_JOBS)
|
AC_SUBST(UDEV_SYSTEMD_BACKGROUND_JOBS)
|
||||||
AC_SUBST(UDEV_RULE_EXEC_DETECTION)
|
AC_SUBST(UDEV_RULE_EXEC_DETECTION)
|
||||||
AC_SUBST(UDEV_HAS_BUILTIN_BLKID)
|
AC_SUBST(UDEV_HAS_BUILTIN_BLKID)
|
||||||
|
AC_SUBST(USE_TRACKING)
|
||||||
AC_SUBST(VALGRIND_POOL)
|
AC_SUBST(VALGRIND_POOL)
|
||||||
AC_SUBST(WRITE_INSTALL)
|
AC_SUBST(WRITE_INSTALL)
|
||||||
AC_SUBST(DMEVENTD_PIDFILE)
|
AC_SUBST(DMEVENTD_PIDFILE)
|
||||||
@@ -2075,7 +2082,7 @@ lib/format_pool/Makefile
|
|||||||
lib/locking/Makefile
|
lib/locking/Makefile
|
||||||
lib/mirror/Makefile
|
lib/mirror/Makefile
|
||||||
lib/replicator/Makefile
|
lib/replicator/Makefile
|
||||||
lib/misc/lvm-version.h
|
include/lvm-version.h
|
||||||
lib/raid/Makefile
|
lib/raid/Makefile
|
||||||
lib/snapshot/Makefile
|
lib/snapshot/Makefile
|
||||||
lib/thin/Makefile
|
lib/thin/Makefile
|
||||||
|
|||||||
122
coverity/coverity_model.c
Normal file
122
coverity/coverity_model.c
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
/*
|
||||||
|
* 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];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
*/
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
#
|
#
|
||||||
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
srcdir = @srcdir@
|
srcdir = @srcdir@
|
||||||
top_srcdir = @top_srcdir@
|
top_srcdir = @top_srcdir@
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
#
|
#
|
||||||
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
srcdir = @srcdir@
|
srcdir = @srcdir@
|
||||||
top_srcdir = @top_srcdir@
|
top_srcdir = @top_srcdir@
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Definitions for CLVMD server and clients */
|
/* Definitions for CLVMD server and clients */
|
||||||
@@ -76,8 +76,10 @@ static const char CLVMD_SOCKNAME[]= DEFAULT_RUN_DIR "/clvmd.sock";
|
|||||||
#define CLVMD_CMD_SYNC_NAMES 45
|
#define CLVMD_CMD_SYNC_NAMES 45
|
||||||
|
|
||||||
/* Used internally by some callers, but not part of the protocol.*/
|
/* Used internally by some callers, but not part of the protocol.*/
|
||||||
|
#ifndef NODE_ALL
|
||||||
# define NODE_ALL "*"
|
# define NODE_ALL "*"
|
||||||
# define NODE_LOCAL "."
|
# define NODE_LOCAL "."
|
||||||
# define NODE_REMOTE "^"
|
# define NODE_REMOTE "^"
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "clvmd-common.h"
|
#include "clvmd-common.h"
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -154,7 +154,7 @@ static void usage(const char *prog, FILE *file)
|
|||||||
{
|
{
|
||||||
fprintf(file, "Usage: %s [options]\n"
|
fprintf(file, "Usage: %s [options]\n"
|
||||||
" -C Sets debug level (from -d) on all clvmd instances clusterwide\n"
|
" -C Sets debug level (from -d) on all clvmd instances clusterwide\n"
|
||||||
" -d[n] Set debug logging (0:none, 1:stderr (implies -f option), 2:syslog)\n"
|
" -d[<n>] Set debug logging (0:none, 1:stderr (implies -f option), 2:syslog)\n"
|
||||||
" -E<uuid> Take this lock uuid as exclusively locked resource (for restart)\n"
|
" -E<uuid> Take this lock uuid as exclusively locked resource (for restart)\n"
|
||||||
" -f Don't fork, run in the foreground\n"
|
" -f Don't fork, run in the foreground\n"
|
||||||
" -h Show this help information\n"
|
" -h Show this help information\n"
|
||||||
@@ -374,7 +374,7 @@ int main(int argc, char *argv[])
|
|||||||
/* Deal with command-line arguments */
|
/* Deal with command-line arguments */
|
||||||
opterr = 0;
|
opterr = 0;
|
||||||
optind = 0;
|
optind = 0;
|
||||||
while ((opt = getopt_long(argc, argv, "vVhfd:t:RST:CI:E:",
|
while ((opt = getopt_long(argc, argv, "Vhfd:t:RST:CI:E:",
|
||||||
longopts, NULL)) != -1) {
|
longopts, NULL)) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'h':
|
case 'h':
|
||||||
@@ -604,7 +604,10 @@ int main(int argc, char *argv[])
|
|||||||
local_client_head.fd, &local_client_head, newfd->fd, newfd);
|
local_client_head.fd, &local_client_head, newfd->fd, newfd);
|
||||||
|
|
||||||
/* Don't let anyone else to do work until we are started */
|
/* Don't let anyone else to do work until we are started */
|
||||||
pthread_create(&lvm_thread, &stack_attr, lvm_thread_fn, &lvm_params);
|
if (pthread_create(&lvm_thread, &stack_attr, lvm_thread_fn, &lvm_params)) {
|
||||||
|
log_sys_error("pthread_create", "");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
/* Don't start until the LVM thread is ready */
|
/* Don't start until the LVM thread is ready */
|
||||||
pthread_barrier_wait(&lvm_start_barrier);
|
pthread_barrier_wait(&lvm_start_barrier);
|
||||||
@@ -855,12 +858,12 @@ static void main_loop(int cmd_timeout)
|
|||||||
int quorate = clops->is_quorate();
|
int quorate = clops->is_quorate();
|
||||||
int client_count = 0;
|
int client_count = 0;
|
||||||
int max_fd = 0;
|
int max_fd = 0;
|
||||||
|
struct local_client *lastfd = &local_client_head;
|
||||||
|
struct local_client *nextfd = local_client_head.next;
|
||||||
|
|
||||||
/* Wait on the cluster FD and all local sockets/pipes */
|
/* Wait on the cluster FD and all local sockets/pipes */
|
||||||
local_client_head.fd = clops->get_main_cluster_fd();
|
local_client_head.fd = clops->get_main_cluster_fd();
|
||||||
FD_ZERO(&in);
|
FD_ZERO(&in);
|
||||||
struct local_client *lastfd = &local_client_head;
|
|
||||||
struct local_client *nextfd = local_client_head.next;
|
|
||||||
|
|
||||||
for (thisfd = &local_client_head; thisfd; thisfd = thisfd->next) {
|
for (thisfd = &local_client_head; thisfd; thisfd = thisfd->next) {
|
||||||
client_count++;
|
client_count++;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _CLVMD_H
|
#ifndef _CLVMD_H
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "clvmd-common.h"
|
#include "clvmd-common.h"
|
||||||
@@ -291,6 +291,7 @@ static int hold_lock(char *resource, int mode, int flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
lvi->lock_mode = mode;
|
lvi->lock_mode = mode;
|
||||||
|
lvi->lock_id = 0;
|
||||||
status = sync_lock(resource, mode, flags & ~LCKF_CONVERT, &lvi->lock_id);
|
status = sync_lock(resource, mode, flags & ~LCKF_CONVERT, &lvi->lock_id);
|
||||||
saved_errno = errno;
|
saved_errno = errno;
|
||||||
if (status) {
|
if (status) {
|
||||||
@@ -662,7 +663,8 @@ int do_refresh_cache(void)
|
|||||||
|
|
||||||
init_full_scan_done(0);
|
init_full_scan_done(0);
|
||||||
init_ignore_suspended_devices(1);
|
init_ignore_suspended_devices(1);
|
||||||
lvmcache_label_scan(cmd, 2);
|
lvmcache_force_next_label_scan();
|
||||||
|
lvmcache_label_scan(cmd);
|
||||||
dm_pool_empty(cmd->mem);
|
dm_pool_empty(cmd->mem);
|
||||||
|
|
||||||
pthread_mutex_unlock(&lvm_lock);
|
pthread_mutex_unlock(&lvm_lock);
|
||||||
@@ -899,8 +901,12 @@ int init_clvm(struct dm_hash_table *excl_uuid)
|
|||||||
if (!get_initial_state(excl_uuid))
|
if (!get_initial_state(excl_uuid))
|
||||||
log_error("Cannot load initial lock states.");
|
log_error("Cannot load initial lock states.");
|
||||||
|
|
||||||
|
if (!udev_init_library_context())
|
||||||
|
stack;
|
||||||
|
|
||||||
if (!(cmd = create_toolcontext(1, NULL, 0, 1, 1, 1))) {
|
if (!(cmd = create_toolcontext(1, NULL, 0, 1, 1, 1))) {
|
||||||
log_error("Failed to allocate command context");
|
log_error("Failed to allocate command context");
|
||||||
|
udev_fin_library_context();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -927,6 +933,7 @@ void destroy_lvm(void)
|
|||||||
if (cmd) {
|
if (cmd) {
|
||||||
memlock_dec_daemon(cmd);
|
memlock_dec_daemon(cmd);
|
||||||
destroy_toolcontext(cmd);
|
destroy_toolcontext(cmd);
|
||||||
|
udev_fin_library_context();
|
||||||
cmd = NULL;
|
cmd = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Functions in lvm-functions.c */
|
/* Functions in lvm-functions.c */
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* FIXME Remove duplicated functions from this file. */
|
/* FIXME Remove duplicated functions from this file. */
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
#
|
#
|
||||||
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
srcdir = @srcdir@
|
srcdir = @srcdir@
|
||||||
top_srcdir = @top_srcdir@
|
top_srcdir = @top_srcdir@
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
@@ -15,6 +15,7 @@
|
|||||||
#include "link_mon.h"
|
#include "link_mon.h"
|
||||||
#include "local.h"
|
#include "local.h"
|
||||||
|
|
||||||
|
#include <getopt.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
@@ -32,13 +33,48 @@ static void daemonize(void);
|
|||||||
static void init_all(void);
|
static void init_all(void);
|
||||||
static void cleanup_all(void);
|
static void cleanup_all(void);
|
||||||
|
|
||||||
int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
|
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();
|
daemonize();
|
||||||
|
|
||||||
init_all();
|
init_all();
|
||||||
|
|
||||||
/* Parent can now exit, we're ready to handle requests */
|
/* Parent can now exit, we're ready to handle requests */
|
||||||
|
if (!foreground_mode)
|
||||||
kill(getppid(), SIGTERM);
|
kill(getppid(), SIGTERM);
|
||||||
|
|
||||||
LOG_PRINT("Starting cmirrord:");
|
LOG_PRINT("Starting cmirrord:");
|
||||||
@@ -209,6 +245,16 @@ static void daemonize(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
LOG_OPEN("cmirrord", LOG_PID, LOG_DAEMON);
|
LOG_OPEN("cmirrord", LOG_PID, LOG_DAEMON);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* init_all
|
||||||
|
*
|
||||||
|
* Initialize modules. Exit on failure.
|
||||||
|
*/
|
||||||
|
static void init_all(void)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
|
||||||
(void) dm_prepare_selinux_context(CMIRRORD_PIDFILE, S_IFREG);
|
(void) dm_prepare_selinux_context(CMIRRORD_PIDFILE, S_IFREG);
|
||||||
if (dm_create_lockfile(CMIRRORD_PIDFILE) == 0)
|
if (dm_create_lockfile(CMIRRORD_PIDFILE) == 0)
|
||||||
@@ -227,16 +273,6 @@ static void daemonize(void)
|
|||||||
signal(SIGUSR2, &sig_handler);
|
signal(SIGUSR2, &sig_handler);
|
||||||
sigemptyset(&signal_mask);
|
sigemptyset(&signal_mask);
|
||||||
signal_received = 0;
|
signal_received = 0;
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* init_all
|
|
||||||
*
|
|
||||||
* Initialize modules. Exit on failure.
|
|
||||||
*/
|
|
||||||
static void init_all(void)
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
|
|
||||||
if ((r = init_local()) ||
|
if ((r = init_local()) ||
|
||||||
(r = init_cluster())) {
|
(r = init_cluster())) {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
#include "cluster.h"
|
#include "cluster.h"
|
||||||
@@ -104,10 +104,11 @@ static SaVersionT version = { 'B', 1, 1 };
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define DEBUGGING_HISTORY 100
|
#define DEBUGGING_HISTORY 100
|
||||||
|
#define DEBUGGING_BUFLEN 128
|
||||||
#define LOG_SPRINT(cc, f, arg...) do { \
|
#define LOG_SPRINT(cc, f, arg...) do { \
|
||||||
cc->idx++; \
|
cc->idx++; \
|
||||||
cc->idx = cc->idx % DEBUGGING_HISTORY; \
|
cc->idx = cc->idx % DEBUGGING_HISTORY; \
|
||||||
sprintf(cc->debugging[cc->idx], f, ## arg); \
|
snprintf(cc->debugging[cc->idx], DEBUGGING_BUFLEN, f, ## arg); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
static int log_resp_rec = 0;
|
static int log_resp_rec = 0;
|
||||||
@@ -150,7 +151,7 @@ struct clog_cpg {
|
|||||||
uint32_t checkpoint_requesters[MAX_CHECKPOINT_REQUESTERS];
|
uint32_t checkpoint_requesters[MAX_CHECKPOINT_REQUESTERS];
|
||||||
struct checkpoint_data *checkpoint_list;
|
struct checkpoint_data *checkpoint_list;
|
||||||
int idx;
|
int idx;
|
||||||
char debugging[DEBUGGING_HISTORY][128];
|
char debugging[DEBUGGING_HISTORY][DEBUGGING_BUFLEN];
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct dm_list clog_cpg_list;
|
static struct dm_list clog_cpg_list;
|
||||||
@@ -1294,7 +1295,9 @@ static void cpg_join_callback(struct clog_cpg *match,
|
|||||||
uint32_t my_pid = (uint32_t)getpid();
|
uint32_t my_pid = (uint32_t)getpid();
|
||||||
uint32_t lowest = match->lowest_id;
|
uint32_t lowest = match->lowest_id;
|
||||||
struct clog_request *rq;
|
struct clog_request *rq;
|
||||||
char dbuf[32] = { 0 };
|
char dbuf[64] = { 0 };
|
||||||
|
char *dbuf_p = dbuf;
|
||||||
|
size_t dbuf_rem = sizeof dbuf;
|
||||||
|
|
||||||
/* Assign my_cluster_id */
|
/* Assign my_cluster_id */
|
||||||
if ((my_cluster_id == 0xDEAD) && (joined->pid == my_pid))
|
if ((my_cluster_id == 0xDEAD) && (joined->pid == my_pid))
|
||||||
@@ -1310,9 +1313,17 @@ static void cpg_join_callback(struct clog_cpg *match,
|
|||||||
if (joined->nodeid == my_cluster_id)
|
if (joined->nodeid == my_cluster_id)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
for (i = 0; i < member_list_entries - 1; i++)
|
for (i = 0; i < member_list_entries - 1; i++) {
|
||||||
sprintf(dbuf+strlen(dbuf), "%u-", member_list[i].nodeid);
|
int written = snprintf(dbuf_p, dbuf_rem, "%u-", member_list[i].nodeid);
|
||||||
sprintf(dbuf+strlen(dbuf), "(%u)", joined->nodeid);
|
if (written < 0) continue; /* impossible */
|
||||||
|
if ((unsigned)written >= dbuf_rem) {
|
||||||
|
dbuf_rem = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
dbuf_rem -= written;
|
||||||
|
dbuf_p += written;
|
||||||
|
}
|
||||||
|
snprintf(dbuf_p, dbuf_rem, "(%u)", joined->nodeid);
|
||||||
LOG_COND(log_checkpoint, "[%s] Joining node, %u needs checkpoint [%s]",
|
LOG_COND(log_checkpoint, "[%s] Joining node, %u needs checkpoint [%s]",
|
||||||
SHORT_UUID(match->name.value), joined->nodeid, dbuf);
|
SHORT_UUID(match->name.value), joined->nodeid, dbuf);
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
#ifndef _LVM_CLOG_CLUSTER_H
|
#ifndef _LVM_CLOG_CLUSTER_H
|
||||||
#define _LVM_CLOG_CLUSTER_H
|
#define _LVM_CLOG_CLUSTER_H
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
#ifndef _LVM_CLOG_COMMON_H
|
#ifndef _LVM_CLOG_COMMON_H
|
||||||
#define _LVM_CLOG_COMMON_H
|
#define _LVM_CLOG_COMMON_H
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
#include "functions.h"
|
#include "functions.h"
|
||||||
@@ -32,12 +32,13 @@
|
|||||||
#define LOG_OFFSET 2
|
#define LOG_OFFSET 2
|
||||||
|
|
||||||
#define RESYNC_HISTORY 50
|
#define RESYNC_HISTORY 50
|
||||||
|
#define RESYNC_BUFLEN 128
|
||||||
//static char resync_history[RESYNC_HISTORY][128];
|
//static char resync_history[RESYNC_HISTORY][128];
|
||||||
//static int idx = 0;
|
//static int idx = 0;
|
||||||
#define LOG_SPRINT(_lc, f, arg...) do { \
|
#define LOG_SPRINT(_lc, f, arg...) do { \
|
||||||
lc->idx++; \
|
lc->idx++; \
|
||||||
lc->idx = lc->idx % RESYNC_HISTORY; \
|
lc->idx = lc->idx % RESYNC_HISTORY; \
|
||||||
sprintf(lc->resync_history[lc->idx], f, ## arg); \
|
snprintf(lc->resync_history[lc->idx], RESYNC_BUFLEN, f, ## arg); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
struct log_header {
|
struct log_header {
|
||||||
@@ -88,7 +89,7 @@ struct log_c {
|
|||||||
size_t disk_size; /* size of disk_buffer in bytes */
|
size_t disk_size; /* size of disk_buffer in bytes */
|
||||||
void *disk_buffer; /* aligned memory for O_DIRECT */
|
void *disk_buffer; /* aligned memory for O_DIRECT */
|
||||||
int idx;
|
int idx;
|
||||||
char resync_history[RESYNC_HISTORY][128];
|
char resync_history[RESYNC_HISTORY][RESYNC_BUFLEN];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mark_entry {
|
struct mark_entry {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
#ifndef _LVM_CLOG_FUNCTIONS_H
|
#ifndef _LVM_CLOG_FUNCTIONS_H
|
||||||
#define _LVM_CLOG_FUNCTIONS_H
|
#define _LVM_CLOG_FUNCTIONS_H
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
#include "link_mon.h"
|
#include "link_mon.h"
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
#ifndef _LVM_CLOG_LINK_MON_H
|
#ifndef _LVM_CLOG_LINK_MON_H
|
||||||
#define _LVM_CLOG_LINK_MON_H
|
#define _LVM_CLOG_LINK_MON_H
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
#ifndef _LVM_CLOG_LOCAL_H
|
#ifndef _LVM_CLOG_LOCAL_H
|
||||||
#define _LVM_CLOG_LOCAL_H
|
#define _LVM_CLOG_LOCAL_H
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _LVM_CLOG_LOGGING_H
|
#ifndef _LVM_CLOG_LOGGING_H
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
# 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,
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
srcdir = @srcdir@
|
srcdir = @srcdir@
|
||||||
top_srcdir = @top_srcdir@
|
top_srcdir = @top_srcdir@
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __DMEVENTD_DOT_H__
|
#ifndef __DMEVENTD_DOT_H__
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved.
|
* Copyright (C) 2005-2015 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.
|
||||||
*
|
*
|
||||||
@@ -9,12 +9,12 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "dm-logging.h"
|
||||||
#include "dmlib.h"
|
#include "dmlib.h"
|
||||||
#include "libdevmapper-event.h"
|
#include "libdevmapper-event.h"
|
||||||
//#include "libmultilog.h"
|
|
||||||
#include "dmeventd.h"
|
#include "dmeventd.h"
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@@ -23,7 +23,11 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <arpa/inet.h> /* for htonl, ntohl */
|
#include <arpa/inet.h> /* for htonl, ntohl */
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
|
||||||
|
static int _debug_level = 0;
|
||||||
|
static int _use_syslog = 0;
|
||||||
static int _sequence_nr = 0;
|
static int _sequence_nr = 0;
|
||||||
|
|
||||||
struct dm_event_handler {
|
struct dm_event_handler {
|
||||||
@@ -194,7 +198,7 @@ static int _check_message_id(struct dm_event_daemon_message *msg)
|
|||||||
if ((sscanf(msg->data, "%d:%d", &pid, &seq_nr) != 2) ||
|
if ((sscanf(msg->data, "%d:%d", &pid, &seq_nr) != 2) ||
|
||||||
(pid != getpid()) || (seq_nr != _sequence_nr)) {
|
(pid != getpid()) || (seq_nr != _sequence_nr)) {
|
||||||
log_error("Ignoring out-of-sequence reply from dmeventd. "
|
log_error("Ignoring out-of-sequence reply from dmeventd. "
|
||||||
"Expected %d:%d but received %s", getpid(),
|
"Expected %d:%d but received %s.", getpid(),
|
||||||
_sequence_nr, msg->data);
|
_sequence_nr, msg->data);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -229,7 +233,7 @@ static int _daemon_read(struct dm_event_fifos *fifos,
|
|||||||
FD_SET(fifos->server, &fds);
|
FD_SET(fifos->server, &fds);
|
||||||
ret = select(fifos->server + 1, &fds, NULL, NULL, &tval);
|
ret = select(fifos->server + 1, &fds, NULL, NULL, &tval);
|
||||||
if (ret < 0 && errno != EINTR) {
|
if (ret < 0 && errno != EINTR) {
|
||||||
log_error("Unable to read from event server");
|
log_error("Unable to read from event server.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if ((ret == 0) && (i > 4) && !bytes) {
|
if ((ret == 0) && (i > 4) && !bytes) {
|
||||||
@@ -295,7 +299,7 @@ static int _daemon_write(struct dm_event_fifos *fifos,
|
|||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
if (errno == EINTR)
|
if (errno == EINTR)
|
||||||
continue;
|
continue;
|
||||||
log_error("Unable to talk to event daemon");
|
log_error("Unable to talk to event daemon.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
@@ -304,7 +308,7 @@ static int _daemon_write(struct dm_event_fifos *fifos,
|
|||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
if ((errno == EINTR) || (errno == EAGAIN))
|
if ((errno == EINTR) || (errno == EAGAIN))
|
||||||
continue;
|
continue;
|
||||||
log_error("Unable to talk to event daemon");
|
log_error("Unable to talk to event daemon.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -316,7 +320,7 @@ static int _daemon_write(struct dm_event_fifos *fifos,
|
|||||||
FD_SET(fifos->client, &fds);
|
FD_SET(fifos->client, &fds);
|
||||||
ret = select(fifos->client + 1, NULL, &fds, NULL, NULL);
|
ret = select(fifos->client + 1, NULL, &fds, NULL, NULL);
|
||||||
if ((ret < 0) && (errno != EINTR)) {
|
if ((ret < 0) && (errno != EINTR)) {
|
||||||
log_error("Unable to talk to event daemon");
|
log_error("Unable to talk to event daemon.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} while (ret < 1);
|
} while (ret < 1);
|
||||||
@@ -326,7 +330,7 @@ static int _daemon_write(struct dm_event_fifos *fifos,
|
|||||||
if ((errno == EINTR) || (errno == EAGAIN))
|
if ((errno == EINTR) || (errno == EAGAIN))
|
||||||
continue;
|
continue;
|
||||||
else {
|
else {
|
||||||
log_error("Unable to talk to event daemon");
|
log_error("Unable to talk to event daemon.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -356,7 +360,7 @@ int daemon_talk(struct dm_event_fifos *fifos,
|
|||||||
getpid(), _sequence_nr,
|
getpid(), _sequence_nr,
|
||||||
dso_name ? : "-", dev_name ? : "-", evmask, timeout)))
|
dso_name ? : "-", dev_name ? : "-", evmask, timeout)))
|
||||||
< 0) {
|
< 0) {
|
||||||
log_error("_daemon_talk: message allocation failed");
|
log_error("_daemon_talk: message allocation failed.");
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
msg->cmd = cmd;
|
msg->cmd = cmd;
|
||||||
@@ -408,22 +412,49 @@ static int _start_daemon(char *dmeventd_path, struct dm_event_fifos *fifos)
|
|||||||
char default_dmeventd_path[] = DMEVENTD_PATH;
|
char default_dmeventd_path[] = DMEVENTD_PATH;
|
||||||
char *args[] = { dmeventd_path ? : default_dmeventd_path, NULL };
|
char *args[] = { dmeventd_path ? : default_dmeventd_path, NULL };
|
||||||
|
|
||||||
if (stat(fifos->client_path, &statbuf))
|
/*
|
||||||
goto start_server;
|
* FIXME Explicitly verify the code's requirement that client_path is secure:
|
||||||
|
* - All parent directories owned by root without group/other write access unless sticky.
|
||||||
|
*/
|
||||||
|
|
||||||
if (!S_ISFIFO(statbuf.st_mode)) {
|
/* If client fifo path exists, only use it if it is root-owned fifo mode 0600 */
|
||||||
log_error("%s is not a fifo.", fifos->client_path);
|
if ((lstat(fifos->client_path, &statbuf) < 0)) {
|
||||||
|
if (errno == ENOENT)
|
||||||
|
/* Jump ahead if fifo does not already exist. */
|
||||||
|
goto start_server;
|
||||||
|
else {
|
||||||
|
log_sys_error("stat", fifos->client_path);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} else if (!S_ISFIFO(statbuf.st_mode)) {
|
||||||
|
log_error("%s must be a fifo.", fifos->client_path);
|
||||||
|
return 0;
|
||||||
|
} else if (statbuf.st_uid) {
|
||||||
|
log_error("%s must be owned by uid 0.", fifos->client_path);
|
||||||
|
return 0;
|
||||||
|
} else if (statbuf.st_mode & (S_IEXEC | S_IRWXG | S_IRWXO)) {
|
||||||
|
log_error("%s must have mode 0600.", fifos->client_path);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Anyone listening? If not, errno will be ENXIO */
|
/* Anyone listening? If not, errno will be ENXIO */
|
||||||
fifos->client = open(fifos->client_path, O_WRONLY | O_NONBLOCK);
|
fifos->client = open(fifos->client_path, O_WRONLY | O_NONBLOCK);
|
||||||
if (fifos->client >= 0) {
|
if (fifos->client >= 0) {
|
||||||
|
/* Should never happen if all the above checks passed. */
|
||||||
|
if ((fstat(fifos->client, &statbuf) < 0) ||
|
||||||
|
!S_ISFIFO(statbuf.st_mode) || statbuf.st_uid ||
|
||||||
|
(statbuf.st_mode & (S_IEXEC | S_IRWXG | S_IRWXO))) {
|
||||||
|
log_error("%s is no longer a secure root-owned fifo with mode 0600.", fifos->client_path);
|
||||||
|
if (close(fifos->client))
|
||||||
|
log_sys_debug("close", fifos->client_path);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* server is running and listening */
|
/* server is running and listening */
|
||||||
if (close(fifos->client))
|
if (close(fifos->client))
|
||||||
log_sys_debug("close", fifos->client_path);
|
log_sys_debug("close", fifos->client_path);
|
||||||
return 1;
|
return 1;
|
||||||
} else if (errno != ENXIO) {
|
} else if (errno != ENXIO && errno != ENOENT) {
|
||||||
/* problem */
|
/* problem */
|
||||||
log_sys_error("open", fifos->client_path);
|
log_sys_error("open", fifos->client_path);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -444,11 +475,11 @@ static int _start_daemon(char *dmeventd_path, struct dm_event_fifos *fifos)
|
|||||||
|
|
||||||
else if (!pid) {
|
else if (!pid) {
|
||||||
execvp(args[0], args);
|
execvp(args[0], args);
|
||||||
log_error("Unable to exec dmeventd: %s", strerror(errno));
|
log_error("Unable to exec dmeventd: %s.", strerror(errno));
|
||||||
_exit(EXIT_FAILURE);
|
_exit(EXIT_FAILURE);
|
||||||
} else {
|
} else {
|
||||||
if (waitpid(pid, &status, 0) < 0)
|
if (waitpid(pid, &status, 0) < 0)
|
||||||
log_error("Unable to start dmeventd: %s",
|
log_error("Unable to start dmeventd: %s.",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
else if (WEXITSTATUS(status))
|
else if (WEXITSTATUS(status))
|
||||||
log_error("Unable to start dmeventd.");
|
log_error("Unable to start dmeventd.");
|
||||||
@@ -521,7 +552,7 @@ static struct dm_task *_get_device_info(const struct dm_event_handler *dmevh)
|
|||||||
struct dm_info info;
|
struct dm_info info;
|
||||||
|
|
||||||
if (!(dmt = dm_task_create(DM_DEVICE_INFO))) {
|
if (!(dmt = dm_task_create(DM_DEVICE_INFO))) {
|
||||||
log_error("_get_device_info: dm_task creation for info failed");
|
log_error("_get_device_info: dm_task creation for info failed.");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -539,17 +570,17 @@ static struct dm_task *_get_device_info(const struct dm_event_handler *dmevh)
|
|||||||
|
|
||||||
/* FIXME Add name or uuid or devno to messages */
|
/* FIXME Add name or uuid or devno to messages */
|
||||||
if (!dm_task_run(dmt)) {
|
if (!dm_task_run(dmt)) {
|
||||||
log_error("_get_device_info: dm_task_run() failed");
|
log_error("_get_device_info: dm_task_run() failed.");
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dm_task_get_info(dmt, &info)) {
|
if (!dm_task_get_info(dmt, &info)) {
|
||||||
log_error("_get_device_info: failed to get info for device");
|
log_error("_get_device_info: failed to get info for device.");
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!info.exists) {
|
if (!info.exists) {
|
||||||
log_error("_get_device_info: %s%s%s%.0d%s%.0d%s%s: device not found",
|
log_error("_get_device_info: %s%s%s%.0d%s%.0d%s%s: device not found.",
|
||||||
dmevh->uuid ? : "",
|
dmevh->uuid ? : "",
|
||||||
(!dmevh->uuid && dmevh->dev_name) ? dmevh->dev_name : "",
|
(!dmevh->uuid && dmevh->dev_name) ? dmevh->dev_name : "",
|
||||||
(!dmevh->uuid && !dmevh->dev_name && dmevh->major > 0) ? "(" : "",
|
(!dmevh->uuid && !dmevh->dev_name && dmevh->major > 0) ? "(" : "",
|
||||||
@@ -583,8 +614,8 @@ static int _do_event(int cmd, char *dmeventd_path, struct dm_event_daemon_messag
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (!_init_client(dmeventd_path, &fifos)) {
|
if (!_init_client(dmeventd_path, &fifos)) {
|
||||||
stack;
|
ret = -ESRCH;
|
||||||
return -ESRCH;
|
goto_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = daemon_talk(&fifos, msg, DM_EVENT_CMD_HELLO, NULL, NULL, 0, 0);
|
ret = daemon_talk(&fifos, msg, DM_EVENT_CMD_HELLO, NULL, NULL, 0, 0);
|
||||||
@@ -594,7 +625,7 @@ static int _do_event(int cmd, char *dmeventd_path, struct dm_event_daemon_messag
|
|||||||
|
|
||||||
if (!ret)
|
if (!ret)
|
||||||
ret = daemon_talk(&fifos, msg, cmd, dso_name, dev_name, evmask, timeout);
|
ret = daemon_talk(&fifos, msg, cmd, dso_name, dev_name, evmask, timeout);
|
||||||
|
out:
|
||||||
/* what is the opposite of init? */
|
/* what is the opposite of init? */
|
||||||
fini_fifos(&fifos);
|
fini_fifos(&fifos);
|
||||||
|
|
||||||
@@ -618,12 +649,12 @@ int dm_event_register_handler(const struct dm_event_handler *dmevh)
|
|||||||
!strstr(dmevh->dso, "libdevmapper-event-lvm2snapshot.so") &&
|
!strstr(dmevh->dso, "libdevmapper-event-lvm2snapshot.so") &&
|
||||||
!strstr(dmevh->dso, "libdevmapper-event-lvm2mirror.so") &&
|
!strstr(dmevh->dso, "libdevmapper-event-lvm2mirror.so") &&
|
||||||
!strstr(dmevh->dso, "libdevmapper-event-lvm2raid.so"))
|
!strstr(dmevh->dso, "libdevmapper-event-lvm2raid.so"))
|
||||||
log_warn("WARNING: %s: dmeventd plugins are deprecated", dmevh->dso);
|
log_warn("WARNING: %s: dmeventd plugins are deprecated.", dmevh->dso);
|
||||||
|
|
||||||
|
|
||||||
if ((err = _do_event(DM_EVENT_CMD_REGISTER_FOR_EVENT, dmevh->dmeventd_path, &msg,
|
if ((err = _do_event(DM_EVENT_CMD_REGISTER_FOR_EVENT, dmevh->dmeventd_path, &msg,
|
||||||
dmevh->dso, uuid, dmevh->mask, dmevh->timeout)) < 0) {
|
dmevh->dso, uuid, dmevh->mask, dmevh->timeout)) < 0) {
|
||||||
log_error("%s: event registration failed: %s",
|
log_error("%s: event registration failed: %s.",
|
||||||
dm_task_get_name(dmt),
|
dm_task_get_name(dmt),
|
||||||
msg.data ? msg.data : strerror(-err));
|
msg.data ? msg.data : strerror(-err));
|
||||||
ret = 0;
|
ret = 0;
|
||||||
@@ -650,7 +681,7 @@ int dm_event_unregister_handler(const struct dm_event_handler *dmevh)
|
|||||||
|
|
||||||
if ((err = _do_event(DM_EVENT_CMD_UNREGISTER_FOR_EVENT, dmevh->dmeventd_path, &msg,
|
if ((err = _do_event(DM_EVENT_CMD_UNREGISTER_FOR_EVENT, dmevh->dmeventd_path, &msg,
|
||||||
dmevh->dso, uuid, dmevh->mask, dmevh->timeout)) < 0) {
|
dmevh->dso, uuid, dmevh->mask, dmevh->timeout)) < 0) {
|
||||||
log_error("%s: event deregistration failed: %s",
|
log_error("%s: event deregistration failed: %s.",
|
||||||
dm_task_get_name(dmt),
|
dm_task_get_name(dmt),
|
||||||
msg.data ? msg.data : strerror(-err));
|
msg.data ? msg.data : strerror(-err));
|
||||||
ret = 0;
|
ret = 0;
|
||||||
@@ -723,6 +754,7 @@ int dm_event_get_registered_device(struct dm_event_handler *dmevh, int next)
|
|||||||
|
|
||||||
uuid = dm_task_get_uuid(dmt);
|
uuid = dm_task_get_uuid(dmt);
|
||||||
|
|
||||||
|
/* FIXME Distinguish errors connecting to daemon */
|
||||||
if (_do_event(next ? DM_EVENT_CMD_GET_NEXT_REGISTERED_DEVICE :
|
if (_do_event(next ? DM_EVENT_CMD_GET_NEXT_REGISTERED_DEVICE :
|
||||||
DM_EVENT_CMD_GET_REGISTERED_DEVICE, dmevh->dmeventd_path,
|
DM_EVENT_CMD_GET_REGISTERED_DEVICE, dmevh->dmeventd_path,
|
||||||
&msg, dmevh->dso, uuid, dmevh->mask, 0)) {
|
&msg, dmevh->dso, uuid, dmevh->mask, 0)) {
|
||||||
@@ -823,6 +855,79 @@ int dm_event_get_version(struct dm_event_fifos *fifos, int *version) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dm_event_log_set(int debug_level, int use_syslog)
|
||||||
|
{
|
||||||
|
_debug_level = debug_level;
|
||||||
|
_use_syslog = use_syslog;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dm_event_log(const char *subsys, int level, const char *file,
|
||||||
|
int line, int dm_errno_or_class,
|
||||||
|
const char *format, va_list ap)
|
||||||
|
{
|
||||||
|
static pthread_mutex_t _log_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
static time_t start = 0;
|
||||||
|
const char *indent = "";
|
||||||
|
FILE *stream = stdout;
|
||||||
|
int prio;
|
||||||
|
time_t now;
|
||||||
|
|
||||||
|
switch (level & ~(_LOG_STDERR | _LOG_ONCE)) {
|
||||||
|
case _LOG_DEBUG:
|
||||||
|
if (_debug_level < 3)
|
||||||
|
return;
|
||||||
|
prio = LOG_DEBUG;
|
||||||
|
indent = " ";
|
||||||
|
break;
|
||||||
|
case _LOG_INFO:
|
||||||
|
if (_debug_level < 2)
|
||||||
|
return;
|
||||||
|
prio = LOG_INFO;
|
||||||
|
indent = " ";
|
||||||
|
break;
|
||||||
|
case _LOG_NOTICE:
|
||||||
|
if (_debug_level < 1)
|
||||||
|
return;
|
||||||
|
prio = LOG_NOTICE;
|
||||||
|
indent = " ";
|
||||||
|
break;
|
||||||
|
case _LOG_WARN:
|
||||||
|
prio = LOG_WARNING;
|
||||||
|
break;
|
||||||
|
case _LOG_ERR:
|
||||||
|
prio = LOG_ERR;
|
||||||
|
stream = stderr;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
prio = LOG_CRIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Serialize to keep lines readable */
|
||||||
|
pthread_mutex_lock(&_log_mutex);
|
||||||
|
|
||||||
|
if (_use_syslog) {
|
||||||
|
vsyslog(prio, format, ap);
|
||||||
|
} else {
|
||||||
|
now = time(NULL);
|
||||||
|
if (!start)
|
||||||
|
start = now;
|
||||||
|
now -= start;
|
||||||
|
fprintf(stream, "[%2d:%02d] %8x:%-6s%s",
|
||||||
|
(int)now / 60, (int)now % 60,
|
||||||
|
// TODO: Maybe use shorter ID
|
||||||
|
// ((int)(pthread_self()) >> 6) & 0xffff,
|
||||||
|
(int)pthread_self(), subsys,
|
||||||
|
(_debug_level > 3) ? "" : indent);
|
||||||
|
if (_debug_level > 3)
|
||||||
|
fprintf(stream, "%28s:%4d %s", file, line, indent);
|
||||||
|
vfprintf(stream, _(format), ap);
|
||||||
|
fputc('\n', stream);
|
||||||
|
fflush(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&_log_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
#if 0 /* left out for now */
|
#if 0 /* left out for now */
|
||||||
|
|
||||||
static char *_skip_string(char *src, const int delimiter)
|
static char *_skip_string(char *src, const int delimiter)
|
||||||
@@ -856,7 +961,7 @@ int dm_event_get_timeout(const char *device_path, uint32_t *timeout)
|
|||||||
0, 0))) {
|
0, 0))) {
|
||||||
char *p = _skip_string(msg.data, ' ');
|
char *p = _skip_string(msg.data, ' ');
|
||||||
if (!p) {
|
if (!p) {
|
||||||
log_error("malformed reply from dmeventd '%s'\n",
|
log_error("Malformed reply from dmeventd '%s'.",
|
||||||
msg.data);
|
msg.data);
|
||||||
dm_free(msg.data);
|
dm_free(msg.data);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved.
|
* Copyright (C) 2005-2015 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.
|
||||||
*
|
*
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -105,6 +105,25 @@ int dm_event_get_registered_device(struct dm_event_handler *dmevh, int next);
|
|||||||
int dm_event_register_handler(const struct dm_event_handler *dmevh);
|
int dm_event_register_handler(const struct dm_event_handler *dmevh);
|
||||||
int dm_event_unregister_handler(const struct dm_event_handler *dmevh);
|
int dm_event_unregister_handler(const struct dm_event_handler *dmevh);
|
||||||
|
|
||||||
|
/* Set debug level for logging, and whether to log on stdout/stderr or syslog */
|
||||||
|
void dm_event_log_set(int debug_level, int use_syslog);
|
||||||
|
|
||||||
|
/* Log messages acroding to current debug level */
|
||||||
|
__attribute__((format(printf, 6, 0)))
|
||||||
|
void dm_event_log(const char *subsys, int level, const char *file,
|
||||||
|
int line, int dm_errno_or_class,
|
||||||
|
const char *format, va_list ap);
|
||||||
|
/* Macro to route print_log do dm_event_log() */
|
||||||
|
#define DM_EVENT_LOG_FN(subsys) \
|
||||||
|
void print_log(int level, const char *file, int line, int dm_errno_or_class,\
|
||||||
|
const char *format, ...)\
|
||||||
|
{\
|
||||||
|
va_list ap;\
|
||||||
|
va_start(ap, format);\
|
||||||
|
dm_event_log(subsys, level, file, line, dm_errno_or_class, format, ap);\
|
||||||
|
va_end(ap);\
|
||||||
|
}
|
||||||
|
|
||||||
/* Prototypes for DSO interface, see dmeventd.c, struct dso_data for
|
/* Prototypes for DSO interface, see dmeventd.c, struct dso_data for
|
||||||
detailed descriptions. */
|
detailed descriptions. */
|
||||||
// FIXME misuse of bitmask as enum
|
// FIXME misuse of bitmask as enum
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
#
|
#
|
||||||
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
srcdir = @srcdir@
|
srcdir = @srcdir@
|
||||||
top_srcdir = @top_srcdir@
|
top_srcdir = @top_srcdir@
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
#
|
#
|
||||||
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
srcdir = @srcdir@
|
srcdir = @srcdir@
|
||||||
top_srcdir = @top_srcdir@
|
top_srcdir = @top_srcdir@
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2010 Red Hat, Inc. All rights reserved.
|
* Copyright (C) 2010-2015 Red Hat, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* This file is part of LVM2.
|
* This file is part of LVM2.
|
||||||
*
|
*
|
||||||
@@ -9,19 +9,15 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "lib.h"
|
#include "lib.h"
|
||||||
#include "log.h"
|
|
||||||
|
|
||||||
#include "lvm2cmd.h"
|
|
||||||
#include "dmeventd_lvm.h"
|
#include "dmeventd_lvm.h"
|
||||||
|
#include "libdevmapper-event.h"
|
||||||
|
#include "lvm2cmd.h"
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <syslog.h>
|
|
||||||
|
|
||||||
extern int dmeventd_debug;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* register_device() is called first and performs initialisation.
|
* register_device() is called first and performs initialisation.
|
||||||
@@ -36,48 +32,19 @@ static int _register_count = 0;
|
|||||||
static struct dm_pool *_mem_pool = NULL;
|
static struct dm_pool *_mem_pool = NULL;
|
||||||
static void *_lvm_handle = NULL;
|
static void *_lvm_handle = NULL;
|
||||||
|
|
||||||
|
DM_EVENT_LOG_FN("lvm")
|
||||||
|
|
||||||
|
static void _lvm2_print_log(int level, const char *file, int line,
|
||||||
|
int dm_errno_or_class, const char *msg)
|
||||||
|
{
|
||||||
|
print_log(level, file, line, dm_errno_or_class, "%s", msg);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Currently only one event can be processed at a time.
|
* Currently only one event can be processed at a time.
|
||||||
*/
|
*/
|
||||||
static pthread_mutex_t _event_mutex = PTHREAD_MUTEX_INITIALIZER;
|
static pthread_mutex_t _event_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
/*
|
|
||||||
* FIXME Do not pass things directly to syslog, rather use the existing logging
|
|
||||||
* facilities to sort logging ... however that mechanism needs to be somehow
|
|
||||||
* configurable and we don't have that option yet
|
|
||||||
*/
|
|
||||||
static void _temporary_log_fn(int level,
|
|
||||||
const char *file __attribute__((unused)),
|
|
||||||
int line __attribute__((unused)),
|
|
||||||
int dm_errno __attribute__((unused)),
|
|
||||||
const char *message)
|
|
||||||
{
|
|
||||||
level &= ~(_LOG_STDERR | _LOG_ONCE);
|
|
||||||
|
|
||||||
switch (level) {
|
|
||||||
case _LOG_DEBUG:
|
|
||||||
if (dmeventd_debug >= 3)
|
|
||||||
syslog(LOG_DEBUG, "%s", message);
|
|
||||||
break;
|
|
||||||
case _LOG_INFO:
|
|
||||||
if (dmeventd_debug >= 2)
|
|
||||||
syslog(LOG_INFO, "%s", message);
|
|
||||||
break;
|
|
||||||
case _LOG_NOTICE:
|
|
||||||
if (dmeventd_debug >= 1)
|
|
||||||
syslog(LOG_NOTICE, "%s", message);
|
|
||||||
break;
|
|
||||||
case _LOG_WARN:
|
|
||||||
syslog(LOG_WARNING, "%s", message);
|
|
||||||
break;
|
|
||||||
case _LOG_ERR:
|
|
||||||
syslog(LOG_ERR, "%s", message);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
syslog(LOG_CRIT, "%s", message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void dmeventd_lvm2_lock(void)
|
void dmeventd_lvm2_lock(void)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&_event_mutex);
|
pthread_mutex_lock(&_event_mutex);
|
||||||
@@ -94,24 +61,26 @@ int dmeventd_lvm2_init(void)
|
|||||||
|
|
||||||
pthread_mutex_lock(&_register_mutex);
|
pthread_mutex_lock(&_register_mutex);
|
||||||
|
|
||||||
|
if (!_lvm_handle) {
|
||||||
|
lvm2_log_fn(_lvm2_print_log);
|
||||||
|
|
||||||
|
if (!(_lvm_handle = lvm2_init()))
|
||||||
|
goto out;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Need some space for allocations. 1024 should be more
|
* Need some space for allocations. 1024 should be more
|
||||||
* than enough for what we need (device mapper name splitting)
|
* than enough for what we need (device mapper name splitting)
|
||||||
*/
|
*/
|
||||||
if (!_mem_pool && !(_mem_pool = dm_pool_create("mirror_dso", 1024)))
|
if (!_mem_pool && !(_mem_pool = dm_pool_create("mirror_dso", 1024))) {
|
||||||
goto out;
|
lvm2_exit(_lvm_handle);
|
||||||
|
_lvm_handle = NULL;
|
||||||
if (!_lvm_handle) {
|
|
||||||
if (!getenv("LVM_LOG_FILE_EPOCH"))
|
|
||||||
lvm2_log_fn(_temporary_log_fn);
|
|
||||||
if (!(_lvm_handle = lvm2_init())) {
|
|
||||||
dm_pool_destroy(_mem_pool);
|
|
||||||
_mem_pool = NULL;
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
lvm2_disable_dmeventd_monitoring(_lvm_handle);
|
lvm2_disable_dmeventd_monitoring(_lvm_handle);
|
||||||
/* FIXME Temporary: move to dmeventd core */
|
/* FIXME Temporary: move to dmeventd core */
|
||||||
lvm2_run(_lvm_handle, "_memlock_inc");
|
lvm2_run(_lvm_handle, "_memlock_inc");
|
||||||
|
log_debug("lvm plugin initilized.");
|
||||||
}
|
}
|
||||||
|
|
||||||
_register_count++;
|
_register_count++;
|
||||||
@@ -127,11 +96,13 @@ void dmeventd_lvm2_exit(void)
|
|||||||
pthread_mutex_lock(&_register_mutex);
|
pthread_mutex_lock(&_register_mutex);
|
||||||
|
|
||||||
if (!--_register_count) {
|
if (!--_register_count) {
|
||||||
|
log_debug("lvm plugin shuting down.");
|
||||||
lvm2_run(_lvm_handle, "_memlock_dec");
|
lvm2_run(_lvm_handle, "_memlock_dec");
|
||||||
dm_pool_destroy(_mem_pool);
|
dm_pool_destroy(_mem_pool);
|
||||||
_mem_pool = NULL;
|
_mem_pool = NULL;
|
||||||
lvm2_exit(_lvm_handle);
|
lvm2_exit(_lvm_handle);
|
||||||
_lvm_handle = NULL;
|
_lvm_handle = NULL;
|
||||||
|
log_debug("lvm plugin exited.");
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_unlock(&_register_mutex);
|
pthread_mutex_unlock(&_register_mutex);
|
||||||
@@ -154,7 +125,7 @@ int dmeventd_lvm2_command(struct dm_pool *mem, char *buffer, size_t size,
|
|||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (!dm_split_lvm_name(mem, device, &vg, &lv, &layer)) {
|
if (!dm_split_lvm_name(mem, device, &vg, &lv, &layer)) {
|
||||||
syslog(LOG_ERR, "Unable to determine VG name from %s.\n",
|
log_error("Unable to determine VG name from %s.",
|
||||||
device);
|
device);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -169,7 +140,7 @@ int dmeventd_lvm2_command(struct dm_pool *mem, char *buffer, size_t size,
|
|||||||
dm_pool_free(mem, vg);
|
dm_pool_free(mem, vg);
|
||||||
|
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
syslog(LOG_ERR, "Unable to form LVM command. (too long).\n");
|
log_error("Unable to form LVM command. (too long).");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2010 Red Hat, Inc. All rights reserved.
|
* Copyright (C) 2010-2015 Red Hat, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* This file is part of LVM2.
|
* This file is part of LVM2.
|
||||||
*
|
*
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -39,4 +39,36 @@ struct dm_pool *dmeventd_lvm2_pool(void);
|
|||||||
int dmeventd_lvm2_command(struct dm_pool *mem, char *buffer, size_t size,
|
int dmeventd_lvm2_command(struct dm_pool *mem, char *buffer, size_t size,
|
||||||
const char *cmd, const char *device);
|
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 */
|
#endif /* _DMEVENTD_LVMWRAP_H */
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
#
|
#
|
||||||
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
srcdir = @srcdir@
|
srcdir = @srcdir@
|
||||||
top_srcdir = @top_srcdir@
|
top_srcdir = @top_srcdir@
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2012 Red Hat, Inc. All rights reserved.
|
* Copyright (C) 2005-2015 Red Hat, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* This file is part of LVM2.
|
* This file is part of LVM2.
|
||||||
*
|
*
|
||||||
@@ -9,26 +9,31 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "lib.h"
|
#include "lib.h"
|
||||||
|
|
||||||
#include "libdevmapper-event.h"
|
#include "libdevmapper-event.h"
|
||||||
#include "dmeventd_lvm.h"
|
#include "dmeventd_lvm.h"
|
||||||
#include "defaults.h"
|
#include "defaults.h"
|
||||||
|
|
||||||
#include <syslog.h> /* FIXME Replace syslog with multilog */
|
|
||||||
/* FIXME Missing openlog? */
|
|
||||||
/* FIXME Replace most syslogs with log_error() style messages and add complete context. */
|
|
||||||
/* FIXME Reformat to 80 char lines. */
|
/* FIXME Reformat to 80 char lines. */
|
||||||
|
|
||||||
#define ME_IGNORE 0
|
#define ME_IGNORE 0
|
||||||
#define ME_INSYNC 1
|
#define ME_INSYNC 1
|
||||||
#define ME_FAILURE 2
|
#define ME_FAILURE 2
|
||||||
|
|
||||||
static int _process_status_code(const char status_code, const char *dev_name,
|
struct dso_state {
|
||||||
const char *dev_type, int r)
|
struct dm_pool *mem;
|
||||||
|
char cmd_lvscan[512];
|
||||||
|
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
|
* A => Alive - No failures
|
||||||
@@ -38,169 +43,124 @@ static int _process_status_code(const char status_code, const char *dev_name,
|
|||||||
* R => Read - A read failure occurred, mirror data unaffected
|
* R => Read - A read failure occurred, mirror data unaffected
|
||||||
* U => Unclassified failure (bug)
|
* U => Unclassified failure (bug)
|
||||||
*/
|
*/
|
||||||
if (status_code == 'F') {
|
switch (health) {
|
||||||
syslog(LOG_ERR, "%s device %s flush failed.",
|
case DM_STATUS_MIRROR_ALIVE:
|
||||||
dev_type, dev_name);
|
return;
|
||||||
r = ME_FAILURE;
|
case DM_STATUS_MIRROR_FLUSH_FAILED:
|
||||||
} else if (status_code == 'S')
|
log_error("%s device %u:%u flush failed.",
|
||||||
syslog(LOG_ERR, "%s device %s sync failed.",
|
dev_type, major, minor);
|
||||||
dev_type, dev_name);
|
*r = ME_FAILURE;
|
||||||
else if (status_code == 'R')
|
break;
|
||||||
syslog(LOG_ERR, "%s device %s read failed.",
|
case DM_STATUS_MIRROR_SYNC_FAILED:
|
||||||
dev_type, dev_name);
|
log_error("%s device %u:%u sync failed.",
|
||||||
else if (status_code != 'A') {
|
dev_type, major, minor);
|
||||||
syslog(LOG_ERR, "%s device %s has failed (%c).",
|
break;
|
||||||
dev_type, dev_name, status_code);
|
case DM_STATUS_MIRROR_READ_FAILED:
|
||||||
r = ME_FAILURE;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return r;
|
static int _get_mirror_event(struct dso_state *state, char *params)
|
||||||
}
|
|
||||||
|
|
||||||
static int _get_mirror_event(char *params)
|
|
||||||
{
|
{
|
||||||
int i, r = ME_INSYNC;
|
int r = ME_INSYNC;
|
||||||
char **args = NULL;
|
unsigned i;
|
||||||
char *dev_status_str;
|
struct dm_status_mirror *ms;
|
||||||
char *log_status_str;
|
|
||||||
char *sync_str;
|
|
||||||
char *p = NULL;
|
|
||||||
int log_argc, num_devs;
|
|
||||||
|
|
||||||
/*
|
if (!dm_get_status_mirror(state->mem, params, &ms))
|
||||||
* dm core parms: 0 409600 mirror
|
goto_out;
|
||||||
* Mirror core parms: 2 253:4 253:5 400/400
|
|
||||||
* New-style failure params: 1 AA
|
|
||||||
* New-style log params: 3 cluster 253:3 A
|
|
||||||
* or 3 disk 253:3 A
|
|
||||||
* or 1 core
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* number of devices */
|
|
||||||
if (!dm_split_words(params, 1, 0, &p))
|
|
||||||
goto out_parse;
|
|
||||||
|
|
||||||
if (!(num_devs = atoi(p)) ||
|
|
||||||
(num_devs > DEFAULT_MIRROR_MAX_IMAGES) || (num_devs < 0))
|
|
||||||
goto out_parse;
|
|
||||||
p += strlen(p) + 1;
|
|
||||||
|
|
||||||
/* devices names + "400/400" + "1 AA" + 1 or 3 log parms + NULL */
|
|
||||||
args = dm_malloc((num_devs + 7) * sizeof(char *));
|
|
||||||
if (!args || dm_split_words(p, num_devs + 7, 0, args) < num_devs + 5)
|
|
||||||
goto out_parse;
|
|
||||||
|
|
||||||
/* FIXME: Code differs from lib/mirror/mirrored.c */
|
|
||||||
dev_status_str = args[2 + num_devs];
|
|
||||||
log_argc = atoi(args[3 + num_devs]);
|
|
||||||
log_status_str = args[3 + num_devs + log_argc];
|
|
||||||
sync_str = args[num_devs];
|
|
||||||
|
|
||||||
/* Check for bad mirror devices */
|
/* Check for bad mirror devices */
|
||||||
for (i = 0; i < num_devs; i++)
|
for (i = 0; i < ms->dev_count; ++i)
|
||||||
r = _process_status_code(dev_status_str[i], args[i],
|
_process_status_code(ms->devs[i].health,
|
||||||
i ? "Secondary mirror" : "Primary mirror", r);
|
ms->devs[i].major, ms->devs[i].minor,
|
||||||
|
i ? "Secondary mirror" : "Primary mirror", &r);
|
||||||
|
|
||||||
/* Check for bad disk log device */
|
/* Check for bad disk log device */
|
||||||
if (log_argc > 1)
|
for (i = 0; i < ms->log_count; ++i)
|
||||||
r = _process_status_code(log_status_str[0],
|
_process_status_code(ms->logs[i].health,
|
||||||
args[2 + num_devs + log_argc],
|
ms->logs[i].major, ms->logs[i].minor,
|
||||||
"Log", r);
|
"Log", &r);
|
||||||
|
|
||||||
if (r == ME_FAILURE)
|
/* Ignore if not in-sync */
|
||||||
goto out;
|
if ((r == ME_INSYNC) && (ms->insync_regions != ms->total_regions))
|
||||||
|
|
||||||
p = strstr(sync_str, "/");
|
|
||||||
if (p) {
|
|
||||||
p[0] = '\0';
|
|
||||||
if (strcmp(sync_str, p+1))
|
|
||||||
r = ME_IGNORE;
|
r = ME_IGNORE;
|
||||||
p[0] = '/';
|
|
||||||
} else
|
|
||||||
goto out_parse;
|
|
||||||
|
|
||||||
out:
|
dm_pool_free(state->mem, ms);
|
||||||
dm_free(args);
|
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
out_parse:
|
out:
|
||||||
dm_free(args);
|
log_error("Unable to parse mirror status string.");
|
||||||
syslog(LOG_ERR, "Unable to parse mirror status string.");
|
|
||||||
return ME_IGNORE;
|
return ME_IGNORE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _remove_failed_devices(const char *device)
|
static int _remove_failed_devices(const char *cmd_lvscan, const char *cmd_lvconvert)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
#define CMD_SIZE 256 /* FIXME Use system restriction */
|
|
||||||
char cmd_str[CMD_SIZE];
|
|
||||||
|
|
||||||
if (!dmeventd_lvm2_command(dmeventd_lvm2_pool(), cmd_str, sizeof(cmd_str),
|
if (!dmeventd_lvm2_run_with_lock(cmd_lvscan))
|
||||||
"lvscan --cache", device))
|
log_info("Re-scan of mirrored device failed.");
|
||||||
return -1;
|
|
||||||
|
|
||||||
r = dmeventd_lvm2_run(cmd_str);
|
|
||||||
|
|
||||||
if (!r)
|
|
||||||
syslog(LOG_INFO, "Re-scan of mirror device %s failed.", device);
|
|
||||||
|
|
||||||
if (!dmeventd_lvm2_command(dmeventd_lvm2_pool(), cmd_str, sizeof(cmd_str),
|
|
||||||
"lvconvert --config devices{ignore_suspended_devices=1} "
|
|
||||||
"--repair --use-policies", device))
|
|
||||||
return -ENAMETOOLONG; /* FIXME Replace with generic error return - reason for failure has already got logged */
|
|
||||||
|
|
||||||
/* if repair goes OK, report success even if lvscan has failed */
|
/* if repair goes OK, report success even if lvscan has failed */
|
||||||
r = dmeventd_lvm2_run(cmd_str);
|
r = dmeventd_lvm2_run_with_lock(cmd_lvconvert);
|
||||||
|
|
||||||
syslog(LOG_INFO, "Repair of mirrored device %s %s.", device,
|
log_info("Repair of mirrored device %s.",
|
||||||
(r) ? "finished successfully" : "failed");
|
(r) ? "finished successfully" : "failed");
|
||||||
|
|
||||||
return (r) ? 0 : -1;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_event(struct dm_task *dmt,
|
void process_event(struct dm_task *dmt,
|
||||||
enum dm_event_mask event __attribute__((unused)),
|
enum dm_event_mask event __attribute__((unused)),
|
||||||
void **unused __attribute__((unused)))
|
void **user)
|
||||||
{
|
{
|
||||||
|
struct dso_state *state = *user;
|
||||||
void *next = NULL;
|
void *next = NULL;
|
||||||
uint64_t start, length;
|
uint64_t start, length;
|
||||||
char *target_type = NULL;
|
char *target_type = NULL;
|
||||||
char *params;
|
char *params;
|
||||||
const char *device = dm_task_get_name(dmt);
|
const char *device = dm_task_get_name(dmt);
|
||||||
|
|
||||||
dmeventd_lvm2_lock();
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
next = dm_get_next_target(dmt, next, &start, &length,
|
next = dm_get_next_target(dmt, next, &start, &length,
|
||||||
&target_type, ¶ms);
|
&target_type, ¶ms);
|
||||||
|
|
||||||
if (!target_type) {
|
if (!target_type) {
|
||||||
syslog(LOG_INFO, "%s mapping lost.", device);
|
log_info("%s mapping lost.", device);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(target_type, "mirror")) {
|
if (strcmp(target_type, "mirror")) {
|
||||||
syslog(LOG_INFO, "%s has unmirrored portion.", device);
|
log_info("%s has unmirrored portion.", device);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(_get_mirror_event(params)) {
|
switch(_get_mirror_event(state, params)) {
|
||||||
case ME_INSYNC:
|
case ME_INSYNC:
|
||||||
/* FIXME: all we really know is that this
|
/* FIXME: all we really know is that this
|
||||||
_part_ of the device is in sync
|
_part_ of the device is in sync
|
||||||
Also, this is not an error
|
Also, this is not an error
|
||||||
*/
|
*/
|
||||||
syslog(LOG_NOTICE, "%s is now in-sync.", device);
|
log_notice("%s is now in-sync.", device);
|
||||||
break;
|
break;
|
||||||
case ME_FAILURE:
|
case ME_FAILURE:
|
||||||
syslog(LOG_ERR, "Device failure in %s.", device);
|
log_error("Device failure in %s.", device);
|
||||||
if (_remove_failed_devices(device))
|
if (!_remove_failed_devices(state->cmd_lvscan,
|
||||||
|
state->cmd_lvconvert))
|
||||||
/* FIXME Why are all the error return codes unused? Get rid of them? */
|
/* FIXME Why are all the error return codes unused? Get rid of them? */
|
||||||
syslog(LOG_ERR, "Failed to remove faulty devices in %s.",
|
log_error("Failed to remove faulty devices in %s.",
|
||||||
device);
|
device);
|
||||||
/* Should check before warning user that device is now linear
|
/* Should check before warning user that device is now linear
|
||||||
else
|
else
|
||||||
syslog(LOG_NOTICE, "%s is now a linear device.\n",
|
log_notice("%s is now a linear device.",
|
||||||
device);
|
device);
|
||||||
*/
|
*/
|
||||||
break;
|
break;
|
||||||
@@ -208,36 +168,56 @@ void process_event(struct dm_task *dmt,
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* FIXME Provide value then! */
|
/* FIXME Provide value then! */
|
||||||
syslog(LOG_INFO, "Unknown event received.");
|
log_info("Unknown event received.");
|
||||||
}
|
}
|
||||||
} while (next);
|
} while (next);
|
||||||
|
|
||||||
dmeventd_lvm2_unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int register_device(const char *device,
|
int register_device(const char *device,
|
||||||
const char *uuid __attribute__((unused)),
|
const char *uuid __attribute__((unused)),
|
||||||
int major __attribute__((unused)),
|
int major __attribute__((unused)),
|
||||||
int minor __attribute__((unused)),
|
int minor __attribute__((unused)),
|
||||||
void **unused __attribute__((unused)))
|
void **user)
|
||||||
{
|
{
|
||||||
if (!dmeventd_lvm2_init())
|
struct dso_state *state;
|
||||||
return 0;
|
|
||||||
|
|
||||||
syslog(LOG_INFO, "Monitoring mirror device %s for events.", device);
|
if (!dmeventd_lvm2_init_with_pool("mirror_state", state))
|
||||||
|
goto_bad;
|
||||||
|
|
||||||
|
if (!dmeventd_lvm2_command(state->mem, state->cmd_lvscan, sizeof(state->cmd_lvscan),
|
||||||
|
"lvscan --cache", device)) {
|
||||||
|
dmeventd_lvm2_exit_with_pool(state);
|
||||||
|
goto_bad;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dmeventd_lvm2_command(state->mem, state->cmd_lvconvert, sizeof(state->cmd_lvconvert),
|
||||||
|
"lvconvert --repair --use-policies", device)) {
|
||||||
|
dmeventd_lvm2_exit_with_pool(state);
|
||||||
|
goto_bad;
|
||||||
|
}
|
||||||
|
|
||||||
|
*user = state;
|
||||||
|
|
||||||
|
log_info("Monitoring mirror device %s for events.", device);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
bad:
|
||||||
|
log_error("Failed to monitor mirror %s.", device);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int unregister_device(const char *device,
|
int unregister_device(const char *device,
|
||||||
const char *uuid __attribute__((unused)),
|
const char *uuid __attribute__((unused)),
|
||||||
int major __attribute__((unused)),
|
int major __attribute__((unused)),
|
||||||
int minor __attribute__((unused)),
|
int minor __attribute__((unused)),
|
||||||
void **unused __attribute__((unused)))
|
void **user)
|
||||||
{
|
{
|
||||||
syslog(LOG_INFO, "No longer monitoring mirror device %s for events.",
|
struct dso_state *state = *user;
|
||||||
|
|
||||||
|
dmeventd_lvm2_exit_with_pool(state);
|
||||||
|
log_info("No longer monitoring mirror device %s for events.",
|
||||||
device);
|
device);
|
||||||
dmeventd_lvm2_exit();
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
#
|
#
|
||||||
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
srcdir = @srcdir@
|
srcdir = @srcdir@
|
||||||
top_srcdir = @top_srcdir@
|
top_srcdir = @top_srcdir@
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2011 Red Hat, Inc. All rights reserved.
|
* Copyright (C) 2005-2015 Red Hat, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* This file is part of LVM2.
|
* This file is part of LVM2.
|
||||||
*
|
*
|
||||||
@@ -9,172 +9,137 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "lib.h"
|
#include "lib.h"
|
||||||
|
|
||||||
#include "libdevmapper-event.h"
|
|
||||||
#include "dmeventd_lvm.h"
|
#include "dmeventd_lvm.h"
|
||||||
|
#include "libdevmapper-event.h"
|
||||||
|
|
||||||
|
struct dso_state {
|
||||||
|
struct dm_pool *mem;
|
||||||
|
char cmd_lvscan[512];
|
||||||
|
char cmd_lvconvert[512];
|
||||||
|
int failed;
|
||||||
|
};
|
||||||
|
|
||||||
|
DM_EVENT_LOG_FN("raid")
|
||||||
|
|
||||||
#include <syslog.h> /* FIXME Replace syslog with multilog */
|
|
||||||
/* FIXME Missing openlog? */
|
|
||||||
/* FIXME Replace most syslogs with log_error() style messages and add complete context. */
|
|
||||||
/* FIXME Reformat to 80 char lines. */
|
/* FIXME Reformat to 80 char lines. */
|
||||||
|
|
||||||
/*
|
static int _process_raid_event(struct dso_state *state, char *params, const char *device)
|
||||||
* run_repair is a close copy to
|
|
||||||
* plugins/mirror/dmeventd_mirror.c:_remove_failed_devices()
|
|
||||||
*/
|
|
||||||
static int run_repair(const char *device)
|
|
||||||
{
|
{
|
||||||
int r;
|
struct dm_status_raid *status;
|
||||||
#define CMD_SIZE 256 /* FIXME Use system restriction */
|
const char *d;
|
||||||
char cmd_str[CMD_SIZE];
|
|
||||||
|
|
||||||
if (!dmeventd_lvm2_command(dmeventd_lvm2_pool(), cmd_str, sizeof(cmd_str),
|
if (!dm_get_status_raid(state->mem, params, &status)) {
|
||||||
"lvscan --cache", device))
|
log_error("Failed to process status line for %s.", device);
|
||||||
return -1;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
r = dmeventd_lvm2_run(cmd_str);
|
if ((d = strchr(status->dev_health, 'D'))) {
|
||||||
|
if (state->failed)
|
||||||
|
goto out; /* already reported */
|
||||||
|
|
||||||
if (!r)
|
log_error("Device #%d of %s array, %s, has failed.",
|
||||||
syslog(LOG_INFO, "Re-scan of RAID device %s failed.", device);
|
(int)(d - status->dev_health),
|
||||||
|
status->raid_type, device);
|
||||||
|
|
||||||
if (!dmeventd_lvm2_command(dmeventd_lvm2_pool(), cmd_str, sizeof(cmd_str),
|
state->failed = 1;
|
||||||
"lvconvert --config devices{ignore_suspended_devices=1} "
|
if (!dmeventd_lvm2_run_with_lock(state->cmd_lvscan))
|
||||||
"--repair --use-policies", device))
|
log_warn("WARNING: Re-scan of RAID device %s failed.", device);
|
||||||
return -1;
|
|
||||||
|
|
||||||
/* if repair goes OK, report success even if lvscan has failed */
|
/* if repair goes OK, report success even if lvscan has failed */
|
||||||
r = dmeventd_lvm2_run(cmd_str);
|
if (!dmeventd_lvm2_run_with_lock(state->cmd_lvconvert)) {
|
||||||
|
log_info("Repair of RAID device %s failed.", device);
|
||||||
if (!r)
|
dm_pool_free(state->mem, status);
|
||||||
syslog(LOG_INFO, "Repair of RAID device %s failed.", device);
|
|
||||||
|
|
||||||
return (r) ? 0 : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _process_raid_event(char *params, const char *device)
|
|
||||||
{
|
|
||||||
int i, n, failure = 0;
|
|
||||||
char *p, *a[4];
|
|
||||||
char *raid_type;
|
|
||||||
char *num_devices;
|
|
||||||
char *health_chars;
|
|
||||||
char *resync_ratio;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* RAID parms: <raid_type> <#raid_disks> \
|
|
||||||
* <health chars> <resync ratio>
|
|
||||||
*/
|
|
||||||
if (!dm_split_words(params, 4, 0, a)) {
|
|
||||||
syslog(LOG_ERR, "Failed to process status line for %s\n",
|
|
||||||
device);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
raid_type = a[0];
|
|
||||||
num_devices = a[1];
|
|
||||||
health_chars = a[2];
|
|
||||||
resync_ratio = a[3];
|
|
||||||
|
|
||||||
if (!(n = atoi(num_devices))) {
|
|
||||||
syslog(LOG_ERR, "Failed to parse number of devices for %s: %s",
|
|
||||||
device, num_devices);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
|
||||||
switch (health_chars[i]) {
|
|
||||||
case 'A':
|
|
||||||
/* Device is 'A'live and well */
|
|
||||||
case 'a':
|
|
||||||
/* Device is 'a'live, but not yet in-sync */
|
|
||||||
break;
|
|
||||||
case 'D':
|
|
||||||
syslog(LOG_ERR,
|
|
||||||
"Device #%d of %s array, %s, has failed.",
|
|
||||||
i, raid_type, device);
|
|
||||||
failure++;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* Unhandled character returned from kernel */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (failure)
|
|
||||||
return run_repair(device);
|
|
||||||
}
|
|
||||||
|
|
||||||
p = strstr(resync_ratio, "/");
|
|
||||||
if (!p) {
|
|
||||||
syslog(LOG_ERR, "Failed to parse resync_ratio for %s: %s",
|
|
||||||
device, resync_ratio);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
p[0] = '\0';
|
|
||||||
syslog(LOG_INFO, "%s array, %s, is %s in-sync.",
|
|
||||||
raid_type, device, strcmp(resync_ratio, p+1) ? "not" : "now");
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
state->failed = 0;
|
||||||
|
log_info("%s array, %s, is %s in-sync.",
|
||||||
|
status->raid_type, device,
|
||||||
|
(status->insync_regions == status->total_regions) ? "now" : "not");
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
dm_pool_free(state->mem, status);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
void process_event(struct dm_task *dmt,
|
void process_event(struct dm_task *dmt,
|
||||||
enum dm_event_mask event __attribute__((unused)),
|
enum dm_event_mask event __attribute__((unused)),
|
||||||
void **unused __attribute__((unused)))
|
void **user)
|
||||||
{
|
{
|
||||||
|
struct dso_state *state = *user;
|
||||||
void *next = NULL;
|
void *next = NULL;
|
||||||
uint64_t start, length;
|
uint64_t start, length;
|
||||||
char *target_type = NULL;
|
char *target_type = NULL;
|
||||||
char *params;
|
char *params;
|
||||||
const char *device = dm_task_get_name(dmt);
|
const char *device = dm_task_get_name(dmt);
|
||||||
|
|
||||||
dmeventd_lvm2_lock();
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
next = dm_get_next_target(dmt, next, &start, &length,
|
next = dm_get_next_target(dmt, next, &start, &length,
|
||||||
&target_type, ¶ms);
|
&target_type, ¶ms);
|
||||||
|
|
||||||
if (!target_type) {
|
if (!target_type) {
|
||||||
syslog(LOG_INFO, "%s mapping lost.", device);
|
log_info("%s mapping lost.", device);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(target_type, "raid")) {
|
if (strcmp(target_type, "raid")) {
|
||||||
syslog(LOG_INFO, "%s has non-raid portion.", device);
|
log_info("%s has non-raid portion.", device);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_process_raid_event(params, device))
|
if (!_process_raid_event(state, params, device))
|
||||||
syslog(LOG_ERR, "Failed to process event for %s",
|
log_error("Failed to process event for %s.",
|
||||||
device);
|
device);
|
||||||
} while (next);
|
} while (next);
|
||||||
|
|
||||||
dmeventd_lvm2_unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int register_device(const char *device,
|
int register_device(const char *device,
|
||||||
const char *uuid __attribute__((unused)),
|
const char *uuid __attribute__((unused)),
|
||||||
int major __attribute__((unused)),
|
int major __attribute__((unused)),
|
||||||
int minor __attribute__((unused)),
|
int minor __attribute__((unused)),
|
||||||
void **unused __attribute__((unused)))
|
void **user)
|
||||||
{
|
{
|
||||||
if (!dmeventd_lvm2_init())
|
struct dso_state *state;
|
||||||
return 0;
|
|
||||||
|
|
||||||
syslog(LOG_INFO, "Monitoring RAID device %s for events.", device);
|
if (!dmeventd_lvm2_init_with_pool("raid_state", state))
|
||||||
|
goto_bad;
|
||||||
|
|
||||||
|
if (!dmeventd_lvm2_command(state->mem, state->cmd_lvscan, sizeof(state->cmd_lvscan),
|
||||||
|
"lvscan --cache", device) ||
|
||||||
|
!dmeventd_lvm2_command(state->mem, state->cmd_lvconvert, sizeof(state->cmd_lvconvert),
|
||||||
|
"lvconvert --config devices{ignore_suspended_devices=1} "
|
||||||
|
"--repair --use-policies", device)) {
|
||||||
|
dmeventd_lvm2_exit_with_pool(state);
|
||||||
|
goto_bad;
|
||||||
|
}
|
||||||
|
|
||||||
|
*user = state;
|
||||||
|
|
||||||
|
log_info("Monitoring RAID device %s for events.", device);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
bad:
|
||||||
|
log_error("Failed to monitor RAID %s.", device);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int unregister_device(const char *device,
|
int unregister_device(const char *device,
|
||||||
const char *uuid __attribute__((unused)),
|
const char *uuid __attribute__((unused)),
|
||||||
int major __attribute__((unused)),
|
int major __attribute__((unused)),
|
||||||
int minor __attribute__((unused)),
|
int minor __attribute__((unused)),
|
||||||
void **unused __attribute__((unused)))
|
void **user)
|
||||||
{
|
{
|
||||||
syslog(LOG_INFO, "No longer monitoring RAID device %s for events.",
|
struct dso_state *state = *user;
|
||||||
|
|
||||||
|
dmeventd_lvm2_exit_with_pool(state);
|
||||||
|
log_info("No longer monitoring RAID device %s for events.",
|
||||||
device);
|
device);
|
||||||
dmeventd_lvm2_exit();
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
#
|
#
|
||||||
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
srcdir = @srcdir@
|
srcdir = @srcdir@
|
||||||
top_srcdir = @top_srcdir@
|
top_srcdir = @top_srcdir@
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2007-2011 Red Hat, Inc. All rights reserved.
|
* Copyright (C) 2007-2015 Red Hat, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* This file is part of LVM2.
|
* This file is part of LVM2.
|
||||||
*
|
*
|
||||||
@@ -9,35 +9,35 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "lib.h"
|
#include "lib.h"
|
||||||
|
|
||||||
#include "libdevmapper-event.h"
|
|
||||||
#include "dmeventd_lvm.h"
|
#include "dmeventd_lvm.h"
|
||||||
|
#include "libdevmapper-event.h"
|
||||||
|
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <syslog.h> /* FIXME Replace syslog with multilog */
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
/* FIXME Missing openlog? */
|
#include <pthread.h>
|
||||||
|
|
||||||
/* First warning when snapshot is 80% full. */
|
/* First warning when snapshot is 80% full. */
|
||||||
#define WARNING_THRESH 80
|
#define WARNING_THRESH (DM_PERCENT_1 * 80)
|
||||||
/* Run a check every 5%. */
|
/* Run a check every 5%. */
|
||||||
#define CHECK_STEP 5
|
#define CHECK_STEP (DM_PERCENT_1 * 5)
|
||||||
/* Do not bother checking snapshots less than 50% full. */
|
/* Do not bother checking snapshots less than 50% full. */
|
||||||
#define CHECK_MINIMUM 50
|
#define CHECK_MINIMUM (DM_PERCENT_1 * 50)
|
||||||
|
|
||||||
#define UMOUNT_COMMAND "/bin/umount"
|
#define UMOUNT_COMMAND "/bin/umount"
|
||||||
|
|
||||||
struct dso_state {
|
struct dso_state {
|
||||||
struct dm_pool *mem;
|
struct dm_pool *mem;
|
||||||
int percent_check;
|
dm_percent_t percent_check;
|
||||||
uint64_t known_size;
|
uint64_t known_size;
|
||||||
char cmd_str[1024];
|
char cmd_lvextend[512];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
DM_EVENT_LOG_FN("snap")
|
||||||
|
|
||||||
static int _run(const char *cmd, ...)
|
static int _run(const char *cmd, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
@@ -62,7 +62,7 @@ static int _run(const char *cmd, ...)
|
|||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
execvp(cmd, (char **)argv);
|
execvp(cmd, (char **)argv);
|
||||||
syslog(LOG_ERR, "Failed to execute %s: %s.\n", cmd, strerror(errno));
|
log_sys_error("exec", cmd);
|
||||||
exit(127);
|
exit(127);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,18 +81,56 @@ static int _run(const char *cmd, ...)
|
|||||||
|
|
||||||
static int _extend(const char *cmd)
|
static int _extend(const char *cmd)
|
||||||
{
|
{
|
||||||
return dmeventd_lvm2_run(cmd);
|
log_debug("Extending snapshot via %s.", cmd);
|
||||||
|
return dmeventd_lvm2_run_with_lock(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef SNAPSHOT_REMOVE
|
||||||
|
/* Remove invalid snapshot from dm-table */
|
||||||
|
/* Experimental for now and not used by default */
|
||||||
|
static int _remove(const char *uuid)
|
||||||
|
{
|
||||||
|
int r = 1;
|
||||||
|
uint32_t cookie = 0;
|
||||||
|
struct dm_task *dmt;
|
||||||
|
|
||||||
|
if (!(dmt = dm_task_create(DM_DEVICE_REMOVE)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!dm_task_set_uuid(dmt, uuid)) {
|
||||||
|
r = 0;
|
||||||
|
goto_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
dm_task_retry_remove(dmt);
|
||||||
|
|
||||||
|
if (!dm_task_set_cookie(dmt, &cookie, 0)) {
|
||||||
|
r = 0;
|
||||||
|
goto_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dm_task_run(dmt)) {
|
||||||
|
r = 0;
|
||||||
|
goto_out;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
dm_task_destroy(dmt);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
#endif /* SNAPSHOT_REMOVE */
|
||||||
|
|
||||||
static void _umount(const char *device, int major, int minor)
|
static void _umount(const char *device, int major, int minor)
|
||||||
{
|
{
|
||||||
FILE *mounts;
|
FILE *mounts;
|
||||||
char buffer[4096];
|
char buffer[4096];
|
||||||
char *words[3];
|
char *words[3];
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
const char procmounts[] = "/proc/mounts";
|
||||||
|
|
||||||
if (!(mounts = fopen("/proc/mounts", "r"))) {
|
if (!(mounts = fopen(procmounts, "r"))) {
|
||||||
syslog(LOG_ERR, "Could not read /proc/mounts. Not umounting %s.\n", device);
|
log_sys_error("fopen", procmounts);
|
||||||
|
log_error("Not umounting %s.", device);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,21 +150,22 @@ static void _umount(const char *device, int major, int minor)
|
|||||||
if (S_ISBLK(st.st_mode) &&
|
if (S_ISBLK(st.st_mode) &&
|
||||||
major(st.st_rdev) == major &&
|
major(st.st_rdev) == major &&
|
||||||
minor(st.st_rdev) == minor) {
|
minor(st.st_rdev) == minor) {
|
||||||
syslog(LOG_ERR, "Unmounting invalid snapshot %s from %s.\n", device, words[1]);
|
log_error("Unmounting invalid snapshot %s from %s.", device, words[1]);
|
||||||
if (!_run(UMOUNT_COMMAND, "-fl", words[1], NULL))
|
if (!_run(UMOUNT_COMMAND, "-fl", words[1], NULL))
|
||||||
syslog(LOG_ERR, "Failed to umount snapshot %s from %s: %s.\n",
|
log_error("Failed to umount snapshot %s from %s: %s.",
|
||||||
device, words[1], strerror(errno));
|
device, words[1], strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fclose(mounts))
|
if (fclose(mounts))
|
||||||
syslog(LOG_ERR, "Failed to close /proc/mounts.\n");
|
log_sys_error("close", procmounts);
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_event(struct dm_task *dmt,
|
void process_event(struct dm_task *dmt,
|
||||||
enum dm_event_mask event __attribute__((unused)),
|
enum dm_event_mask event __attribute__((unused)),
|
||||||
void **private)
|
void **user)
|
||||||
{
|
{
|
||||||
|
struct dso_state *state = *user;
|
||||||
void *next = NULL;
|
void *next = NULL;
|
||||||
uint64_t start, length;
|
uint64_t start, length;
|
||||||
char *target_type = NULL;
|
char *target_type = NULL;
|
||||||
@@ -134,28 +173,47 @@ void process_event(struct dm_task *dmt,
|
|||||||
struct dm_status_snapshot *status = NULL;
|
struct dm_status_snapshot *status = NULL;
|
||||||
const char *device = dm_task_get_name(dmt);
|
const char *device = dm_task_get_name(dmt);
|
||||||
int percent;
|
int percent;
|
||||||
struct dso_state *state = *private;
|
struct dm_info info;
|
||||||
|
|
||||||
/* No longer monitoring, waiting for remove */
|
/* No longer monitoring, waiting for remove */
|
||||||
if (!state->percent_check)
|
if (!state->percent_check)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
dmeventd_lvm2_lock();
|
|
||||||
|
|
||||||
dm_get_next_target(dmt, next, &start, &length, &target_type, ¶ms);
|
dm_get_next_target(dmt, next, &start, &length, &target_type, ¶ms);
|
||||||
if (!target_type)
|
if (!target_type || strcmp(target_type, "snapshot")) {
|
||||||
goto out;
|
log_error("Target %s is not snapshot.", target_type);
|
||||||
|
|
||||||
if (!dm_get_status_snapshot(state->mem, params, &status))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (status->invalid) {
|
|
||||||
struct dm_info info;
|
|
||||||
if (dm_task_get_info(dmt, &info)) {
|
|
||||||
dmeventd_lvm2_unlock();
|
|
||||||
_umount(device, info.major, info.minor);
|
|
||||||
return;
|
return;
|
||||||
} /* else; too bad, but this is best-effort thing... */
|
}
|
||||||
|
|
||||||
|
if (!dm_get_status_snapshot(state->mem, params, &status)) {
|
||||||
|
log_error("Cannot parse snapshot %s state: %s.", device, params);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the snapshot has been invalidated or we failed to parse
|
||||||
|
* the status string. Report the full status string to syslog.
|
||||||
|
*/
|
||||||
|
if (status->invalid || status->overflow || !status->total_sectors) {
|
||||||
|
log_warn("WARNING: Snapshot %s changed state to: %s and should be removed.",
|
||||||
|
device, params);
|
||||||
|
state->percent_check = 0;
|
||||||
|
if (dm_task_get_info(dmt, &info))
|
||||||
|
_umount(device, info.major, info.minor);
|
||||||
|
#ifdef SNAPSHOT_REMOVE
|
||||||
|
/* Maybe configurable ? */
|
||||||
|
_remove(dm_task_get_uuid(dmt));
|
||||||
|
#endif
|
||||||
|
pthread_kill(pthread_self(), SIGALRM);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length <= (status->used_sectors - status->metadata_sectors)) {
|
||||||
|
/* TODO eventually recognize earlier when room is enough */
|
||||||
|
log_info("Dropping monitoring of fully provisioned snapshot %s.",
|
||||||
|
device);
|
||||||
|
pthread_kill(pthread_self(), SIGALRM);
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Snapshot size had changed. Clear the threshold. */
|
/* Snapshot size had changed. Clear the threshold. */
|
||||||
@@ -164,69 +222,50 @@ void process_event(struct dm_task *dmt,
|
|||||||
state->known_size = status->total_sectors;
|
state->known_size = status->total_sectors;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
percent = dm_make_percent(status->used_sectors, status->total_sectors);
|
||||||
* If the snapshot has been invalidated or we failed to parse
|
|
||||||
* the status string. Report the full status string to syslog.
|
|
||||||
*/
|
|
||||||
if (status->invalid || !status->total_sectors) {
|
|
||||||
syslog(LOG_ERR, "Snapshot %s changed state to: %s\n", device, params);
|
|
||||||
state->percent_check = 0;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
percent = (int) (100 * status->used_sectors / status->total_sectors);
|
|
||||||
if (percent >= state->percent_check) {
|
if (percent >= state->percent_check) {
|
||||||
/* Usage has raised more than CHECK_STEP since the last
|
/* Usage has raised more than CHECK_STEP since the last
|
||||||
time. Run actions. */
|
time. Run actions. */
|
||||||
state->percent_check = (percent / CHECK_STEP) * CHECK_STEP + CHECK_STEP;
|
state->percent_check = (percent / CHECK_STEP) * CHECK_STEP + CHECK_STEP;
|
||||||
|
|
||||||
if (percent >= WARNING_THRESH) /* Print a warning to syslog. */
|
if (percent >= WARNING_THRESH) /* Print a warning to syslog. */
|
||||||
syslog(LOG_WARNING, "Snapshot %s is now %i%% full.\n", device, percent);
|
log_warn("WARNING: Snapshot %s is now %.2f%% full.",
|
||||||
/* Try to extend the snapshot, in accord with user-set policies */
|
device, dm_percent_to_float(percent));
|
||||||
if (!_extend(state->cmd_str))
|
|
||||||
syslog(LOG_ERR, "Failed to extend snapshot %s.\n", device);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* Try to extend the snapshot, in accord with user-set policies */
|
||||||
|
if (!_extend(state->cmd_lvextend))
|
||||||
|
log_error("Failed to extend snapshot %s.", device);
|
||||||
|
}
|
||||||
out:
|
out:
|
||||||
if (status)
|
|
||||||
dm_pool_free(state->mem, status);
|
dm_pool_free(state->mem, status);
|
||||||
dmeventd_lvm2_unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int register_device(const char *device,
|
int register_device(const char *device,
|
||||||
const char *uuid __attribute__((unused)),
|
const char *uuid __attribute__((unused)),
|
||||||
int major __attribute__((unused)),
|
int major __attribute__((unused)),
|
||||||
int minor __attribute__((unused)),
|
int minor __attribute__((unused)),
|
||||||
void **private)
|
void **user)
|
||||||
{
|
{
|
||||||
struct dm_pool *statemem = NULL;
|
|
||||||
struct dso_state *state;
|
struct dso_state *state;
|
||||||
|
|
||||||
if (!dmeventd_lvm2_init())
|
if (!dmeventd_lvm2_init_with_pool("snapshot_state", state))
|
||||||
goto out;
|
goto_bad;
|
||||||
|
|
||||||
if (!(statemem = dm_pool_create("snapshot_state", 512)) ||
|
if (!dmeventd_lvm2_command(state->mem, state->cmd_lvextend,
|
||||||
!(state = dm_pool_zalloc(statemem, sizeof(*state))))
|
sizeof(state->cmd_lvextend),
|
||||||
goto bad;
|
"lvextend --use-policies", device)) {
|
||||||
|
dmeventd_lvm2_exit_with_pool(state);
|
||||||
|
goto_bad;
|
||||||
|
}
|
||||||
|
|
||||||
if (!dmeventd_lvm2_command(statemem, state->cmd_str,
|
|
||||||
sizeof(state->cmd_str),
|
|
||||||
"lvextend --use-policies", device))
|
|
||||||
goto bad;
|
|
||||||
|
|
||||||
state->mem = statemem;
|
|
||||||
state->percent_check = CHECK_MINIMUM;
|
state->percent_check = CHECK_MINIMUM;
|
||||||
*private = state;
|
*user = state;
|
||||||
|
|
||||||
syslog(LOG_INFO, "Monitoring snapshot %s\n", device);
|
log_info("Monitoring snapshot %s.", device);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
bad:
|
bad:
|
||||||
if (statemem)
|
log_error("Failed to monitor snapshot %s.", device);
|
||||||
dm_pool_destroy(statemem);
|
|
||||||
dmeventd_lvm2_exit();
|
|
||||||
out:
|
|
||||||
syslog(LOG_ERR, "Failed to monitor snapshot %s.\n", device);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -235,13 +274,12 @@ int unregister_device(const char *device,
|
|||||||
const char *uuid __attribute__((unused)),
|
const char *uuid __attribute__((unused)),
|
||||||
int major __attribute__((unused)),
|
int major __attribute__((unused)),
|
||||||
int minor __attribute__((unused)),
|
int minor __attribute__((unused)),
|
||||||
void **private)
|
void **user)
|
||||||
{
|
{
|
||||||
struct dso_state *state = *private;
|
struct dso_state *state = *user;
|
||||||
|
|
||||||
syslog(LOG_INFO, "No longer monitoring snapshot %s\n", device);
|
dmeventd_lvm2_exit_with_pool(state);
|
||||||
dm_pool_destroy(state->mem);
|
log_info("No longer monitoring snapshot %s.", device);
|
||||||
dmeventd_lvm2_exit();
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
#
|
#
|
||||||
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
srcdir = @srcdir@
|
srcdir = @srcdir@
|
||||||
top_srcdir = @top_srcdir@
|
top_srcdir = @top_srcdir@
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2011-2013 Red Hat, Inc. All rights reserved.
|
* Copyright (C) 2011-2015 Red Hat, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* This file is part of LVM2.
|
* This file is part of LVM2.
|
||||||
*
|
*
|
||||||
@@ -9,28 +9,36 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "lib.h"
|
#include "lib.h" /* using here lvm log */
|
||||||
|
|
||||||
#include "libdevmapper-event.h"
|
|
||||||
#include "dmeventd_lvm.h"
|
#include "dmeventd_lvm.h"
|
||||||
|
#include "libdevmapper-event.h"
|
||||||
|
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <syslog.h> /* FIXME Replace syslog with multilog */
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
/* FIXME Missing openlog? */
|
#include <pthread.h>
|
||||||
|
|
||||||
/* First warning when thin is 80% full. */
|
/* TODO - move this mountinfo code into library to be reusable */
|
||||||
#define WARNING_THRESH 80
|
#ifdef __linux__
|
||||||
|
# include "kdev_t.h"
|
||||||
|
#else
|
||||||
|
# define MAJOR(x) major((x))
|
||||||
|
# define MINOR(x) minor((x))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* First warning when thin data or metadata is 80% full. */
|
||||||
|
#define WARNING_THRESH (DM_PERCENT_1 * 80)
|
||||||
/* Run a check every 5%. */
|
/* Run a check every 5%. */
|
||||||
#define CHECK_STEP 5
|
#define CHECK_STEP (DM_PERCENT_1 * 5)
|
||||||
/* Do not bother checking thins less than 50% full. */
|
/* Do not bother checking thin data or metadata is less than 50% full. */
|
||||||
#define CHECK_MINIMUM 50
|
#define CHECK_MINIMUM (DM_PERCENT_1 * 50)
|
||||||
|
|
||||||
#define UMOUNT_COMMAND "/bin/umount"
|
#define UMOUNT_COMMAND "/bin/umount"
|
||||||
|
|
||||||
|
#define MAX_FAILS (10)
|
||||||
|
|
||||||
#define THIN_DEBUG 0
|
#define THIN_DEBUG 0
|
||||||
|
|
||||||
struct dso_state {
|
struct dso_state {
|
||||||
@@ -39,18 +47,11 @@ struct dso_state {
|
|||||||
int data_percent_check;
|
int data_percent_check;
|
||||||
uint64_t known_metadata_size;
|
uint64_t known_metadata_size;
|
||||||
uint64_t known_data_size;
|
uint64_t known_data_size;
|
||||||
|
unsigned fails;
|
||||||
char cmd_str[1024];
|
char cmd_str[1024];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
DM_EVENT_LOG_FN("thin")
|
||||||
/* TODO - move this mountinfo code into library to be reusable */
|
|
||||||
#ifdef __linux__
|
|
||||||
# include "kdev_t.h"
|
|
||||||
#else
|
|
||||||
# define MAJOR(x) major((x))
|
|
||||||
# define MINOR(x) minor((x))
|
|
||||||
# define MKDEV(x,y) makedev((x),(y))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Get dependencies for device, and try to find matching device */
|
/* Get dependencies for device, and try to find matching device */
|
||||||
static int _has_deps(const char *name, int tp_major, int tp_minor, int *dev_minor)
|
static int _has_deps(const char *name, int tp_major, int tp_minor, int *dev_minor)
|
||||||
@@ -93,7 +94,7 @@ static int _has_deps(const char *name, int tp_major, int tp_minor, int *dev_mino
|
|||||||
{
|
{
|
||||||
char dev_name[PATH_MAX];
|
char dev_name[PATH_MAX];
|
||||||
if (dm_device_get_name(major, minor, 0, dev_name, sizeof(dev_name)))
|
if (dm_device_get_name(major, minor, 0, dev_name, sizeof(dev_name)))
|
||||||
syslog(LOG_DEBUG, "Found %s (%u:%u) depends on %s",
|
log_debug("Found %s (%u:%u) depends on %s.",
|
||||||
name, major, *dev_minor, dev_name);
|
name, major, *dev_minor, dev_name);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -141,14 +142,6 @@ out:
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _extend(struct dso_state *state)
|
|
||||||
{
|
|
||||||
#if THIN_DEBUG
|
|
||||||
syslog(LOG_INFO, "dmeventd executes: %s.\n", state->cmd_str);
|
|
||||||
#endif
|
|
||||||
return dmeventd_lvm2_run(state->cmd_str);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _run(const char *cmd, ...)
|
static int _run(const char *cmd, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
@@ -173,7 +166,7 @@ static int _run(const char *cmd, ...)
|
|||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
execvp(cmd, (char **)argv);
|
execvp(cmd, (char **)argv);
|
||||||
syslog(LOG_ERR, "Failed to execute %s: %s.\n", cmd, strerror(errno));
|
log_sys_error("exec", cmd);
|
||||||
exit(127);
|
exit(127);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,9 +184,9 @@ static int _run(const char *cmd, ...)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct mountinfo_s {
|
struct mountinfo_s {
|
||||||
|
const char *device;
|
||||||
struct dm_info info;
|
struct dm_info info;
|
||||||
dm_bitset_t minors; /* Bitset for active thin pool minors */
|
dm_bitset_t minors; /* Bitset for active thin pool minors */
|
||||||
const char *device;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int _umount_device(char *buffer, unsigned major, unsigned minor,
|
static int _umount_device(char *buffer, unsigned major, unsigned minor,
|
||||||
@@ -202,10 +195,10 @@ static int _umount_device(char *buffer, unsigned major, unsigned minor,
|
|||||||
struct mountinfo_s *data = cb_data;
|
struct mountinfo_s *data = cb_data;
|
||||||
|
|
||||||
if ((major == data->info.major) && dm_bit(data->minors, minor)) {
|
if ((major == data->info.major) && dm_bit(data->minors, minor)) {
|
||||||
syslog(LOG_INFO, "Unmounting thin volume %s from %s.\n",
|
log_info("Unmounting thin volume %s from %s.",
|
||||||
data->device, target);
|
data->device, target);
|
||||||
if (!_run(UMOUNT_COMMAND, "-fl", target, NULL))
|
if (!_run(UMOUNT_COMMAND, "-fl", target, NULL))
|
||||||
syslog(LOG_ERR, "Failed to umount thin %s from %s: %s.\n",
|
log_error("Failed to umount thin %s from %s: %s.",
|
||||||
data->device, target, strerror(errno));
|
data->device, target, strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,76 +209,92 @@ static int _umount_device(char *buffer, unsigned major, unsigned minor,
|
|||||||
* Find all thin pool users and try to umount them.
|
* Find all thin pool users and try to umount them.
|
||||||
* TODO: work with read-only thin pool support
|
* TODO: work with read-only thin pool support
|
||||||
*/
|
*/
|
||||||
static void _umount(struct dm_task *dmt, const char *device)
|
static void _umount(struct dm_task *dmt)
|
||||||
{
|
{
|
||||||
/* TODO: Convert to use hash to reduce memory usage */
|
/* TODO: Convert to use hash to reduce memory usage */
|
||||||
static const size_t MINORS = (1U << 20); /* 20 bit */
|
static const size_t MINORS = (1U << 20); /* 20 bit */
|
||||||
struct mountinfo_s data = {
|
struct mountinfo_s data = { NULL };
|
||||||
.device = device,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!dm_task_get_info(dmt, &data.info))
|
if (!dm_task_get_info(dmt, &data.info))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
dmeventd_lvm2_unlock();
|
data.device = dm_task_get_name(dmt);
|
||||||
|
|
||||||
if (!(data.minors = dm_bitset_create(NULL, MINORS))) {
|
if (!(data.minors = dm_bitset_create(NULL, MINORS))) {
|
||||||
syslog(LOG_ERR, "Failed to allocate bitset. Not unmounting %s.\n", device);
|
log_error("Failed to allocate bitset. Not unmounting %s.", data.device);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_find_all_devs(data.minors, data.info.major, data.info.minor)) {
|
if (!_find_all_devs(data.minors, data.info.major, data.info.minor)) {
|
||||||
syslog(LOG_ERR, "Failed to detect mounted volumes for %s.\n", device);
|
log_error("Failed to detect mounted volumes for %s.", data.device);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dm_mountinfo_read(_umount_device, &data)) {
|
if (!dm_mountinfo_read(_umount_device, &data)) {
|
||||||
syslog(LOG_ERR, "Could not parse mountinfo file.\n");
|
log_error("Could not parse mountinfo file.");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (data.minors)
|
if (data.minors)
|
||||||
dm_bitset_destroy(data.minors);
|
dm_bitset_destroy(data.minors);
|
||||||
dmeventd_lvm2_lock();
|
}
|
||||||
|
|
||||||
|
static void _use_policy(struct dm_task *dmt, struct dso_state *state)
|
||||||
|
{
|
||||||
|
#if THIN_DEBUG
|
||||||
|
log_info("dmeventd executes: %s.", state->cmd_str);
|
||||||
|
#endif
|
||||||
|
if (!dmeventd_lvm2_run_with_lock(state->cmd_str)) {
|
||||||
|
log_error("Failed to extend thin pool %s.",
|
||||||
|
dm_task_get_name(dmt));
|
||||||
|
_umount(dmt);
|
||||||
|
state->fails++;
|
||||||
|
} else
|
||||||
|
state->fails = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_event(struct dm_task *dmt,
|
void process_event(struct dm_task *dmt,
|
||||||
enum dm_event_mask event __attribute__((unused)),
|
enum dm_event_mask event __attribute__((unused)),
|
||||||
void **private)
|
void **user)
|
||||||
{
|
{
|
||||||
const char *device = dm_task_get_name(dmt);
|
const char *device = dm_task_get_name(dmt);
|
||||||
int percent;
|
int percent;
|
||||||
struct dso_state *state = *private;
|
struct dso_state *state = *user;
|
||||||
struct dm_status_thin_pool *tps = NULL;
|
struct dm_status_thin_pool *tps = NULL;
|
||||||
void *next = NULL;
|
void *next = NULL;
|
||||||
uint64_t start, length;
|
uint64_t start, length;
|
||||||
char *target_type = NULL;
|
char *target_type = NULL;
|
||||||
char *params;
|
char *params;
|
||||||
|
int needs_policy = 0;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* No longer monitoring, waiting for remove */
|
/* No longer monitoring, waiting for remove */
|
||||||
if (!state->meta_percent_check && !state->data_percent_check)
|
if (!state->meta_percent_check && !state->data_percent_check)
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
dmeventd_lvm2_lock();
|
if (event & DM_EVENT_DEVICE_ERROR) {
|
||||||
|
/* Error -> no need to check and do instant resize */
|
||||||
|
_use_policy(dmt, state);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
dm_get_next_target(dmt, next, &start, &length, &target_type, ¶ms);
|
dm_get_next_target(dmt, next, &start, &length, &target_type, ¶ms);
|
||||||
|
|
||||||
if (!target_type || (strcmp(target_type, "thin-pool") != 0)) {
|
if (!target_type || (strcmp(target_type, "thin-pool") != 0)) {
|
||||||
syslog(LOG_ERR, "Invalid target type.\n");
|
log_error("Invalid target type.");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dm_get_status_thin_pool(state->mem, params, &tps)) {
|
if (!dm_get_status_thin_pool(state->mem, params, &tps)) {
|
||||||
syslog(LOG_ERR, "Failed to parse status.\n");
|
log_error("Failed to parse status.");
|
||||||
_umount(dmt, device);
|
_umount(dmt);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if THIN_DEBUG
|
#if THIN_DEBUG
|
||||||
syslog(LOG_INFO, "%p: Got status %" PRIu64 " / %" PRIu64
|
log_debug("Thin pool status " FMTu64 "/" FMTu64 " "
|
||||||
" %" PRIu64 " / %" PRIu64 ".\n", state,
|
FMTu64 "/" FMTu64 ".",
|
||||||
tps->used_metadata_blocks, tps->total_metadata_blocks,
|
tps->used_metadata_blocks, tps->total_metadata_blocks,
|
||||||
tps->used_data_blocks, tps->total_data_blocks);
|
tps->used_data_blocks, tps->total_data_blocks);
|
||||||
#endif
|
#endif
|
||||||
@@ -301,7 +310,7 @@ void process_event(struct dm_task *dmt,
|
|||||||
state->known_data_size = tps->total_data_blocks;
|
state->known_data_size = tps->total_data_blocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
percent = 100 * tps->used_metadata_blocks / tps->total_metadata_blocks;
|
percent = dm_make_percent(tps->used_metadata_blocks, tps->total_metadata_blocks);
|
||||||
if (percent >= state->metadata_percent_check) {
|
if (percent >= state->metadata_percent_check) {
|
||||||
/*
|
/*
|
||||||
* Usage has raised more than CHECK_STEP since the last
|
* Usage has raised more than CHECK_STEP since the last
|
||||||
@@ -311,18 +320,12 @@ void process_event(struct dm_task *dmt,
|
|||||||
|
|
||||||
/* FIXME: extension of metadata needs to be written! */
|
/* FIXME: extension of metadata needs to be written! */
|
||||||
if (percent >= WARNING_THRESH) /* Print a warning to syslog. */
|
if (percent >= WARNING_THRESH) /* Print a warning to syslog. */
|
||||||
syslog(LOG_WARNING, "Thin metadata %s is now %i%% full.\n",
|
log_warn("WARNING: Thin pool %s metadata is now %.2f%% full.",
|
||||||
device, percent);
|
device, dm_percent_to_float(percent));
|
||||||
/* Try to extend the metadata, in accord with user-set policies */
|
needs_policy = 1;
|
||||||
if (!_extend(state)) {
|
|
||||||
syslog(LOG_ERR, "Failed to extend thin metadata %s.\n",
|
|
||||||
device);
|
|
||||||
_umount(dmt, device);
|
|
||||||
}
|
|
||||||
/* FIXME: hmm READ-ONLY switch should happen in error path */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
percent = 100 * tps->used_data_blocks / tps->total_data_blocks;
|
percent = dm_make_percent(tps->used_data_blocks, tps->total_data_blocks);
|
||||||
if (percent >= state->data_percent_check) {
|
if (percent >= state->data_percent_check) {
|
||||||
/*
|
/*
|
||||||
* Usage has raised more than CHECK_STEP since
|
* Usage has raised more than CHECK_STEP since
|
||||||
@@ -331,56 +334,53 @@ void process_event(struct dm_task *dmt,
|
|||||||
state->data_percent_check = (percent / CHECK_STEP) * CHECK_STEP + CHECK_STEP;
|
state->data_percent_check = (percent / CHECK_STEP) * CHECK_STEP + CHECK_STEP;
|
||||||
|
|
||||||
if (percent >= WARNING_THRESH) /* Print a warning to syslog. */
|
if (percent >= WARNING_THRESH) /* Print a warning to syslog. */
|
||||||
syslog(LOG_WARNING, "Thin %s is now %i%% full.\n", device, percent);
|
log_warn("WARNING: Thin pool %s data is now %.2f%% full.",
|
||||||
/* Try to extend the thin data, in accord with user-set policies */
|
device, dm_percent_to_float(percent));
|
||||||
if (!_extend(state)) {
|
needs_policy = 1;
|
||||||
syslog(LOG_ERR, "Failed to extend thin %s.\n", device);
|
|
||||||
state->data_percent_check = 0;
|
|
||||||
_umount(dmt, device);
|
|
||||||
}
|
|
||||||
/* FIXME: hmm READ-ONLY switch should happen in error path */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (needs_policy)
|
||||||
|
_use_policy(dmt, state);
|
||||||
out:
|
out:
|
||||||
if (tps)
|
if (tps)
|
||||||
dm_pool_free(state->mem, tps);
|
dm_pool_free(state->mem, tps);
|
||||||
|
|
||||||
dmeventd_lvm2_unlock();
|
if (state->fails >= MAX_FAILS) {
|
||||||
|
log_warn("WARNING: Dropping monitoring of %s. "
|
||||||
|
"lvm2 command fails too often (%u times in raw).",
|
||||||
|
device, state->fails);
|
||||||
|
pthread_kill(pthread_self(), SIGALRM);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int register_device(const char *device,
|
int register_device(const char *device,
|
||||||
const char *uuid __attribute__((unused)),
|
const char *uuid __attribute__((unused)),
|
||||||
int major __attribute__((unused)),
|
int major __attribute__((unused)),
|
||||||
int minor __attribute__((unused)),
|
int minor __attribute__((unused)),
|
||||||
void **private)
|
void **user)
|
||||||
{
|
{
|
||||||
struct dm_pool *statemem = NULL;
|
|
||||||
struct dso_state *state;
|
struct dso_state *state;
|
||||||
|
|
||||||
if (!dmeventd_lvm2_init())
|
if (!dmeventd_lvm2_init_with_pool("thin_pool_state", state))
|
||||||
goto bad;
|
goto_bad;
|
||||||
|
|
||||||
if (!(statemem = dm_pool_create("thin_pool_state", 2048)) ||
|
if (!dmeventd_lvm2_command(state->mem, state->cmd_str,
|
||||||
!(state = dm_pool_zalloc(statemem, sizeof(*state))) ||
|
|
||||||
!dmeventd_lvm2_command(statemem, state->cmd_str,
|
|
||||||
sizeof(state->cmd_str),
|
sizeof(state->cmd_str),
|
||||||
"lvextend --use-policies",
|
"lvextend --use-policies",
|
||||||
device)) {
|
device)) {
|
||||||
if (statemem)
|
dmeventd_lvm2_exit_with_pool(state);
|
||||||
dm_pool_destroy(statemem);
|
goto_bad;
|
||||||
dmeventd_lvm2_exit();
|
|
||||||
goto bad;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
state->mem = statemem;
|
|
||||||
state->metadata_percent_check = CHECK_MINIMUM;
|
state->metadata_percent_check = CHECK_MINIMUM;
|
||||||
state->data_percent_check = CHECK_MINIMUM;
|
state->data_percent_check = CHECK_MINIMUM;
|
||||||
*private = state;
|
*user = state;
|
||||||
|
|
||||||
syslog(LOG_INFO, "Monitoring thin %s.\n", device);
|
log_info("Monitoring thin %s.", device);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
bad:
|
bad:
|
||||||
syslog(LOG_ERR, "Failed to monitor thin %s.\n", device);
|
log_error("Failed to monitor thin %s.", device);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -389,13 +389,12 @@ int unregister_device(const char *device,
|
|||||||
const char *uuid __attribute__((unused)),
|
const char *uuid __attribute__((unused)),
|
||||||
int major __attribute__((unused)),
|
int major __attribute__((unused)),
|
||||||
int minor __attribute__((unused)),
|
int minor __attribute__((unused)),
|
||||||
void **private)
|
void **user)
|
||||||
{
|
{
|
||||||
struct dso_state *state = *private;
|
struct dso_state *state = *user;
|
||||||
|
|
||||||
syslog(LOG_INFO, "No longer monitoring thin %s.\n", device);
|
dmeventd_lvm2_exit_with_pool(state);
|
||||||
dm_pool_destroy(state->mem);
|
log_info("No longer monitoring thin %s.", device);
|
||||||
dmeventd_lvm2_exit();
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
# 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,
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
srcdir = @srcdir@
|
srcdir = @srcdir@
|
||||||
top_srcdir = @top_srcdir@
|
top_srcdir = @top_srcdir@
|
||||||
@@ -45,6 +45,8 @@ lvmetactl: lvmetactl.o $(top_builddir)/libdaemon/client/libdaemonclient.a \
|
|||||||
$(top_builddir)/libdaemon/server/libdaemonserver.a
|
$(top_builddir)/libdaemon/server/libdaemonserver.a
|
||||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ lvmetactl.o $(LVMLIBS)
|
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ lvmetactl.o $(LVMLIBS)
|
||||||
|
|
||||||
|
CLEAN_TARGETS += lvmetactl.o
|
||||||
|
|
||||||
# TODO: No idea. No idea how to test either.
|
# TODO: No idea. No idea how to test either.
|
||||||
#ifneq ("$(CFLOW_CMD)", "")
|
#ifneq ("$(CFLOW_CMD)", "")
|
||||||
#CFLOW_SOURCES = $(addprefix $(srcdir)/, $(SOURCES))
|
#CFLOW_SOURCES = $(addprefix $(srcdir)/, $(SOURCES))
|
||||||
|
|||||||
@@ -34,16 +34,16 @@ int main(int argc, char **argv)
|
|||||||
int ver;
|
int ver;
|
||||||
|
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
printf("lvmeta dump\n");
|
printf("lvmetactl dump\n");
|
||||||
printf("lvmeta pv_list\n");
|
printf("lvmetactl pv_list\n");
|
||||||
printf("lvmeta vg_list\n");
|
printf("lvmetactl vg_list\n");
|
||||||
printf("lvmeta vg_lookup_name <name>\n");
|
printf("lvmetactl vg_lookup_name <name>\n");
|
||||||
printf("lvmeta vg_lookup_uuid <uuid>\n");
|
printf("lvmetactl vg_lookup_uuid <uuid>\n");
|
||||||
printf("lvmeta pv_lookup_uuid <uuid>\n");
|
printf("lvmetactl pv_lookup_uuid <uuid>\n");
|
||||||
printf("lvmeta set_global_invalid 0|1\n");
|
printf("lvmetactl set_global_invalid 0|1\n");
|
||||||
printf("lvmeta get_global_invalid\n");
|
printf("lvmetactl get_global_invalid\n");
|
||||||
printf("lvmeta set_vg_version <uuid> <version>\n");
|
printf("lvmetactl set_vg_version <uuid> <name> <version>\n");
|
||||||
printf("lvmeta vg_lock_type <uuid>\n");
|
printf("lvmetactl vg_lock_type <uuid>\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ int main(int argc, char **argv)
|
|||||||
val = atoi(argv[2]);
|
val = atoi(argv[2]);
|
||||||
|
|
||||||
reply = daemon_send_simple(h, "set_global_info",
|
reply = daemon_send_simple(h, "set_global_info",
|
||||||
"global_invalid = %d", val,
|
"global_invalid = " FMTd64, (int64_t) val,
|
||||||
"token = %s", "skip",
|
"token = %s", "skip",
|
||||||
NULL);
|
NULL);
|
||||||
print_reply(reply);
|
print_reply(reply);
|
||||||
@@ -89,18 +89,43 @@ int main(int argc, char **argv)
|
|||||||
printf("%s\n", reply.buffer.mem);
|
printf("%s\n", reply.buffer.mem);
|
||||||
|
|
||||||
} else if (!strcmp(cmd, "set_vg_version")) {
|
} else if (!strcmp(cmd, "set_vg_version")) {
|
||||||
if (argc < 4) {
|
if (argc < 5) {
|
||||||
printf("set_vg_version <uuid> <ver>\n");
|
printf("set_vg_version <uuid> <name> <ver>\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
uuid = argv[2];
|
uuid = argv[2];
|
||||||
ver = atoi(argv[3]);
|
name = argv[3];
|
||||||
|
ver = atoi(argv[4]);
|
||||||
|
|
||||||
|
if ((strlen(uuid) == 1) && (uuid[0] == '-'))
|
||||||
|
uuid = NULL;
|
||||||
|
if ((strlen(name) == 1) && (name[0] == '-'))
|
||||||
|
name = NULL;
|
||||||
|
|
||||||
|
if (uuid && name) {
|
||||||
reply = daemon_send_simple(h, "set_vg_info",
|
reply = daemon_send_simple(h, "set_vg_info",
|
||||||
"uuid = %s", uuid,
|
"uuid = %s", uuid,
|
||||||
"version = %d", ver,
|
"name = %s", name,
|
||||||
|
"version = " FMTd64, (int64_t) ver,
|
||||||
"token = %s", "skip",
|
"token = %s", "skip",
|
||||||
NULL);
|
NULL);
|
||||||
|
} else if (uuid) {
|
||||||
|
reply = daemon_send_simple(h, "set_vg_info",
|
||||||
|
"uuid = %s", uuid,
|
||||||
|
"version = " FMTd64, (int64_t) ver,
|
||||||
|
"token = %s", "skip",
|
||||||
|
NULL);
|
||||||
|
} else if (name) {
|
||||||
|
reply = daemon_send_simple(h, "set_vg_info",
|
||||||
|
"name = %s", name,
|
||||||
|
"version = " FMTd64, (int64_t) ver,
|
||||||
|
"token = %s", "skip",
|
||||||
|
NULL);
|
||||||
|
} else {
|
||||||
|
printf("name or uuid required\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
print_reply(reply);
|
print_reply(reply);
|
||||||
|
|
||||||
} else if (!strcmp(cmd, "vg_lookup_name")) {
|
} else if (!strcmp(cmd, "vg_lookup_name")) {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _LVM_LVMETAD_CLIENT_H
|
#ifndef _LVM_LVMETAD_CLIENT_H
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
#include "tool.h"
|
#include "tool.h"
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
# 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,
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
srcdir = @srcdir@
|
srcdir = @srcdir@
|
||||||
top_srcdir = @top_srcdir@
|
top_srcdir = @top_srcdir@
|
||||||
|
|||||||
@@ -18,7 +18,6 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
|
|
||||||
@@ -151,13 +150,12 @@ static void format_info_r(char *line, char *r_name_out, char *r_type_out)
|
|||||||
sscanf(line, "info=r name=%s type=%s mode=%s %s version=%u",
|
sscanf(line, "info=r name=%s type=%s mode=%s %s version=%u",
|
||||||
r_name, r_type, mode, sh_count, &ver);
|
r_name, r_type, mode, sh_count, &ver);
|
||||||
|
|
||||||
/* when mode is not un, wait and print each lk line */
|
|
||||||
|
|
||||||
if (strcmp(mode, "un")) {
|
|
||||||
strcpy(r_name_out, r_name);
|
strcpy(r_name_out, r_name);
|
||||||
strcpy(r_type_out, r_type);
|
strcpy(r_type_out, r_type);
|
||||||
|
|
||||||
|
/* when mode is not un, wait and print each lk line */
|
||||||
|
if (strcmp(mode, "un"))
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
/* when mode is un, there will be no lk lines, so print now */
|
/* when mode is un, there will be no lk lines, so print now */
|
||||||
|
|
||||||
@@ -229,7 +227,7 @@ static void format_info_r_action(char *line, char *r_name, char *r_type)
|
|||||||
find_client_info(client_id, &pid, cl_name);
|
find_client_info(client_id, &pid, cl_name);
|
||||||
|
|
||||||
if (strcmp(op, "lock")) {
|
if (strcmp(op, "lock")) {
|
||||||
printf("OP %s pid %u (%s)", op, pid, cl_name);
|
printf("OP %s pid %u (%s)\n", op, pid, cl_name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -380,6 +378,7 @@ static int setup_dump_socket(void)
|
|||||||
|
|
||||||
rv = bind(s, (struct sockaddr *) &dump_addr, dump_addrlen);
|
rv = bind(s, (struct sockaddr *) &dump_addr, dump_addrlen);
|
||||||
if (rv < 0) {
|
if (rv < 0) {
|
||||||
|
rv = -errno;
|
||||||
if (!close(s))
|
if (!close(s))
|
||||||
log_error("failed to close dump socket");
|
log_error("failed to close dump socket");
|
||||||
return rv;
|
return rv;
|
||||||
@@ -393,6 +392,7 @@ static int do_dump(const char *req_name)
|
|||||||
daemon_reply reply;
|
daemon_reply reply;
|
||||||
int result;
|
int result;
|
||||||
int fd, rv = 0;
|
int fd, rv = 0;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
fd = setup_dump_socket();
|
fd = setup_dump_socket();
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
@@ -423,13 +423,18 @@ static int do_dump(const char *req_name)
|
|||||||
|
|
||||||
memset(dump_buf, 0, sizeof(dump_buf));
|
memset(dump_buf, 0, sizeof(dump_buf));
|
||||||
|
|
||||||
rv = recvfrom(fd, dump_buf, dump_len, MSG_WAITALL,
|
retry:
|
||||||
|
rv = recvfrom(fd, dump_buf + count, dump_len - count, MSG_WAITALL,
|
||||||
(struct sockaddr *)&dump_addr, &dump_addrlen);
|
(struct sockaddr *)&dump_addr, &dump_addrlen);
|
||||||
if (rv < 0) {
|
if (rv < 0) {
|
||||||
log_error("recvfrom error %d %d", rv, errno);
|
log_error("recvfrom error %d %d", rv, errno);
|
||||||
rv = -errno;
|
rv = -errno;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
count += rv;
|
||||||
|
|
||||||
|
if (count < dump_len)
|
||||||
|
goto retry;
|
||||||
|
|
||||||
rv = 0;
|
rv = 0;
|
||||||
if ((info && dump) || !strcmp(req_name, "dump"))
|
if ((info && dump) || !strcmp(req_name, "dump"))
|
||||||
@@ -450,7 +455,7 @@ static int do_able(const char *req_name)
|
|||||||
|
|
||||||
reply = _lvmlockd_send(req_name,
|
reply = _lvmlockd_send(req_name,
|
||||||
"cmd = %s", "lvmlockctl",
|
"cmd = %s", "lvmlockctl",
|
||||||
"pid = %d", getpid(),
|
"pid = " FMTd64, (int64_t) getpid(),
|
||||||
"vg_name = %s", arg_vg_name,
|
"vg_name = %s", arg_vg_name,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
@@ -481,7 +486,7 @@ static int do_stop_lockspaces(void)
|
|||||||
|
|
||||||
reply = _lvmlockd_send("stop_all",
|
reply = _lvmlockd_send("stop_all",
|
||||||
"cmd = %s", "lvmlockctl",
|
"cmd = %s", "lvmlockctl",
|
||||||
"pid = %d", getpid(),
|
"pid = " FMTd64, (int64_t) getpid(),
|
||||||
"opts = %s", opts[0] ? opts : "none",
|
"opts = %s", opts[0] ? opts : "none",
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
@@ -516,7 +521,7 @@ static int do_kill(void)
|
|||||||
|
|
||||||
reply = _lvmlockd_send("kill_vg",
|
reply = _lvmlockd_send("kill_vg",
|
||||||
"cmd = %s", "lvmlockctl",
|
"cmd = %s", "lvmlockctl",
|
||||||
"pid = %d", getpid(),
|
"pid = " FMTd64, (int64_t) getpid(),
|
||||||
"vg_name = %s", arg_vg_name,
|
"vg_name = %s", arg_vg_name,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
@@ -562,7 +567,7 @@ static int do_drop(void)
|
|||||||
|
|
||||||
reply = _lvmlockd_send("drop_vg",
|
reply = _lvmlockd_send("drop_vg",
|
||||||
"cmd = %s", "lvmlockctl",
|
"cmd = %s", "lvmlockctl",
|
||||||
"pid = %d", getpid(),
|
"pid = " FMTd64, (int64_t) getpid(),
|
||||||
"vg_name = %s", arg_vg_name,
|
"vg_name = %s", arg_vg_name,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
@@ -593,14 +598,14 @@ static void print_usage(void)
|
|||||||
printf(" Wait option for other commands.\n");
|
printf(" Wait option for other commands.\n");
|
||||||
printf("--force | -f 0|1>\n");
|
printf("--force | -f 0|1>\n");
|
||||||
printf(" Force option for other commands.\n");
|
printf(" Force option for other commands.\n");
|
||||||
printf("--kill | -k <vg_name>\n");
|
printf("--kill | -k <vgname>\n");
|
||||||
printf(" Kill access to the vg when sanlock cannot renew lease.\n");
|
printf(" Kill access to the VG when sanlock cannot renew lease.\n");
|
||||||
printf("--drop | -r <vg_name>\n");
|
printf("--drop | -r <vgname>\n");
|
||||||
printf(" Clear locks for the vg after it has been killed and is no longer used.\n");
|
printf(" Clear locks for the VG when it is unused after kill (-k).\n");
|
||||||
printf("--gl-enable <vg_name>\n");
|
printf("--gl-enable | -E <vgname>\n");
|
||||||
printf(" Tell lvmlockd to enable the global lock in a sanlock vg.\n");
|
printf(" Tell lvmlockd to enable the global lock in a sanlock VG.\n");
|
||||||
printf("--gl-disable <vg_name>\n");
|
printf("--gl-disable | -D <vgname>\n");
|
||||||
printf(" Tell lvmlockd to disable the global lock in a sanlock vg.\n");
|
printf(" Tell lvmlockd to disable the global lock in a sanlock VG.\n");
|
||||||
printf("--stop-lockspaces | -S\n");
|
printf("--stop-lockspaces | -S\n");
|
||||||
printf(" Stop all lockspaces.\n");
|
printf(" Stop all lockspaces.\n");
|
||||||
}
|
}
|
||||||
@@ -725,11 +730,13 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (gl_enable) {
|
if (gl_enable) {
|
||||||
|
syslog(LOG_INFO, "Enabling global lock in VG %s.", arg_vg_name);
|
||||||
rv = do_able("enable_gl");
|
rv = do_able("enable_gl");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gl_disable) {
|
if (gl_disable) {
|
||||||
|
syslog(LOG_INFO, "Disabling global lock in VG %s.", arg_vg_name);
|
||||||
rv = do_able("disable_gl");
|
rv = do_able("disable_gl");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,5 +47,6 @@ static inline void lvmlockd_close(daemon_handle h)
|
|||||||
#define ELOCKD 216
|
#define ELOCKD 216
|
||||||
#define EVGKILLED 217 /* sanlock lost access to leases and VG is killed. */
|
#define EVGKILLED 217 /* sanlock lost access to leases and VG is killed. */
|
||||||
#define ELOCKIO 218 /* sanlock io errors during lock op, may be transient. */
|
#define ELOCKIO 218 /* sanlock io errors during lock op, may be transient. */
|
||||||
|
#define EREMOVED 219
|
||||||
|
|
||||||
#endif /* _LVM_LVMLOCKD_CLIENT_H */
|
#endif /* _LVM_LVMLOCKD_CLIENT_H */
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -14,7 +14,6 @@
|
|||||||
#include "tool.h"
|
#include "tool.h"
|
||||||
|
|
||||||
#include "daemon-server.h"
|
#include "daemon-server.h"
|
||||||
#include "daemon-log.h"
|
|
||||||
#include "xlate.h"
|
#include "xlate.h"
|
||||||
|
|
||||||
#include "lvmlockd-internal.h"
|
#include "lvmlockd-internal.h"
|
||||||
@@ -26,7 +25,6 @@
|
|||||||
*/
|
*/
|
||||||
#include "libdlm.h"
|
#include "libdlm.h"
|
||||||
|
|
||||||
#include <pthread.h>
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@@ -35,7 +33,6 @@
|
|||||||
#include <byteswap.h>
|
#include <byteswap.h>
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <sys/socket.h>
|
|
||||||
|
|
||||||
struct lm_dlm {
|
struct lm_dlm {
|
||||||
dlm_lshandle_t *dh;
|
dlm_lshandle_t *dh;
|
||||||
@@ -67,6 +64,8 @@ int lm_data_size_dlm(void)
|
|||||||
#define VG_LOCK_ARGS_MINOR 0
|
#define VG_LOCK_ARGS_MINOR 0
|
||||||
#define VG_LOCK_ARGS_PATCH 0
|
#define VG_LOCK_ARGS_PATCH 0
|
||||||
|
|
||||||
|
static int dlm_has_lvb_bug;
|
||||||
|
|
||||||
static int cluster_name_from_args(char *vg_args, char *clustername)
|
static int cluster_name_from_args(char *vg_args, char *clustername)
|
||||||
{
|
{
|
||||||
return last_string_from_args(vg_args, clustername);
|
return last_string_from_args(vg_args, clustername);
|
||||||
@@ -160,9 +159,13 @@ int lm_prepare_lockspace_dlm(struct lockspace *ls)
|
|||||||
{
|
{
|
||||||
char sys_clustername[MAX_ARGS+1];
|
char sys_clustername[MAX_ARGS+1];
|
||||||
char arg_clustername[MAX_ARGS+1];
|
char arg_clustername[MAX_ARGS+1];
|
||||||
|
uint32_t major = 0, minor = 0, patch = 0;
|
||||||
struct lm_dlm *lmd;
|
struct lm_dlm *lmd;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
|
if (daemon_test)
|
||||||
|
goto skip_args;
|
||||||
|
|
||||||
memset(sys_clustername, 0, sizeof(sys_clustername));
|
memset(sys_clustername, 0, sizeof(sys_clustername));
|
||||||
memset(arg_clustername, 0, sizeof(arg_clustername));
|
memset(arg_clustername, 0, sizeof(arg_clustername));
|
||||||
|
|
||||||
@@ -170,6 +173,17 @@ int lm_prepare_lockspace_dlm(struct lockspace *ls)
|
|||||||
if (rv < 0)
|
if (rv < 0)
|
||||||
return -EMANAGER;
|
return -EMANAGER;
|
||||||
|
|
||||||
|
rv = dlm_kernel_version(&major, &minor, &patch);
|
||||||
|
if (rv < 0) {
|
||||||
|
log_error("prepare_lockspace_dlm kernel_version not detected %d", rv);
|
||||||
|
dlm_has_lvb_bug = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((major == 6) && (minor == 0) && (patch == 1)) {
|
||||||
|
log_debug("dlm kernel version %u.%u.%u has lvb bug", major, minor, patch);
|
||||||
|
dlm_has_lvb_bug = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (!ls->vg_args[0]) {
|
if (!ls->vg_args[0]) {
|
||||||
/* global lockspace has no vg args */
|
/* global lockspace has no vg args */
|
||||||
goto skip_args;
|
goto skip_args;
|
||||||
@@ -246,10 +260,6 @@ int lm_rem_lockspace_dlm(struct lockspace *ls, int free_vg)
|
|||||||
out:
|
out:
|
||||||
free(lmd);
|
free(lmd);
|
||||||
ls->lm_data = NULL;
|
ls->lm_data = NULL;
|
||||||
|
|
||||||
if (!strcmp(ls->name, gl_lsname_dlm))
|
|
||||||
gl_running_dlm = 0;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -333,7 +343,7 @@ static int to_dlm_mode(int ld_mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int lm_adopt_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
|
static int lm_adopt_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
|
||||||
uint32_t *r_version)
|
struct val_blk *vb_out)
|
||||||
{
|
{
|
||||||
struct lm_dlm *lmd = (struct lm_dlm *)ls->lm_data;
|
struct lm_dlm *lmd = (struct lm_dlm *)ls->lm_data;
|
||||||
struct rd_dlm *rdd = (struct rd_dlm *)r->lm_data;
|
struct rd_dlm *rdd = (struct rd_dlm *)r->lm_data;
|
||||||
@@ -342,7 +352,7 @@ static int lm_adopt_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
|
|||||||
int mode;
|
int mode;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
*r_version = 0;
|
memset(vb_out, 0, sizeof(struct val_blk));
|
||||||
|
|
||||||
if (!r->lm_init) {
|
if (!r->lm_init) {
|
||||||
rv = lm_add_resource_dlm(ls, r, 0);
|
rv = lm_add_resource_dlm(ls, r, 0);
|
||||||
@@ -384,7 +394,7 @@ static int lm_adopt_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
|
|||||||
(void *)1, (void *)1, (void *)1,
|
(void *)1, (void *)1, (void *)1,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
|
|
||||||
if (rv == -EAGAIN) {
|
if (rv == -1 && errno == -EAGAIN) {
|
||||||
log_debug("S %s R %s adopt_dlm adopt mode %d try other mode",
|
log_debug("S %s R %s adopt_dlm adopt mode %d try other mode",
|
||||||
ls->name, r->name, ld_mode);
|
ls->name, r->name, ld_mode);
|
||||||
rv = -EUCLEAN;
|
rv = -EUCLEAN;
|
||||||
@@ -421,14 +431,13 @@ static int lm_adopt_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
int lm_lock_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
|
int lm_lock_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
|
||||||
uint32_t *r_version, int adopt)
|
struct val_blk *vb_out, int adopt)
|
||||||
{
|
{
|
||||||
struct lm_dlm *lmd = (struct lm_dlm *)ls->lm_data;
|
struct lm_dlm *lmd = (struct lm_dlm *)ls->lm_data;
|
||||||
struct rd_dlm *rdd = (struct rd_dlm *)r->lm_data;
|
struct rd_dlm *rdd = (struct rd_dlm *)r->lm_data;
|
||||||
struct dlm_lksb *lksb;
|
struct dlm_lksb *lksb;
|
||||||
struct val_blk vb;
|
struct val_blk vb;
|
||||||
uint32_t flags = 0;
|
uint32_t flags = 0;
|
||||||
uint16_t vb_version;
|
|
||||||
int mode;
|
int mode;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
@@ -436,7 +445,7 @@ int lm_lock_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
|
|||||||
/* When adopting, we don't follow the normal method
|
/* When adopting, we don't follow the normal method
|
||||||
of acquiring a NL lock then converting it to the
|
of acquiring a NL lock then converting it to the
|
||||||
desired mode. */
|
desired mode. */
|
||||||
return lm_adopt_dlm(ls, r, ld_mode, r_version);
|
return lm_adopt_dlm(ls, r, ld_mode, vb_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!r->lm_init) {
|
if (!r->lm_init) {
|
||||||
@@ -464,19 +473,41 @@ int lm_lock_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
|
|||||||
log_debug("S %s R %s lock_dlm", ls->name, r->name);
|
log_debug("S %s R %s lock_dlm", ls->name, r->name);
|
||||||
|
|
||||||
if (daemon_test) {
|
if (daemon_test) {
|
||||||
*r_version = 0;
|
if (rdd->vb) {
|
||||||
|
vb_out->version = le16_to_cpu(rdd->vb->version);
|
||||||
|
vb_out->flags = le16_to_cpu(rdd->vb->flags);
|
||||||
|
vb_out->r_version = le32_to_cpu(rdd->vb->r_version);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The dlm lvb bug means that converting NL->EX will not return
|
||||||
|
* the latest lvb, so we have to convert NL->PR->EX to reread it.
|
||||||
|
*/
|
||||||
|
if (dlm_has_lvb_bug && (ld_mode == LD_LK_EX)) {
|
||||||
|
rv = dlm_ls_lock_wait(lmd->dh, LKM_PRMODE, lksb, flags,
|
||||||
|
r->name, strlen(r->name),
|
||||||
|
0, NULL, NULL, NULL);
|
||||||
|
if (rv == -1) {
|
||||||
|
log_debug("S %s R %s lock_dlm acquire mode PR for %d rv %d",
|
||||||
|
ls->name, r->name, mode, rv);
|
||||||
|
goto lockrv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fall through to request EX. */
|
||||||
|
}
|
||||||
|
|
||||||
rv = dlm_ls_lock_wait(lmd->dh, mode, lksb, flags,
|
rv = dlm_ls_lock_wait(lmd->dh, mode, lksb, flags,
|
||||||
r->name, strlen(r->name),
|
r->name, strlen(r->name),
|
||||||
0, NULL, NULL, NULL);
|
0, NULL, NULL, NULL);
|
||||||
if (rv == -EAGAIN) {
|
lockrv:
|
||||||
log_error("S %s R %s lock_dlm mode %d rv EAGAIN", ls->name, r->name, mode);
|
if (rv == -1 && errno == EAGAIN) {
|
||||||
|
log_debug("S %s R %s lock_dlm acquire mode %d rv EAGAIN", ls->name, r->name, mode);
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
if (rv < 0) {
|
if (rv < 0) {
|
||||||
log_error("S %s R %s lock_dlm error %d", ls->name, r->name, rv);
|
log_error("S %s R %s lock_dlm acquire error %d errno %d", ls->name, r->name, rv, errno);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -484,28 +515,22 @@ int lm_lock_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
|
|||||||
if (lksb->sb_flags & DLM_SBF_VALNOTVALID) {
|
if (lksb->sb_flags & DLM_SBF_VALNOTVALID) {
|
||||||
log_debug("S %s R %s lock_dlm VALNOTVALID", ls->name, r->name);
|
log_debug("S %s R %s lock_dlm VALNOTVALID", ls->name, r->name);
|
||||||
memset(rdd->vb, 0, sizeof(struct val_blk));
|
memset(rdd->vb, 0, sizeof(struct val_blk));
|
||||||
*r_version = 0;
|
memset(vb_out, 0, sizeof(struct val_blk));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 'vb' contains disk endian values, not host endian.
|
||||||
|
* It is copied directly to rdd->vb which is also kept
|
||||||
|
* in disk endian form.
|
||||||
|
* vb_out is returned to the caller in host endian form.
|
||||||
|
*/
|
||||||
memcpy(&vb, lksb->sb_lvbptr, sizeof(struct val_blk));
|
memcpy(&vb, lksb->sb_lvbptr, sizeof(struct val_blk));
|
||||||
vb_version = le16_to_cpu(vb.version);
|
memcpy(rdd->vb, &vb, sizeof(vb));
|
||||||
|
|
||||||
if (vb_version && ((vb_version & 0xFF00) > (VAL_BLK_VERSION & 0xFF00))) {
|
vb_out->version = le16_to_cpu(vb.version);
|
||||||
log_error("S %s R %s lock_dlm ignore vb_version %x",
|
vb_out->flags = le16_to_cpu(vb.flags);
|
||||||
ls->name, r->name, vb_version);
|
vb_out->r_version = le32_to_cpu(vb.r_version);
|
||||||
*r_version = 0;
|
|
||||||
free(rdd->vb);
|
|
||||||
rdd->vb = NULL;
|
|
||||||
lksb->sb_lvbptr = NULL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
*r_version = le32_to_cpu(vb.r_version);
|
|
||||||
memcpy(rdd->vb, &vb, sizeof(vb)); /* rdd->vb saved as le */
|
|
||||||
|
|
||||||
log_debug("S %s R %s lock_dlm get r_version %u",
|
|
||||||
ls->name, r->name, *r_version);
|
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
return 0;
|
return 0;
|
||||||
@@ -549,7 +574,7 @@ int lm_convert_dlm(struct lockspace *ls, struct resource *r,
|
|||||||
rv = dlm_ls_lock_wait(lmd->dh, mode, lksb, flags,
|
rv = dlm_ls_lock_wait(lmd->dh, mode, lksb, flags,
|
||||||
r->name, strlen(r->name),
|
r->name, strlen(r->name),
|
||||||
0, NULL, NULL, NULL);
|
0, NULL, NULL, NULL);
|
||||||
if (rv == -EAGAIN) {
|
if (rv == -1 && errno == EAGAIN) {
|
||||||
/* FIXME: When does this happen? Should something different be done? */
|
/* FIXME: When does this happen? Should something different be done? */
|
||||||
log_error("S %s R %s convert_dlm mode %d rv EAGAIN", ls->name, r->name, mode);
|
log_error("S %s R %s convert_dlm mode %d rv EAGAIN", ls->name, r->name, mode);
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
@@ -561,17 +586,17 @@ int lm_convert_dlm(struct lockspace *ls, struct resource *r,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int lm_unlock_dlm(struct lockspace *ls, struct resource *r,
|
int lm_unlock_dlm(struct lockspace *ls, struct resource *r,
|
||||||
uint32_t r_version, uint32_t lmuf_flags)
|
uint32_t r_version, uint32_t lmu_flags)
|
||||||
{
|
{
|
||||||
struct lm_dlm *lmd = (struct lm_dlm *)ls->lm_data;
|
struct lm_dlm *lmd = (struct lm_dlm *)ls->lm_data;
|
||||||
struct rd_dlm *rdd = (struct rd_dlm *)r->lm_data;
|
struct rd_dlm *rdd = (struct rd_dlm *)r->lm_data;
|
||||||
struct dlm_lksb *lksb = &rdd->lksb;
|
struct dlm_lksb *lksb = &rdd->lksb;
|
||||||
|
struct val_blk vb_prev;
|
||||||
|
struct val_blk vb_next;
|
||||||
uint32_t flags = 0;
|
uint32_t flags = 0;
|
||||||
|
int new_vb = 0;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
log_debug("S %s R %s unlock_dlm r_version %u flags %x",
|
|
||||||
ls->name, r->name, r_version, lmuf_flags);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do not set PERSISTENT, because we don't need an orphan
|
* Do not set PERSISTENT, because we don't need an orphan
|
||||||
* NL lock to protect anything.
|
* NL lock to protect anything.
|
||||||
@@ -579,19 +604,46 @@ int lm_unlock_dlm(struct lockspace *ls, struct resource *r,
|
|||||||
|
|
||||||
flags |= LKF_CONVERT;
|
flags |= LKF_CONVERT;
|
||||||
|
|
||||||
if (rdd->vb && r_version && (r->mode == LD_LK_EX)) {
|
if (rdd->vb && (r->mode == LD_LK_EX)) {
|
||||||
if (!rdd->vb->version) {
|
|
||||||
/* first time vb has been written */
|
|
||||||
rdd->vb->version = cpu_to_le16(VAL_BLK_VERSION);
|
|
||||||
}
|
|
||||||
if (r_version)
|
|
||||||
rdd->vb->r_version = cpu_to_le32(r_version);
|
|
||||||
memcpy(lksb->sb_lvbptr, rdd->vb, sizeof(struct val_blk));
|
|
||||||
|
|
||||||
log_debug("S %s R %s unlock_dlm set r_version %u",
|
/* vb_prev and vb_next are in disk endian form */
|
||||||
ls->name, r->name, r_version);
|
memcpy(&vb_prev, rdd->vb, sizeof(struct val_blk));
|
||||||
|
memcpy(&vb_next, rdd->vb, sizeof(struct val_blk));
|
||||||
|
|
||||||
|
if (!vb_prev.version) {
|
||||||
|
vb_next.version = cpu_to_le16(VAL_BLK_VERSION);
|
||||||
|
new_vb = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((lmu_flags & LMUF_FREE_VG) && (r->type == LD_RT_VG)) {
|
||||||
|
vb_next.flags = cpu_to_le16(VBF_REMOVED);
|
||||||
|
new_vb = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r_version) {
|
||||||
|
vb_next.r_version = cpu_to_le32(r_version);
|
||||||
|
new_vb = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (new_vb) {
|
||||||
|
memcpy(rdd->vb, &vb_next, sizeof(struct val_blk));
|
||||||
|
memcpy(lksb->sb_lvbptr, &vb_next, sizeof(struct val_blk));
|
||||||
|
|
||||||
|
log_debug("S %s R %s unlock_dlm vb old %x %x %u new %x %x %u",
|
||||||
|
ls->name, r->name,
|
||||||
|
le16_to_cpu(vb_prev.version),
|
||||||
|
le16_to_cpu(vb_prev.flags),
|
||||||
|
le32_to_cpu(vb_prev.r_version),
|
||||||
|
le16_to_cpu(vb_next.version),
|
||||||
|
le16_to_cpu(vb_next.flags),
|
||||||
|
le32_to_cpu(vb_next.r_version));
|
||||||
|
} else {
|
||||||
|
log_debug("S %s R %s unlock_dlm vb unchanged", ls->name, r->name);
|
||||||
|
}
|
||||||
|
|
||||||
flags |= LKF_VALBLK;
|
flags |= LKF_VALBLK;
|
||||||
|
} else {
|
||||||
|
log_debug("S %s R %s unlock_dlm", ls->name, r->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (daemon_test)
|
if (daemon_test)
|
||||||
@@ -614,6 +666,65 @@ int lm_unlock_dlm(struct lockspace *ls, struct resource *r,
|
|||||||
|
|
||||||
#define DLM_LOCKSPACES_PATH "/sys/kernel/config/dlm/cluster/spaces"
|
#define DLM_LOCKSPACES_PATH "/sys/kernel/config/dlm/cluster/spaces"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FIXME: this should be implemented differently.
|
||||||
|
* It's not nice to use an aspect of the dlm clustering
|
||||||
|
* implementation, which could change. It would be
|
||||||
|
* better to do something like use a special lock in the
|
||||||
|
* lockspace that was held PR by all nodes, and then an
|
||||||
|
* EX request on it could check if it's started (and
|
||||||
|
* possibly also notify others to stop it automatically).
|
||||||
|
* Or, possibly an enhancement to libdlm that would give
|
||||||
|
* info about lockspace members.
|
||||||
|
*
|
||||||
|
* (We could let the VG be removed while others still
|
||||||
|
* have the lockspace running, which largely works, but
|
||||||
|
* introduces problems if another VG with the same name is
|
||||||
|
* recreated while others still have the lockspace running
|
||||||
|
* for the previous VG. We'd also want a way to clean up
|
||||||
|
* the stale lockspaces on the others eventually.)
|
||||||
|
*/
|
||||||
|
|
||||||
|
int lm_hosts_dlm(struct lockspace *ls, int notify)
|
||||||
|
{
|
||||||
|
static const char closedir_err_msg[] = "lm_hosts_dlm: closedir failed";
|
||||||
|
char ls_nodes_path[PATH_MAX];
|
||||||
|
struct dirent *de;
|
||||||
|
DIR *ls_dir;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
if (daemon_test)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
memset(ls_nodes_path, 0, sizeof(ls_nodes_path));
|
||||||
|
snprintf(ls_nodes_path, PATH_MAX-1, "%s/%s/nodes",
|
||||||
|
DLM_LOCKSPACES_PATH, ls->name);
|
||||||
|
|
||||||
|
if (!(ls_dir = opendir(ls_nodes_path)))
|
||||||
|
return -ECONNREFUSED;
|
||||||
|
|
||||||
|
while ((de = readdir(ls_dir))) {
|
||||||
|
if (de->d_name[0] == '.')
|
||||||
|
continue;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (closedir(ls_dir))
|
||||||
|
log_error(closedir_err_msg);
|
||||||
|
|
||||||
|
if (!count) {
|
||||||
|
log_error("lm_hosts_dlm found no nodes in %s", ls_nodes_path);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Assume that a count of one node represents ourself,
|
||||||
|
* and any value over one represents other nodes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
return count - 1;
|
||||||
|
}
|
||||||
|
|
||||||
int lm_get_lockspaces_dlm(struct list_head *ls_rejoin)
|
int lm_get_lockspaces_dlm(struct list_head *ls_rejoin)
|
||||||
{
|
{
|
||||||
static const char closedir_err_msg[] = "lm_get_lockspace_dlm: closedir failed";
|
static const char closedir_err_msg[] = "lm_get_lockspace_dlm: closedir failed";
|
||||||
@@ -653,6 +764,9 @@ int lm_is_running_dlm(void)
|
|||||||
char sys_clustername[MAX_ARGS+1];
|
char sys_clustername[MAX_ARGS+1];
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
|
if (daemon_test)
|
||||||
|
return gl_use_dlm;
|
||||||
|
|
||||||
memset(sys_clustername, 0, sizeof(sys_clustername));
|
memset(sys_clustername, 0, sizeof(sys_clustername));
|
||||||
|
|
||||||
rv = read_cluster_name(sys_clustername);
|
rv = read_cluster_name(sys_clustername);
|
||||||
@@ -660,3 +774,4 @@ int lm_is_running_dlm(void)
|
|||||||
return 0;
|
return 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,9 +50,9 @@ enum {
|
|||||||
LD_OP_RENAME_FINAL,
|
LD_OP_RENAME_FINAL,
|
||||||
LD_OP_RUNNING_LM,
|
LD_OP_RUNNING_LM,
|
||||||
LD_OP_FIND_FREE_LOCK,
|
LD_OP_FIND_FREE_LOCK,
|
||||||
LD_OP_FORGET_VG_NAME,
|
|
||||||
LD_OP_KILL_VG,
|
LD_OP_KILL_VG,
|
||||||
LD_OP_DROP_VG,
|
LD_OP_DROP_VG,
|
||||||
|
LD_OP_BUSY,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* resource types */
|
/* resource types */
|
||||||
@@ -85,11 +85,12 @@ struct client {
|
|||||||
unsigned int recv : 1;
|
unsigned int recv : 1;
|
||||||
unsigned int dead : 1;
|
unsigned int dead : 1;
|
||||||
unsigned int poll_ignore : 1;
|
unsigned int poll_ignore : 1;
|
||||||
|
unsigned int lock_ops : 1;
|
||||||
char name[MAX_NAME+1];
|
char name[MAX_NAME+1];
|
||||||
};
|
};
|
||||||
|
|
||||||
#define LD_AF_PERSISTENT 0x00000001
|
#define LD_AF_PERSISTENT 0x00000001
|
||||||
#define LD_AF_UNUSED 0x00000002 /* use me */
|
#define LD_AF_NO_CLIENT 0x00000002
|
||||||
#define LD_AF_UNLOCK_CANCEL 0x00000004
|
#define LD_AF_UNLOCK_CANCEL 0x00000004
|
||||||
#define LD_AF_NEXT_VERSION 0x00000008
|
#define LD_AF_NEXT_VERSION 0x00000008
|
||||||
#define LD_AF_WAIT 0x00000010
|
#define LD_AF_WAIT 0x00000010
|
||||||
@@ -100,10 +101,10 @@ struct client {
|
|||||||
#define LD_AF_SEARCH_LS 0x00000200
|
#define LD_AF_SEARCH_LS 0x00000200
|
||||||
#define LD_AF_WAIT_STARTING 0x00001000
|
#define LD_AF_WAIT_STARTING 0x00001000
|
||||||
#define LD_AF_DUP_GL_LS 0x00002000
|
#define LD_AF_DUP_GL_LS 0x00002000
|
||||||
#define LD_AF_INACTIVE_LS 0x00004000
|
|
||||||
#define LD_AF_ADD_LS_ERROR 0x00008000
|
|
||||||
#define LD_AF_ADOPT 0x00010000
|
#define LD_AF_ADOPT 0x00010000
|
||||||
#define LD_AF_WARN_GL_REMOVED 0x00020000
|
#define LD_AF_WARN_GL_REMOVED 0x00020000
|
||||||
|
#define LD_AF_LV_LOCK 0x00040000
|
||||||
|
#define LD_AF_LV_UNLOCK 0x00080000
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Number of times to repeat a lock request after
|
* Number of times to repeat a lock request after
|
||||||
@@ -142,12 +143,13 @@ struct resource {
|
|||||||
int8_t mode;
|
int8_t mode;
|
||||||
unsigned int sh_count; /* number of sh locks on locks list */
|
unsigned int sh_count; /* number of sh locks on locks list */
|
||||||
uint32_t version;
|
uint32_t version;
|
||||||
|
uint32_t last_client_id; /* last client_id to lock or unlock resource */
|
||||||
unsigned int lm_init : 1; /* lm_data is initialized */
|
unsigned int lm_init : 1; /* lm_data is initialized */
|
||||||
unsigned int adopt : 1; /* temp flag in remove_inactive_lvs */
|
unsigned int adopt : 1; /* temp flag in remove_inactive_lvs */
|
||||||
unsigned int version_zero_valid : 1;
|
unsigned int version_zero_valid : 1;
|
||||||
|
unsigned int use_vb : 1;
|
||||||
struct list_head locks;
|
struct list_head locks;
|
||||||
struct list_head actions;
|
struct list_head actions;
|
||||||
struct val_blk *vb;
|
|
||||||
char lv_args[MAX_ARGS+1];
|
char lv_args[MAX_ARGS+1];
|
||||||
char lm_data[0]; /* lock manager specific data */
|
char lm_data[0]; /* lock manager specific data */
|
||||||
};
|
};
|
||||||
@@ -193,8 +195,12 @@ struct lockspace {
|
|||||||
struct list_head resources; /* resource/lock state for gl/vg/lv */
|
struct list_head resources; /* resource/lock state for gl/vg/lv */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* val_blk version */
|
||||||
#define VAL_BLK_VERSION 0x0101
|
#define VAL_BLK_VERSION 0x0101
|
||||||
|
|
||||||
|
/* val_blk flags */
|
||||||
|
#define VBF_REMOVED 0x0001
|
||||||
|
|
||||||
struct val_blk {
|
struct val_blk {
|
||||||
uint16_t version;
|
uint16_t version;
|
||||||
uint16_t flags;
|
uint16_t flags;
|
||||||
@@ -311,14 +317,12 @@ static inline int list_empty(const struct list_head *head)
|
|||||||
* or when disable_gl matches.
|
* or when disable_gl matches.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
EXTERN int gl_running_dlm;
|
|
||||||
EXTERN int gl_type_static;
|
EXTERN int gl_type_static;
|
||||||
EXTERN int gl_use_dlm;
|
EXTERN int gl_use_dlm;
|
||||||
EXTERN int gl_use_sanlock;
|
EXTERN int gl_use_sanlock;
|
||||||
EXTERN pthread_mutex_t gl_type_mutex;
|
|
||||||
|
|
||||||
EXTERN char gl_lsname_dlm[MAX_NAME+1];
|
EXTERN char gl_lsname_dlm[MAX_NAME+1];
|
||||||
EXTERN char gl_lsname_sanlock[MAX_NAME+1];
|
EXTERN char gl_lsname_sanlock[MAX_NAME+1];
|
||||||
|
EXTERN int global_dlm_lockspace_exists;
|
||||||
|
|
||||||
EXTERN int daemon_test; /* run as much as possible without a live lock manager */
|
EXTERN int daemon_test; /* run as much as possible without a live lock manager */
|
||||||
EXTERN int daemon_debug;
|
EXTERN int daemon_debug;
|
||||||
@@ -347,6 +351,23 @@ int lockspaces_empty(void);
|
|||||||
int last_string_from_args(char *args_in, char *last);
|
int last_string_from_args(char *args_in, char *last);
|
||||||
int version_from_args(char *args, unsigned int *major, unsigned int *minor, unsigned int *patch);
|
int version_from_args(char *args, unsigned int *major, unsigned int *minor, unsigned int *patch);
|
||||||
|
|
||||||
|
static inline const char *mode_str(int x)
|
||||||
|
{
|
||||||
|
switch (x) {
|
||||||
|
case LD_LK_IV:
|
||||||
|
return "iv";
|
||||||
|
case LD_LK_UN:
|
||||||
|
return "un";
|
||||||
|
case LD_LK_NL:
|
||||||
|
return "nl";
|
||||||
|
case LD_LK_SH:
|
||||||
|
return "sh";
|
||||||
|
case LD_LK_EX:
|
||||||
|
return "ex";
|
||||||
|
default:
|
||||||
|
return ".";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef LOCKDDLM_SUPPORT
|
#ifdef LOCKDDLM_SUPPORT
|
||||||
|
|
||||||
@@ -355,7 +376,7 @@ int lm_prepare_lockspace_dlm(struct lockspace *ls);
|
|||||||
int lm_add_lockspace_dlm(struct lockspace *ls, int adopt);
|
int lm_add_lockspace_dlm(struct lockspace *ls, int adopt);
|
||||||
int lm_rem_lockspace_dlm(struct lockspace *ls, int free_vg);
|
int lm_rem_lockspace_dlm(struct lockspace *ls, int free_vg);
|
||||||
int lm_lock_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
|
int lm_lock_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
|
||||||
uint32_t *r_version, int adopt);
|
struct val_blk *vb_out, int adopt);
|
||||||
int lm_convert_dlm(struct lockspace *ls, struct resource *r,
|
int lm_convert_dlm(struct lockspace *ls, struct resource *r,
|
||||||
int ld_mode, uint32_t r_version);
|
int ld_mode, uint32_t r_version);
|
||||||
int lm_unlock_dlm(struct lockspace *ls, struct resource *r,
|
int lm_unlock_dlm(struct lockspace *ls, struct resource *r,
|
||||||
@@ -364,6 +385,7 @@ int lm_rem_resource_dlm(struct lockspace *ls, struct resource *r);
|
|||||||
int lm_get_lockspaces_dlm(struct list_head *ls_rejoin);
|
int lm_get_lockspaces_dlm(struct list_head *ls_rejoin);
|
||||||
int lm_data_size_dlm(void);
|
int lm_data_size_dlm(void);
|
||||||
int lm_is_running_dlm(void);
|
int lm_is_running_dlm(void);
|
||||||
|
int lm_hosts_dlm(struct lockspace *ls, int notify);
|
||||||
|
|
||||||
static inline int lm_support_dlm(void)
|
static inline int lm_support_dlm(void)
|
||||||
{
|
{
|
||||||
@@ -393,7 +415,7 @@ static inline int lm_rem_lockspace_dlm(struct lockspace *ls, int free_vg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline int lm_lock_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
|
static inline int lm_lock_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
|
||||||
uint32_t *r_version, int adopt)
|
struct val_blk *vb_out, int adopt)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -435,6 +457,11 @@ static inline int lm_support_dlm(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int lm_hosts_dlm(struct lockspace *ls, int notify)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* dlm support */
|
#endif /* dlm support */
|
||||||
|
|
||||||
#ifdef LOCKDSANLOCK_SUPPORT
|
#ifdef LOCKDSANLOCK_SUPPORT
|
||||||
@@ -447,7 +474,7 @@ int lm_prepare_lockspace_sanlock(struct lockspace *ls);
|
|||||||
int lm_add_lockspace_sanlock(struct lockspace *ls, int adopt);
|
int lm_add_lockspace_sanlock(struct lockspace *ls, int adopt);
|
||||||
int lm_rem_lockspace_sanlock(struct lockspace *ls, int free_vg);
|
int lm_rem_lockspace_sanlock(struct lockspace *ls, int free_vg);
|
||||||
int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
|
int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
|
||||||
uint32_t *r_version, int *retry, int adopt);
|
struct val_blk *vb_out, int *retry, int adopt);
|
||||||
int lm_convert_sanlock(struct lockspace *ls, struct resource *r,
|
int lm_convert_sanlock(struct lockspace *ls, struct resource *r,
|
||||||
int ld_mode, uint32_t r_version);
|
int ld_mode, uint32_t r_version);
|
||||||
int lm_unlock_sanlock(struct lockspace *ls, struct resource *r,
|
int lm_unlock_sanlock(struct lockspace *ls, struct resource *r,
|
||||||
@@ -505,7 +532,7 @@ static inline int lm_rem_lockspace_sanlock(struct lockspace *ls, int free_vg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
|
static inline int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
|
||||||
uint32_t *r_version, int *retry, int adopt)
|
struct val_blk *vb_out, int *retry, int adopt)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,6 @@
|
|||||||
#include "tool.h"
|
#include "tool.h"
|
||||||
|
|
||||||
#include "daemon-server.h"
|
#include "daemon-server.h"
|
||||||
#include "daemon-log.h"
|
|
||||||
#include "xlate.h"
|
#include "xlate.h"
|
||||||
|
|
||||||
#include "lvmlockd-internal.h"
|
#include "lvmlockd-internal.h"
|
||||||
@@ -25,12 +24,10 @@
|
|||||||
#include "sanlock_admin.h"
|
#include "sanlock_admin.h"
|
||||||
#include "sanlock_resource.h"
|
#include "sanlock_resource.h"
|
||||||
|
|
||||||
#include <pthread.h>
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
#include <sys/socket.h>
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@@ -205,9 +202,11 @@ int lm_data_size_sanlock(void)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define LS_BEGIN 0
|
#define LS_BEGIN 0
|
||||||
#define GL_LOCK_BEGIN 65
|
#define GL_LOCK_BEGIN UINT64_C(65)
|
||||||
#define VG_LOCK_BEGIN 66
|
#define VG_LOCK_BEGIN UINT64_C(66)
|
||||||
#define LV_LOCK_BEGIN 67
|
#define LV_LOCK_BEGIN UINT64_C(67)
|
||||||
|
|
||||||
|
static unsigned int daemon_test_lv_count;
|
||||||
|
|
||||||
static int lock_lv_name_from_args(char *vg_args, char *lock_lv_name)
|
static int lock_lv_name_from_args(char *vg_args, char *lock_lv_name)
|
||||||
{
|
{
|
||||||
@@ -341,6 +340,7 @@ int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_ar
|
|||||||
if (daemon_test) {
|
if (daemon_test) {
|
||||||
if (!gl_lsname_sanlock[0])
|
if (!gl_lsname_sanlock[0])
|
||||||
strncpy(gl_lsname_sanlock, ls_name, MAX_NAME);
|
strncpy(gl_lsname_sanlock, ls_name, MAX_NAME);
|
||||||
|
snprintf(vg_args, MAX_ARGS, "%s:%s", lock_args_version, lock_lv_name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -492,6 +492,15 @@ int lm_init_lv_sanlock(char *ls_name, char *vg_name, char *lv_name,
|
|||||||
snprintf(lock_args_version, MAX_ARGS, "%u.%u.%u",
|
snprintf(lock_args_version, MAX_ARGS, "%u.%u.%u",
|
||||||
LV_LOCK_ARGS_MAJOR, LV_LOCK_ARGS_MINOR, LV_LOCK_ARGS_PATCH);
|
LV_LOCK_ARGS_MAJOR, LV_LOCK_ARGS_MINOR, LV_LOCK_ARGS_PATCH);
|
||||||
|
|
||||||
|
if (daemon_test) {
|
||||||
|
align_size = 1048576;
|
||||||
|
snprintf(lv_args, MAX_ARGS, "%s:%llu",
|
||||||
|
lock_args_version,
|
||||||
|
(unsigned long long)((align_size * LV_LOCK_BEGIN) + (align_size * daemon_test_lv_count)));
|
||||||
|
daemon_test_lv_count++;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
strncpy(rd.rs.lockspace_name, ls_name, SANLK_NAME_LEN);
|
strncpy(rd.rs.lockspace_name, ls_name, SANLK_NAME_LEN);
|
||||||
rd.rs.num_disks = 1;
|
rd.rs.num_disks = 1;
|
||||||
snprintf(rd.rs.disks[0].path, SANLK_PATH_LEN-1, "/dev/mapper/%s-%s", vg_name, lock_lv_name);
|
snprintf(rd.rs.disks[0].path, SANLK_PATH_LEN-1, "/dev/mapper/%s-%s", vg_name, lock_lv_name);
|
||||||
@@ -508,12 +517,6 @@ int lm_init_lv_sanlock(char *ls_name, char *vg_name, char *lv_name,
|
|||||||
offset = align_size * LV_LOCK_BEGIN;
|
offset = align_size * LV_LOCK_BEGIN;
|
||||||
rd.rs.disks[0].offset = offset;
|
rd.rs.disks[0].offset = offset;
|
||||||
|
|
||||||
if (daemon_test) {
|
|
||||||
snprintf(lv_args, MAX_ARGS, "%s:%llu",
|
|
||||||
lock_args_version, (unsigned long long)1111);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
rd.rs.disks[0].offset = offset;
|
rd.rs.disks[0].offset = offset;
|
||||||
|
|
||||||
@@ -762,6 +765,9 @@ int lm_ex_disable_gl_sanlock(struct lockspace *ls)
|
|||||||
struct sanlk_resource **rs_args;
|
struct sanlk_resource **rs_args;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
|
if (daemon_test)
|
||||||
|
return 0;
|
||||||
|
|
||||||
rs_args = malloc(2 * sizeof(struct sanlk_resource *));
|
rs_args = malloc(2 * sizeof(struct sanlk_resource *));
|
||||||
if (!rs_args)
|
if (!rs_args)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@@ -831,6 +837,9 @@ int lm_able_gl_sanlock(struct lockspace *ls, int enable)
|
|||||||
else
|
else
|
||||||
gl_name = R_NAME_GL_DISABLED;
|
gl_name = R_NAME_GL_DISABLED;
|
||||||
|
|
||||||
|
if (daemon_test)
|
||||||
|
goto out;
|
||||||
|
|
||||||
memset(&rd, 0, sizeof(rd));
|
memset(&rd, 0, sizeof(rd));
|
||||||
|
|
||||||
strncpy(rd.rs.lockspace_name, ls->name, SANLK_NAME_LEN);
|
strncpy(rd.rs.lockspace_name, ls->name, SANLK_NAME_LEN);
|
||||||
@@ -846,7 +855,7 @@ int lm_able_gl_sanlock(struct lockspace *ls, int enable)
|
|||||||
ls->name, enable, rv, rd.rs.disks[0].path);
|
ls->name, enable, rv, rd.rs.disks[0].path);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
out:
|
||||||
log_debug("S %s able_gl %s", ls->name, gl_name);
|
log_debug("S %s able_gl %s", ls->name, gl_name);
|
||||||
|
|
||||||
ls->sanlock_gl_enabled = enable;
|
ls->sanlock_gl_enabled = enable;
|
||||||
@@ -867,6 +876,9 @@ static int gl_is_enabled(struct lockspace *ls, struct lm_sanlock *lms)
|
|||||||
uint64_t offset;
|
uint64_t offset;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
|
if (daemon_test)
|
||||||
|
return 1;
|
||||||
|
|
||||||
memset(&rd, 0, sizeof(rd));
|
memset(&rd, 0, sizeof(rd));
|
||||||
|
|
||||||
strncpy(rd.rs.lockspace_name, ls->name, SANLK_NAME_LEN);
|
strncpy(rd.rs.lockspace_name, ls->name, SANLK_NAME_LEN);
|
||||||
@@ -925,8 +937,10 @@ int lm_find_free_lock_sanlock(struct lockspace *ls, uint64_t *free_offset)
|
|||||||
uint64_t offset;
|
uint64_t offset;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
if (daemon_test)
|
if (daemon_test) {
|
||||||
|
*free_offset = (1048576 * LV_LOCK_BEGIN) + (1048576 * (daemon_test_lv_count + 1));
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
memset(&rd, 0, sizeof(rd));
|
memset(&rd, 0, sizeof(rd));
|
||||||
|
|
||||||
@@ -1175,6 +1189,11 @@ int lm_add_lockspace_sanlock(struct lockspace *ls, int adopt)
|
|||||||
struct lm_sanlock *lms = (struct lm_sanlock *)ls->lm_data;
|
struct lm_sanlock *lms = (struct lm_sanlock *)ls->lm_data;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
|
if (daemon_test) {
|
||||||
|
sleep(2);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
rv = sanlock_add_lockspace_timeout(&lms->ss, 0, sanlock_io_timeout);
|
rv = sanlock_add_lockspace_timeout(&lms->ss, 0, sanlock_io_timeout);
|
||||||
if (rv == -EEXIST && adopt) {
|
if (rv == -EEXIST && adopt) {
|
||||||
/* We could alternatively just skip the sanlock call for adopt. */
|
/* We could alternatively just skip the sanlock call for adopt. */
|
||||||
@@ -1243,10 +1262,10 @@ int lm_rem_lockspace_sanlock(struct lockspace *ls, int free_vg)
|
|||||||
ls->name, rv, lms->ss.host_id_disk.path);
|
ls->name, rv, lms->ss.host_id_disk.path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out:
|
|
||||||
if (close(lms->sock))
|
if (close(lms->sock))
|
||||||
log_error("failed to close sanlock daemon socket connection");
|
log_error("failed to close sanlock daemon socket connection");
|
||||||
|
out:
|
||||||
free(lms);
|
free(lms);
|
||||||
ls->lm_data = NULL;
|
ls->lm_data = NULL;
|
||||||
|
|
||||||
@@ -1300,15 +1319,15 @@ int lm_rem_resource_sanlock(struct lockspace *ls, struct resource *r)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
|
int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
|
||||||
uint32_t *r_version, int *retry, int adopt)
|
struct val_blk *vb_out, int *retry, int adopt)
|
||||||
{
|
{
|
||||||
struct lm_sanlock *lms = (struct lm_sanlock *)ls->lm_data;
|
struct lm_sanlock *lms = (struct lm_sanlock *)ls->lm_data;
|
||||||
struct rd_sanlock *rds = (struct rd_sanlock *)r->lm_data;
|
struct rd_sanlock *rds = (struct rd_sanlock *)r->lm_data;
|
||||||
struct sanlk_resource *rs;
|
struct sanlk_resource *rs;
|
||||||
|
struct sanlk_options opt;
|
||||||
uint64_t lock_lv_offset;
|
uint64_t lock_lv_offset;
|
||||||
uint32_t flags = 0;
|
uint32_t flags = 0;
|
||||||
struct val_blk vb;
|
struct val_blk vb;
|
||||||
uint16_t vb_version;
|
|
||||||
int added = 0;
|
int added = 0;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
@@ -1379,12 +1398,16 @@ int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
|
|||||||
|
|
||||||
rs->flags |= SANLK_RES_PERSISTENT;
|
rs->flags |= SANLK_RES_PERSISTENT;
|
||||||
|
|
||||||
log_debug("S %s R %s lock_san acquire %s:%llu",
|
log_debug("S %s R %s lock_san %s at %s:%llu",
|
||||||
ls->name, r->name, rs->disks[0].path,
|
ls->name, r->name, mode_str(ld_mode), rs->disks[0].path,
|
||||||
(unsigned long long)rs->disks[0].offset);
|
(unsigned long long)rs->disks[0].offset);
|
||||||
|
|
||||||
if (daemon_test) {
|
if (daemon_test) {
|
||||||
*r_version = 0;
|
if (rds->vb) {
|
||||||
|
vb_out->version = le16_to_cpu(rds->vb->version);
|
||||||
|
vb_out->flags = le16_to_cpu(rds->vb->flags);
|
||||||
|
vb_out->r_version = le32_to_cpu(rds->vb->r_version);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1393,7 +1416,19 @@ int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
|
|||||||
if (adopt)
|
if (adopt)
|
||||||
flags |= SANLK_ACQUIRE_ORPHAN_ONLY;
|
flags |= SANLK_ACQUIRE_ORPHAN_ONLY;
|
||||||
|
|
||||||
rv = sanlock_acquire(lms->sock, -1, flags, 1, &rs, NULL);
|
#ifdef SANLOCK_HAS_ACQUIRE_OWNER_NOWAIT
|
||||||
|
/*
|
||||||
|
* Don't block waiting for a failed lease to expire since it causes
|
||||||
|
* sanlock_acquire to block for a long time, which would prevent this
|
||||||
|
* thread from processing other lock requests.
|
||||||
|
*/
|
||||||
|
flags |= SANLK_ACQUIRE_OWNER_NOWAIT;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
memset(&opt, 0, sizeof(opt));
|
||||||
|
sprintf(opt.owner_name, "%s", "lvmlockd");
|
||||||
|
|
||||||
|
rv = sanlock_acquire(lms->sock, -1, flags, 1, &rs, &opt);
|
||||||
|
|
||||||
if (rv == -EAGAIN) {
|
if (rv == -EAGAIN) {
|
||||||
/*
|
/*
|
||||||
@@ -1463,6 +1498,26 @@ int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
|
|||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef SANLOCK_HAS_ACQUIRE_OWNER_NOWAIT
|
||||||
|
if (rv == SANLK_ACQUIRE_OWNED_RETRY) {
|
||||||
|
/*
|
||||||
|
* The lock is held by a failed host, and will eventually
|
||||||
|
* expire. If we retry we'll eventually acquire the lock
|
||||||
|
* (or find someone else has acquired it). The EAGAIN retry
|
||||||
|
* attempts for SH locks above would not be sufficient for
|
||||||
|
* the length of expiration time. We could add a longer
|
||||||
|
* retry time here to cover the full expiration time and block
|
||||||
|
* the activation command for that long. For now just return
|
||||||
|
* the standard error indicating that another host still owns
|
||||||
|
* the lease. FIXME: return a different error number so the
|
||||||
|
* command can print an different error indicating that the
|
||||||
|
* owner of the lease is in the process of expiring?
|
||||||
|
*/
|
||||||
|
log_debug("S %s R %s lock_san acquire mode %d rv %d", ls->name, r->name, ld_mode, rv);
|
||||||
|
*retry = 0;
|
||||||
|
return -EAGAIN;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (rv < 0) {
|
if (rv < 0) {
|
||||||
log_error("S %s R %s lock_san acquire error %d",
|
log_error("S %s R %s lock_san acquire error %d",
|
||||||
ls->name, r->name, rv);
|
ls->name, r->name, rv);
|
||||||
@@ -1501,26 +1556,23 @@ int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
|
|||||||
rv = sanlock_get_lvb(0, rs, (char *)&vb, sizeof(vb));
|
rv = sanlock_get_lvb(0, rs, (char *)&vb, sizeof(vb));
|
||||||
if (rv < 0) {
|
if (rv < 0) {
|
||||||
log_error("S %s R %s lock_san get_lvb error %d", ls->name, r->name, rv);
|
log_error("S %s R %s lock_san get_lvb error %d", ls->name, r->name, rv);
|
||||||
*r_version = 0;
|
memset(rds->vb, 0, sizeof(struct val_blk));
|
||||||
|
memset(vb_out, 0, sizeof(struct val_blk));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
vb_version = le16_to_cpu(vb.version);
|
/*
|
||||||
|
* 'vb' contains disk endian values, not host endian.
|
||||||
|
* It is copied directly to rrs->vb which is also kept
|
||||||
|
* in disk endian form.
|
||||||
|
* vb_out is returned to the caller in host endian form.
|
||||||
|
*/
|
||||||
|
|
||||||
if (vb_version && ((vb_version & 0xFF00) > (VAL_BLK_VERSION & 0xFF00))) {
|
memcpy(rds->vb, &vb, sizeof(vb));
|
||||||
log_error("S %s R %s lock_san ignore vb_version %x",
|
|
||||||
ls->name, r->name, vb_version);
|
|
||||||
*r_version = 0;
|
|
||||||
free(rds->vb);
|
|
||||||
rds->vb = NULL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
*r_version = le32_to_cpu(vb.r_version);
|
vb_out->version = le16_to_cpu(vb.version);
|
||||||
memcpy(rds->vb, &vb, sizeof(vb)); /* rds->vb saved as le */
|
vb_out->flags = le16_to_cpu(vb.flags);
|
||||||
|
vb_out->r_version = le32_to_cpu(vb.r_version);
|
||||||
log_debug("S %s R %s lock_san get r_version %u",
|
|
||||||
ls->name, r->name, *r_version);
|
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
return rv;
|
return rv;
|
||||||
@@ -1536,7 +1588,8 @@ int lm_convert_sanlock(struct lockspace *ls, struct resource *r,
|
|||||||
uint32_t flags = 0;
|
uint32_t flags = 0;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
log_debug("S %s R %s convert_san", ls->name, r->name);
|
log_debug("S %s R %s convert_san %s to %s",
|
||||||
|
ls->name, r->name, mode_str(r->mode), mode_str(ld_mode));
|
||||||
|
|
||||||
if (daemon_test)
|
if (daemon_test)
|
||||||
goto rs_flag;
|
goto rs_flag;
|
||||||
@@ -1640,11 +1693,18 @@ int lm_unlock_sanlock(struct lockspace *ls, struct resource *r,
|
|||||||
struct val_blk vb;
|
struct val_blk vb;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
log_debug("S %s R %s unlock_san r_version %u flags %x",
|
log_debug("S %s R %s unlock_san %s r_version %u flags %x",
|
||||||
ls->name, r->name, r_version, lmu_flags);
|
ls->name, r->name, mode_str(r->mode), r_version, lmu_flags);
|
||||||
|
|
||||||
if (daemon_test)
|
if (daemon_test) {
|
||||||
|
if (rds->vb && r_version && (r->mode == LD_LK_EX)) {
|
||||||
|
if (!rds->vb->version)
|
||||||
|
rds->vb->version = cpu_to_le16(VAL_BLK_VERSION);
|
||||||
|
if (r_version)
|
||||||
|
rds->vb->r_version = cpu_to_le32(r_version);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (rds->vb && r_version && (r->mode == LD_LK_EX)) {
|
if (rds->vb && r_version && (r->mode == LD_LK_EX)) {
|
||||||
if (!rds->vb->version) {
|
if (!rds->vb->version) {
|
||||||
@@ -1694,6 +1754,9 @@ int lm_hosts_sanlock(struct lockspace *ls, int notify)
|
|||||||
int found_others = 0;
|
int found_others = 0;
|
||||||
int i, rv;
|
int i, rv;
|
||||||
|
|
||||||
|
if (daemon_test)
|
||||||
|
return 0;
|
||||||
|
|
||||||
rv = sanlock_get_hosts(ls->name, 0, &hss, &hss_count, 0);
|
rv = sanlock_get_hosts(ls->name, 0, &hss, &hss_count, 0);
|
||||||
if (rv < 0) {
|
if (rv < 0) {
|
||||||
log_error("S %s hosts_san get_hosts error %d", ls->name, rv);
|
log_error("S %s hosts_san get_hosts error %d", ls->name, rv);
|
||||||
@@ -1793,6 +1856,9 @@ int lm_is_running_sanlock(void)
|
|||||||
uint32_t daemon_proto;
|
uint32_t daemon_proto;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
|
if (daemon_test)
|
||||||
|
return gl_use_sanlock;
|
||||||
|
|
||||||
rv = sanlock_version(0, &daemon_version, &daemon_proto);
|
rv = sanlock_version(0, &daemon_version, &daemon_proto);
|
||||||
if (rv < 0)
|
if (rv < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
# 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,
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
srcdir = @srcdir@
|
srcdir = @srcdir@
|
||||||
top_srcdir = @top_srcdir@
|
top_srcdir = @top_srcdir@
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "lvmpolld-common.h"
|
#include "lvmpolld-common.h"
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _LVM_LVMPOLLD_CMD_UTILS_H
|
#ifndef _LVM_LVMPOLLD_CMD_UTILS_H
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "lvmpolld-common.h"
|
#include "lvmpolld-common.h"
|
||||||
@@ -83,6 +83,12 @@ static int _init(struct daemon_state *s)
|
|||||||
struct lvmpolld_state *ls = s->private;
|
struct lvmpolld_state *ls = s->private;
|
||||||
ls->log = s->log;
|
ls->log = s->log;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* log warnings to stderr by default. Otherwise we would miss any lvpoll
|
||||||
|
* error messages in default configuration
|
||||||
|
*/
|
||||||
|
daemon_log_enable(ls->log, DAEMON_LOG_OUTLET_STDERR, DAEMON_LOG_WARN, 1);
|
||||||
|
|
||||||
if (!daemon_log_parse(ls->log, DAEMON_LOG_OUTLET_STDERR, ls->log_config, 1))
|
if (!daemon_log_parse(ls->log, DAEMON_LOG_OUTLET_STDERR, ls->log_config, 1))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -284,7 +290,7 @@ static int poll_for_output(struct lvmpolld_lv *pdlv, struct lvmpolld_thread_data
|
|||||||
"caught input data in STDERR");
|
"caught input data in STDERR");
|
||||||
|
|
||||||
assert(read_single_line(data, 1)); /* may block indef. anyway */
|
assert(read_single_line(data, 1)); /* may block indef. anyway */
|
||||||
INFO(pdlv->ls, "%s: PID %d: %s: '%s'", LVM2_LOG_PREFIX,
|
WARN(pdlv->ls, "%s: PID %d: %s: '%s'", LVM2_LOG_PREFIX,
|
||||||
pdlv->cmd_pid, "STDERR", data->line);
|
pdlv->cmd_pid, "STDERR", data->line);
|
||||||
} else if (fds[1].revents) {
|
} else if (fds[1].revents) {
|
||||||
if (fds[1].revents & POLLHUP)
|
if (fds[1].revents & POLLHUP)
|
||||||
@@ -327,15 +333,19 @@ static int poll_for_output(struct lvmpolld_lv *pdlv, struct lvmpolld_thread_data
|
|||||||
if (fds[1].fd >= 0)
|
if (fds[1].fd >= 0)
|
||||||
while (read_single_line(data, 1)) {
|
while (read_single_line(data, 1)) {
|
||||||
assert(r > 0);
|
assert(r > 0);
|
||||||
INFO(pdlv->ls, "%s: PID %d: %s: %s", LVM2_LOG_PREFIX, pdlv->cmd_pid, "STDERR", data->line);
|
WARN(pdlv->ls, "%s: PID %d: %s: %s", LVM2_LOG_PREFIX, pdlv->cmd_pid, "STDERR", data->line);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (WIFEXITED(ch_stat)) {
|
if (WIFEXITED(ch_stat)) {
|
||||||
INFO(pdlv->ls, "%s: %s (PID %d) %s (%d)", PD_LOG_PREFIX,
|
|
||||||
"lvm2 cmd", pdlv->cmd_pid, "exited with", WEXITSTATUS(ch_stat));
|
|
||||||
cmd_state.retcode = WEXITSTATUS(ch_stat);
|
cmd_state.retcode = WEXITSTATUS(ch_stat);
|
||||||
|
if (cmd_state.retcode)
|
||||||
|
ERROR(pdlv->ls, "%s: %s (PID %d) %s (retcode: %d)", PD_LOG_PREFIX,
|
||||||
|
"lvm2 cmd", pdlv->cmd_pid, "failed", cmd_state.retcode);
|
||||||
|
else
|
||||||
|
INFO(pdlv->ls, "%s: %s (PID %d) %s", PD_LOG_PREFIX,
|
||||||
|
"lvm2 cmd", pdlv->cmd_pid, "finished successfully");
|
||||||
} else if (WIFSIGNALED(ch_stat)) {
|
} else if (WIFSIGNALED(ch_stat)) {
|
||||||
WARN(pdlv->ls, "%s: %s (PID %d) %s (%d)", PD_LOG_PREFIX,
|
ERROR(pdlv->ls, "%s: %s (PID %d) %s (%d)", PD_LOG_PREFIX,
|
||||||
"lvm2 cmd", pdlv->cmd_pid, "got terminated by signal",
|
"lvm2 cmd", pdlv->cmd_pid, "got terminated by signal",
|
||||||
WTERMSIG(ch_stat));
|
WTERMSIG(ch_stat));
|
||||||
cmd_state.signal = WTERMSIG(ch_stat);
|
cmd_state.signal = WTERMSIG(ch_stat);
|
||||||
@@ -529,7 +539,7 @@ static response progress_info(client_handle h, struct lvmpolld_state *ls, reques
|
|||||||
if (st.polling_finished)
|
if (st.polling_finished)
|
||||||
r = daemon_reply_simple(LVMPD_RESP_FINISHED,
|
r = daemon_reply_simple(LVMPD_RESP_FINISHED,
|
||||||
"reason = %s", st.cmd_state.signal ? LVMPD_REAS_SIGNAL : LVMPD_REAS_RETCODE,
|
"reason = %s", st.cmd_state.signal ? LVMPD_REAS_SIGNAL : LVMPD_REAS_RETCODE,
|
||||||
LVMPD_PARM_VALUE " = %d", (int64_t)(st.cmd_state.signal ?: st.cmd_state.retcode),
|
LVMPD_PARM_VALUE " = " FMTd64, (int64_t)(st.cmd_state.signal ?: st.cmd_state.retcode),
|
||||||
NULL);
|
NULL);
|
||||||
else
|
else
|
||||||
r = daemon_reply_simple(LVMPD_RESP_IN_PROGRESS, NULL);
|
r = daemon_reply_simple(LVMPD_RESP_IN_PROGRESS, NULL);
|
||||||
@@ -585,12 +595,16 @@ static int spawn_detached_thread(struct lvmpolld_lv *pdlv)
|
|||||||
int r;
|
int r;
|
||||||
pthread_attr_t attr;
|
pthread_attr_t attr;
|
||||||
|
|
||||||
pthread_attr_init(&attr);
|
if (pthread_attr_init(&attr) != 0)
|
||||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
return 0;
|
||||||
|
|
||||||
|
if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
r = pthread_create(&pdlv->tid, &attr, fork_and_poll, (void *)pdlv);
|
r = pthread_create(&pdlv->tid, &attr, fork_and_poll, (void *)pdlv);
|
||||||
|
|
||||||
pthread_attr_destroy(&attr);
|
if (pthread_attr_destroy(&attr) != 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
return !r;
|
return !r;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "lvmpolld-common.h"
|
#include "lvmpolld-common.h"
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _LVM_LVMPOLLD_DATA_UTILS_H
|
#ifndef _LVM_LVMPOLLD_DATA_UTILS_H
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _LVM_LVMPOLLD_PROTOCOL_H
|
#ifndef _LVM_LVMPOLLD_PROTOCOL_H
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _LVM_TOOL_POLLING_OPS_H
|
#ifndef _LVM_TOOL_POLLING_OPS_H
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "lvm2cmd.h"
|
#include "lvm2cmd.h"
|
||||||
|
|||||||
@@ -1,15 +1,13 @@
|
|||||||
@top_srcdir@/daemons/clvmd/clvm.h
|
@top_srcdir@/daemons/clvmd/clvm.h
|
||||||
@top_srcdir@/daemons/dmeventd/libdevmapper-event.h
|
@top_srcdir@/daemons/dmeventd/libdevmapper-event.h
|
||||||
@top_srcdir@/daemons/lvmetad/lvmetad-client.h
|
@top_srcdir@/daemons/lvmetad/lvmetad-client.h
|
||||||
|
@top_srcdir@/daemons/lvmlockd/lvmlockd-client.h
|
||||||
@top_srcdir@/daemons/lvmpolld/lvmpolld-protocol.h
|
@top_srcdir@/daemons/lvmpolld/lvmpolld-protocol.h
|
||||||
@top_srcdir@/daemons/lvmpolld/polling_ops.h
|
@top_srcdir@/daemons/lvmpolld/polling_ops.h
|
||||||
@top_srcdir@/daemons/lvmlockd/lvmlockd-client.h
|
|
||||||
@top_srcdir@/liblvm/lvm2app.h
|
|
||||||
@top_srcdir@/lib/activate/activate.h
|
@top_srcdir@/lib/activate/activate.h
|
||||||
@top_srcdir@/lib/activate/targets.h
|
@top_srcdir@/lib/activate/targets.h
|
||||||
@top_srcdir@/lib/cache/lvmcache.h
|
@top_srcdir@/lib/cache/lvmcache.h
|
||||||
@top_srcdir@/lib/cache/lvmetad.h
|
@top_srcdir@/lib/cache/lvmetad.h
|
||||||
@top_srcdir@/lib/locking/lvmlockd.h
|
|
||||||
@top_srcdir@/lib/commands/toolcontext.h
|
@top_srcdir@/lib/commands/toolcontext.h
|
||||||
@top_srcdir@/lib/config/config.h
|
@top_srcdir@/lib/config/config.h
|
||||||
@top_srcdir@/lib/config/config_settings.h
|
@top_srcdir@/lib/config/config_settings.h
|
||||||
@@ -19,8 +17,8 @@
|
|||||||
@top_srcdir@/lib/device/dev-cache.h
|
@top_srcdir@/lib/device/dev-cache.h
|
||||||
@top_srcdir@/lib/device/dev-ext-udev-constants.h
|
@top_srcdir@/lib/device/dev-ext-udev-constants.h
|
||||||
@top_srcdir@/lib/device/dev-type.h
|
@top_srcdir@/lib/device/dev-type.h
|
||||||
@top_srcdir@/lib/device/device.h
|
|
||||||
@top_srcdir@/lib/device/device-types.h
|
@top_srcdir@/lib/device/device-types.h
|
||||||
|
@top_srcdir@/lib/device/device.h
|
||||||
@top_srcdir@/lib/display/display.h
|
@top_srcdir@/lib/display/display.h
|
||||||
@top_srcdir@/lib/filters/filter.h
|
@top_srcdir@/lib/filters/filter.h
|
||||||
@top_srcdir@/lib/format1/format1.h
|
@top_srcdir@/lib/format1/format1.h
|
||||||
@@ -31,21 +29,19 @@
|
|||||||
@top_srcdir@/lib/format_text/text_import.h
|
@top_srcdir@/lib/format_text/text_import.h
|
||||||
@top_srcdir@/lib/label/label.h
|
@top_srcdir@/lib/label/label.h
|
||||||
@top_srcdir@/lib/locking/locking.h
|
@top_srcdir@/lib/locking/locking.h
|
||||||
|
@top_srcdir@/lib/locking/lvmlockd.h
|
||||||
@top_srcdir@/lib/log/log.h
|
@top_srcdir@/lib/log/log.h
|
||||||
@top_srcdir@/lib/log/lvm-logging.h
|
@top_srcdir@/lib/log/lvm-logging.h
|
||||||
@top_srcdir@/lib/lvmpolld/lvmpolld-client.h
|
@top_srcdir@/lib/lvmpolld/lvmpolld-client.h
|
||||||
@top_srcdir@/lib/lvmpolld/polldaemon.h
|
@top_srcdir@/lib/lvmpolld/polldaemon.h
|
||||||
@top_srcdir@/lib/metadata/lv.h
|
@top_srcdir@/lib/metadata/lv.h
|
||||||
@top_srcdir@/lib/metadata/lv_alloc.h
|
@top_srcdir@/lib/metadata/lv_alloc.h
|
||||||
@top_srcdir@/lib/metadata/metadata.h
|
|
||||||
@top_srcdir@/lib/metadata/metadata-exported.h
|
@top_srcdir@/lib/metadata/metadata-exported.h
|
||||||
|
@top_srcdir@/lib/metadata/metadata.h
|
||||||
@top_srcdir@/lib/metadata/pv.h
|
@top_srcdir@/lib/metadata/pv.h
|
||||||
@top_srcdir@/lib/metadata/pv_alloc.h
|
@top_srcdir@/lib/metadata/pv_alloc.h
|
||||||
@top_srcdir@/lib/metadata/segtype.h
|
@top_srcdir@/lib/metadata/segtype.h
|
||||||
@top_srcdir@/lib/metadata/vg.h
|
@top_srcdir@/lib/metadata/vg.h
|
||||||
@top_srcdir@/lib/mm/memlock.h
|
|
||||||
@top_srcdir@/lib/mm/xlate.h
|
|
||||||
@top_builddir@/lib/misc/configure.h
|
|
||||||
@top_srcdir@/lib/misc/crc.h
|
@top_srcdir@/lib/misc/crc.h
|
||||||
@top_srcdir@/lib/misc/intl.h
|
@top_srcdir@/lib/misc/intl.h
|
||||||
@top_srcdir@/lib/misc/last-path-component.h
|
@top_srcdir@/lib/misc/last-path-component.h
|
||||||
@@ -54,26 +50,28 @@
|
|||||||
@top_srcdir@/lib/misc/lvm-file.h
|
@top_srcdir@/lib/misc/lvm-file.h
|
||||||
@top_srcdir@/lib/misc/lvm-flock.h
|
@top_srcdir@/lib/misc/lvm-flock.h
|
||||||
@top_srcdir@/lib/misc/lvm-globals.h
|
@top_srcdir@/lib/misc/lvm-globals.h
|
||||||
|
@top_srcdir@/lib/misc/lvm-percent.h
|
||||||
@top_srcdir@/lib/misc/lvm-signal.h
|
@top_srcdir@/lib/misc/lvm-signal.h
|
||||||
@top_srcdir@/lib/misc/lvm-string.h
|
@top_srcdir@/lib/misc/lvm-string.h
|
||||||
@top_builddir@/lib/misc/lvm-version.h
|
|
||||||
@top_srcdir@/lib/misc/lvm-percent.h
|
|
||||||
@top_srcdir@/lib/misc/lvm-wrappers.h
|
@top_srcdir@/lib/misc/lvm-wrappers.h
|
||||||
@top_srcdir@/lib/misc/sharedlib.h
|
@top_srcdir@/lib/misc/sharedlib.h
|
||||||
@top_srcdir@/lib/misc/util.h
|
@top_srcdir@/lib/misc/util.h
|
||||||
|
@top_srcdir@/lib/mm/memlock.h
|
||||||
|
@top_srcdir@/lib/mm/xlate.h
|
||||||
@top_srcdir@/lib/properties/prop_common.h
|
@top_srcdir@/lib/properties/prop_common.h
|
||||||
@top_srcdir@/lib/report/properties.h
|
@top_srcdir@/lib/report/properties.h
|
||||||
@top_srcdir@/lib/report/report.h
|
@top_srcdir@/lib/report/report.h
|
||||||
@top_srcdir@/lib/uuid/uuid.h
|
@top_srcdir@/lib/uuid/uuid.h
|
||||||
|
@top_srcdir@/libdaemon/client/config-util.h
|
||||||
@top_srcdir@/libdaemon/client/daemon-client.h
|
@top_srcdir@/libdaemon/client/daemon-client.h
|
||||||
@top_srcdir@/libdaemon/client/daemon-io.h
|
@top_srcdir@/libdaemon/client/daemon-io.h
|
||||||
@top_srcdir@/libdaemon/client/config-util.h
|
|
||||||
@top_srcdir@/libdm/libdevmapper.h
|
@top_srcdir@/libdm/libdevmapper.h
|
||||||
@top_srcdir@/libdm/misc/dm-ioctl.h
|
@top_srcdir@/libdm/misc/dm-ioctl.h
|
||||||
@top_srcdir@/libdm/misc/dm-logging.h
|
|
||||||
@top_srcdir@/libdm/misc/dm-log-userspace.h
|
@top_srcdir@/libdm/misc/dm-log-userspace.h
|
||||||
|
@top_srcdir@/libdm/misc/dm-logging.h
|
||||||
@top_srcdir@/libdm/misc/dmlib.h
|
@top_srcdir@/libdm/misc/dmlib.h
|
||||||
@top_srcdir@/libdm/misc/kdev_t.h
|
@top_srcdir@/libdm/misc/kdev_t.h
|
||||||
|
@top_srcdir@/liblvm/lvm2app.h
|
||||||
@top_srcdir@/po/pogen.h
|
@top_srcdir@/po/pogen.h
|
||||||
@top_srcdir@/tools/lvm2cmd.h
|
@top_srcdir@/tools/lvm2cmd.h
|
||||||
@top_srcdir@/tools/tool.h
|
@top_srcdir@/tools/tool.h
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#
|
#
|
||||||
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||||
# Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved.
|
# Copyright (C) 2004-2015 Red Hat, Inc. All rights reserved.
|
||||||
#
|
#
|
||||||
# This file is part of LVM2.
|
# This file is part of LVM2.
|
||||||
#
|
#
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
#
|
#
|
||||||
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
srcdir = @srcdir@
|
srcdir = @srcdir@
|
||||||
top_srcdir = @top_srcdir@
|
top_srcdir = @top_srcdir@
|
||||||
@@ -35,5 +35,5 @@ device-mapper: all
|
|||||||
|
|
||||||
cflow: all
|
cflow: all
|
||||||
|
|
||||||
DISTCLEAN_TARGETS += .symlinks
|
DISTCLEAN_TARGETS += .symlinks configure.h lvm-version.h
|
||||||
CLEAN_TARGETS += $(LINKS) .include_symlinks .symlinks_created
|
CLEAN_TARGETS += $(LINKS) .include_symlinks .symlinks_created
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* lib/misc/configure.h.in. Generated from configure.in by autoheader. */
|
/* include/configure.h.in. Generated from configure.in by autoheader. */
|
||||||
|
|
||||||
/* Define to 1 to use libblkid detection of signatures when wiping. */
|
/* Define to 1 to use libblkid detection of signatures when wiping. */
|
||||||
#undef BLKID_WIPING_SUPPORT
|
#undef BLKID_WIPING_SUPPORT
|
||||||
@@ -258,6 +258,9 @@
|
|||||||
/* Define to 1 if you have the <libintl.h> header file. */
|
/* Define to 1 if you have the <libintl.h> header file. */
|
||||||
#undef HAVE_LIBINTL_H
|
#undef HAVE_LIBINTL_H
|
||||||
|
|
||||||
|
/* Define to 1 if udev_device_get_is_initialized is available. */
|
||||||
|
#undef HAVE_LIBUDEV_UDEV_DEVICE_GET_IS_INITIALIZED
|
||||||
|
|
||||||
/* Define to 1 if you have the <limits.h> header file. */
|
/* Define to 1 if you have the <limits.h> header file. */
|
||||||
#undef HAVE_LIMITS_H
|
#undef HAVE_LIMITS_H
|
||||||
|
|
||||||
@@ -460,7 +463,7 @@
|
|||||||
/* Define to 1 if you have the `strtoull' function. */
|
/* Define to 1 if you have the `strtoull' function. */
|
||||||
#undef HAVE_STRTOULL
|
#undef HAVE_STRTOULL
|
||||||
|
|
||||||
/* Define to 1 if `st_rdev' is member of `struct stat'. */
|
/* Define to 1 if `st_rdev' is a member of `struct stat'. */
|
||||||
#undef HAVE_STRUCT_STAT_ST_RDEV
|
#undef HAVE_STRUCT_STAT_ST_RDEV
|
||||||
|
|
||||||
/* Define to 1 if you have the <syslog.h> header file. */
|
/* Define to 1 if you have the <syslog.h> header file. */
|
||||||
@@ -513,12 +516,12 @@
|
|||||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||||
#undef HAVE_SYS_STAT_H
|
#undef HAVE_SYS_STAT_H
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
|
||||||
#undef HAVE_SYS_TIME_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/timerfd.h> header file. */
|
/* Define to 1 if you have the <sys/timerfd.h> header file. */
|
||||||
#undef HAVE_SYS_TIMERFD_H
|
#undef HAVE_SYS_TIMERFD_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||||
|
#undef HAVE_SYS_TIME_H
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||||
#undef HAVE_SYS_TYPES_H
|
#undef HAVE_SYS_TYPES_H
|
||||||
|
|
||||||
@@ -643,6 +646,9 @@
|
|||||||
/* Define to the one symbol short name of this package. */
|
/* Define to the one symbol short name of this package. */
|
||||||
#undef PACKAGE_TARNAME
|
#undef PACKAGE_TARNAME
|
||||||
|
|
||||||
|
/* Define to the home page for this package. */
|
||||||
|
#undef PACKAGE_URL
|
||||||
|
|
||||||
/* Define to the version of this package. */
|
/* Define to the version of this package. */
|
||||||
#undef PACKAGE_VERSION
|
#undef PACKAGE_VERSION
|
||||||
|
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _LVM_VERSION_H
|
#ifndef _LVM_VERSION_H
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
#
|
#
|
||||||
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
srcdir = @srcdir@
|
srcdir = @srcdir@
|
||||||
top_srcdir = @top_srcdir@
|
top_srcdir = @top_srcdir@
|
||||||
@@ -62,6 +62,7 @@ SOURCES =\
|
|||||||
device/dev-swap.c \
|
device/dev-swap.c \
|
||||||
device/dev-type.c \
|
device/dev-type.c \
|
||||||
device/dev-luks.c \
|
device/dev-luks.c \
|
||||||
|
device/dev-dasd.c \
|
||||||
display/display.c \
|
display/display.c \
|
||||||
error/errseg.c \
|
error/errseg.c \
|
||||||
unknown/unknown.c \
|
unknown/unknown.c \
|
||||||
@@ -230,4 +231,4 @@ CFLAGS += $(BLKID_CFLAGS) $(UDEV_CFLAGS) $(VALGRIND_CFLAGS)
|
|||||||
|
|
||||||
$(SUBDIRS): $(LIB_STATIC)
|
$(SUBDIRS): $(LIB_STATIC)
|
||||||
|
|
||||||
DISTCLEAN_TARGETS += misc/configure.h misc/lvm-version.h
|
CLEAN_TARGETS += misc/configure.h misc/lvm-version.h
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "lib.h"
|
#include "lib.h"
|
||||||
@@ -118,8 +118,8 @@ static int _lv_passes_volumes_filter(struct cmd_context *cmd, const struct logic
|
|||||||
|
|
||||||
config_def_get_path(config_path, sizeof(config_path), cfg_id);
|
config_def_get_path(config_path, sizeof(config_path), cfg_id);
|
||||||
log_verbose("%s configuration setting defined: "
|
log_verbose("%s configuration setting defined: "
|
||||||
"Checking the list to match %s/%s",
|
"Checking the list to match %s.",
|
||||||
config_path, lv->vg->name, lv->name);
|
config_path, display_lvname(lv));
|
||||||
|
|
||||||
for (cv = cn->v; cv; cv = cv->next) {
|
for (cv = cn->v; cv; cv = cv->next) {
|
||||||
if (cv->type == DM_CFG_EMPTY_ARRAY)
|
if (cv->type == DM_CFG_EMPTY_ARRAY)
|
||||||
@@ -170,8 +170,8 @@ static int _lv_passes_volumes_filter(struct cmd_context *cmd, const struct logic
|
|||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
log_verbose("No item supplied in %s configuration setting "
|
log_verbose("No item supplied in %s configuration setting matches %s.",
|
||||||
"matches %s/%s", config_path, lv->vg->name, lv->name);
|
config_path, display_lvname(lv));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -333,7 +333,7 @@ int lv_suspend(struct cmd_context *cmd, const char *lvid_s)
|
|||||||
}
|
}
|
||||||
*******/
|
*******/
|
||||||
int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only, unsigned exclusive,
|
int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only, unsigned exclusive,
|
||||||
const struct logical_volume *ondisk_lv, const struct logical_volume *incore_lv)
|
const struct logical_volume *lv, const struct logical_volume *lv_pre)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -389,6 +389,10 @@ int lv_is_active_locally(const struct logical_volume *lv)
|
|||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
int lv_is_active_remotely(const struct logical_volume *lv)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
int lv_is_active_but_not_locally(const struct logical_volume *lv)
|
int lv_is_active_but_not_locally(const struct logical_volume *lv)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
@@ -469,8 +473,8 @@ static int _passes_activation_filter(struct cmd_context *cmd,
|
|||||||
|
|
||||||
if (!(cn = find_config_tree_array(cmd, activation_volume_list_CFG, NULL))) {
|
if (!(cn = find_config_tree_array(cmd, activation_volume_list_CFG, NULL))) {
|
||||||
log_verbose("activation/volume_list configuration setting "
|
log_verbose("activation/volume_list configuration setting "
|
||||||
"not defined: Checking only host tags for %s/%s",
|
"not defined: Checking only host tags for %s.",
|
||||||
lv->vg->name, lv->name);
|
display_lvname(lv));
|
||||||
|
|
||||||
/* If no host tags defined, activate */
|
/* If no host tags defined, activate */
|
||||||
if (dm_list_empty(&cmd->tags))
|
if (dm_list_empty(&cmd->tags))
|
||||||
@@ -481,8 +485,7 @@ static int _passes_activation_filter(struct cmd_context *cmd,
|
|||||||
str_list_match_list(&cmd->tags, &lv->vg->tags, NULL))
|
str_list_match_list(&cmd->tags, &lv->vg->tags, NULL))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
log_verbose("No host tag matches %s/%s",
|
log_verbose("No host tag matches %s", display_lvname(lv));
|
||||||
lv->vg->name, lv->name);
|
|
||||||
|
|
||||||
/* Don't activate */
|
/* Don't activate */
|
||||||
return 0;
|
return 0;
|
||||||
@@ -771,14 +774,14 @@ int lv_check_not_in_use(const struct logical_volume *lv)
|
|||||||
/* If sysfs is not used, use open_count information only. */
|
/* If sysfs is not used, use open_count information only. */
|
||||||
if (dm_sysfs_dir()) {
|
if (dm_sysfs_dir()) {
|
||||||
if (dm_device_has_holders(info.major, info.minor)) {
|
if (dm_device_has_holders(info.major, info.minor)) {
|
||||||
log_error("Logical volume %s/%s is used by another device.",
|
log_error("Logical volume %s is used by another device.",
|
||||||
lv->vg->name, lv->name);
|
display_lvname(lv));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dm_device_has_mounted_fs(info.major, info.minor)) {
|
if (dm_device_has_mounted_fs(info.major, info.minor)) {
|
||||||
log_error("Logical volume %s/%s contains a filesystem in use.",
|
log_error("Logical volume %s contains a filesystem in use.",
|
||||||
lv->vg->name, lv->name);
|
display_lvname(lv));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -786,14 +789,14 @@ int lv_check_not_in_use(const struct logical_volume *lv)
|
|||||||
open_count_check_retries = retry_deactivation() ? OPEN_COUNT_CHECK_RETRIES : 1;
|
open_count_check_retries = retry_deactivation() ? OPEN_COUNT_CHECK_RETRIES : 1;
|
||||||
while (info.open_count > 0 && open_count_check_retries--) {
|
while (info.open_count > 0 && open_count_check_retries--) {
|
||||||
if (!open_count_check_retries) {
|
if (!open_count_check_retries) {
|
||||||
log_error("Logical volume %s/%s in use.",
|
log_error("Logical volume %s in use.",
|
||||||
lv->vg->name, lv->name);
|
display_lvname(lv));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
usleep(OPEN_COUNT_CHECK_USLEEP_DELAY);
|
usleep(OPEN_COUNT_CHECK_USLEEP_DELAY);
|
||||||
log_debug_activation("Retrying open_count check for %s/%s.",
|
log_debug_activation("Retrying open_count check for %s.",
|
||||||
lv->vg->name, lv->name);
|
display_lvname(lv));
|
||||||
if (!lv_info(lv->vg->cmd, lv, 0, &info, 1, 0)) {
|
if (!lv_info(lv->vg->cmd, lv, 0, &info, 1, 0)) {
|
||||||
stack; /* device dissappeared? */
|
stack; /* device dissappeared? */
|
||||||
break;
|
break;
|
||||||
@@ -814,7 +817,8 @@ int lv_check_transient(struct logical_volume *lv)
|
|||||||
if (!activation())
|
if (!activation())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
log_debug_activation("Checking transient status for LV %s/%s", lv->vg->name, lv->name);
|
log_debug_activation("Checking transient status for LV %s.",
|
||||||
|
display_lvname(lv));
|
||||||
|
|
||||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
||||||
return_0;
|
return_0;
|
||||||
@@ -838,7 +842,8 @@ int lv_snapshot_percent(const struct logical_volume *lv, dm_percent_t *percent)
|
|||||||
if (!lv_info(lv->vg->cmd, lv, 0, NULL, 0, 0))
|
if (!lv_info(lv->vg->cmd, lv, 0, NULL, 0, 0))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
log_debug_activation("Checking snapshot percent for LV %s/%s", lv->vg->name, lv->name);
|
log_debug_activation("Checking snapshot percent for LV %s.",
|
||||||
|
display_lvname(lv));
|
||||||
|
|
||||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
||||||
return_0;
|
return_0;
|
||||||
@@ -868,7 +873,8 @@ int lv_mirror_percent(struct cmd_context *cmd, const struct logical_volume *lv,
|
|||||||
if (!lv_info(cmd, lv, 0, NULL, 0, 0))
|
if (!lv_info(cmd, lv, 0, NULL, 0, 0))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
log_debug_activation("Checking mirror percent for LV %s/%s", lv->vg->name, lv->name);
|
log_debug_activation("Checking mirror percent for LV %s.",
|
||||||
|
display_lvname(lv));
|
||||||
|
|
||||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
||||||
return_0;
|
return_0;
|
||||||
@@ -897,8 +903,8 @@ int lv_raid_dev_health(const struct logical_volume *lv, char **dev_health)
|
|||||||
if (!lv_info(lv->vg->cmd, lv, 0, NULL, 0, 0))
|
if (!lv_info(lv->vg->cmd, lv, 0, NULL, 0, 0))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
log_debug_activation("Checking raid device health for LV %s/%s",
|
log_debug_activation("Checking raid device health for LV %s.",
|
||||||
lv->vg->name, lv->name);
|
display_lvname(lv));
|
||||||
|
|
||||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
||||||
return_0;
|
return_0;
|
||||||
@@ -925,8 +931,8 @@ int lv_raid_mismatch_count(const struct logical_volume *lv, uint64_t *cnt)
|
|||||||
if (!lv_info(lv->vg->cmd, lv, 0, NULL, 0, 0))
|
if (!lv_info(lv->vg->cmd, lv, 0, NULL, 0, 0))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
log_debug_activation("Checking raid mismatch count for LV %s/%s",
|
log_debug_activation("Checking raid mismatch count for LV %s.",
|
||||||
lv->vg->name, lv->name);
|
display_lvname(lv));
|
||||||
|
|
||||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
||||||
return_0;
|
return_0;
|
||||||
@@ -953,8 +959,8 @@ int lv_raid_sync_action(const struct logical_volume *lv, char **sync_action)
|
|||||||
if (!lv_info(lv->vg->cmd, lv, 0, NULL, 0, 0))
|
if (!lv_info(lv->vg->cmd, lv, 0, NULL, 0, 0))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
log_debug_activation("Checking raid sync_action for LV %s/%s",
|
log_debug_activation("Checking raid sync_action for LV %s.",
|
||||||
lv->vg->name, lv->name);
|
display_lvname(lv));
|
||||||
|
|
||||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
||||||
return_0;
|
return_0;
|
||||||
@@ -990,12 +996,12 @@ int lv_raid_message(const struct logical_volume *lv, const char *msg)
|
|||||||
(lv_is_raid(seg_lv(first_seg(lv), 0)) ||
|
(lv_is_raid(seg_lv(first_seg(lv), 0)) ||
|
||||||
lv_is_raid(first_seg(lv)->metadata_lv))) {
|
lv_is_raid(first_seg(lv)->metadata_lv))) {
|
||||||
log_error("Thin pool data or metadata volume "
|
log_error("Thin pool data or metadata volume "
|
||||||
"must be specified. (E.g. \"%s/%s_tdata\")",
|
"must be specified. (E.g. \"%s_tdata\")",
|
||||||
lv->vg->name, lv->name);
|
display_lvname(lv));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
log_error("%s/%s must be a RAID logical volume to"
|
log_error("%s must be a RAID logical volume to perform this action.",
|
||||||
" perform this action.", lv->vg->name, lv->name);
|
display_lvname(lv));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1008,8 +1014,8 @@ int lv_raid_message(const struct logical_volume *lv, const char *msg)
|
|||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
if (!(r = dev_manager_raid_status(dm, lv, &status))) {
|
if (!(r = dev_manager_raid_status(dm, lv, &status))) {
|
||||||
log_error("Failed to retrieve status of %s/%s",
|
log_error("Failed to retrieve status of %s.",
|
||||||
lv->vg->name, lv->name);
|
display_lvname(lv));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1036,8 +1042,8 @@ int lv_raid_message(const struct logical_volume *lv, const char *msg)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (strcmp(status->sync_action, "idle")) {
|
if (strcmp(status->sync_action, "idle")) {
|
||||||
log_error("%s/%s state is currently \"%s\". Unable to switch to \"%s\".",
|
log_error("%s state is currently \"%s\". Unable to switch to \"%s\".",
|
||||||
lv->vg->name, lv->name, status->sync_action, msg);
|
display_lvname(lv), status->sync_action, msg);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1101,8 +1107,8 @@ int lv_thin_pool_percent(const struct logical_volume *lv, int metadata,
|
|||||||
if (!lv_info(lv->vg->cmd, lv, 1, NULL, 0, 0))
|
if (!lv_info(lv->vg->cmd, lv, 1, NULL, 0, 0))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
log_debug_activation("Checking thin %sdata percent for LV %s/%s",
|
log_debug_activation("Checking thin %sdata percent for LV %s.",
|
||||||
(metadata) ? "meta" : "", lv->vg->name, lv->name);
|
(metadata) ? "meta" : "", display_lvname(lv));
|
||||||
|
|
||||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
||||||
return_0;
|
return_0;
|
||||||
@@ -1127,8 +1133,8 @@ int lv_thin_percent(const struct logical_volume *lv,
|
|||||||
if (!lv_info(lv->vg->cmd, lv, 0, NULL, 0, 0))
|
if (!lv_info(lv->vg->cmd, lv, 0, NULL, 0, 0))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
log_debug_activation("Checking thin percent for LV %s/%s",
|
log_debug_activation("Checking thin percent for LV %s.",
|
||||||
lv->vg->name, lv->name);
|
display_lvname(lv));
|
||||||
|
|
||||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
||||||
return_0;
|
return_0;
|
||||||
@@ -1154,8 +1160,8 @@ int lv_thin_pool_transaction_id(const struct logical_volume *lv,
|
|||||||
if (!lv_info(lv->vg->cmd, lv, 1, NULL, 0, 0))
|
if (!lv_info(lv->vg->cmd, lv, 1, NULL, 0, 0))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
log_debug_activation("Checking thin percent for LV %s/%s",
|
log_debug_activation("Checking thin percent for LV %s.",
|
||||||
lv->vg->name, lv->name);
|
display_lvname(lv));
|
||||||
|
|
||||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
||||||
return_0;
|
return_0;
|
||||||
@@ -1178,8 +1184,8 @@ int lv_thin_device_id(const struct logical_volume *lv, uint32_t *device_id)
|
|||||||
if (!lv_info(lv->vg->cmd, lv, 0, NULL, 0, 0))
|
if (!lv_info(lv->vg->cmd, lv, 0, NULL, 0, 0))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
log_debug_activation("Checking device id for LV %s/%s",
|
log_debug_activation("Checking device id for LV %s.",
|
||||||
lv->vg->name, lv->name);
|
display_lvname(lv));
|
||||||
|
|
||||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
||||||
return_0;
|
return_0;
|
||||||
@@ -1332,12 +1338,14 @@ int lvs_in_vg_opened(const struct volume_group *vg)
|
|||||||
* _lv_is_active
|
* _lv_is_active
|
||||||
* @lv: logical volume being queried
|
* @lv: logical volume being queried
|
||||||
* @locally: set if active locally (when provided)
|
* @locally: set if active locally (when provided)
|
||||||
|
* @remotely: set if active remotely (when provided)
|
||||||
* @exclusive: set if active exclusively (when provided)
|
* @exclusive: set if active exclusively (when provided)
|
||||||
*
|
*
|
||||||
* Determine whether an LV is active locally or in a cluster.
|
* Determine whether an LV is active locally or in a cluster.
|
||||||
* In addition to the return code which indicates whether or
|
* In addition to the return code which indicates whether or
|
||||||
* not the LV is active somewhere, two other values are set
|
* not the LV is active somewhere, two other values are set
|
||||||
* to yield more information about the status of the activation:
|
* to yield more information about the status of the activation:
|
||||||
|
*
|
||||||
* return locally exclusively status
|
* return locally exclusively status
|
||||||
* ====== ======= =========== ======
|
* ====== ======= =========== ======
|
||||||
* 0 0 0 not active
|
* 0 0 0 not active
|
||||||
@@ -1350,9 +1358,10 @@ int lvs_in_vg_opened(const struct volume_group *vg)
|
|||||||
* Returns: 0 or 1
|
* Returns: 0 or 1
|
||||||
*/
|
*/
|
||||||
static int _lv_is_active(const struct logical_volume *lv,
|
static int _lv_is_active(const struct logical_volume *lv,
|
||||||
int *locally, int *exclusive)
|
int *locally, int *remotely, int *exclusive)
|
||||||
{
|
{
|
||||||
int r, l, e; /* remote, local, and exclusive */
|
int r, l, e; /* remote, local, and exclusive */
|
||||||
|
int skip_cluster_query = 0;
|
||||||
|
|
||||||
r = l = e = 0;
|
r = l = e = 0;
|
||||||
|
|
||||||
@@ -1365,11 +1374,14 @@ static int _lv_is_active(const struct logical_volume *lv,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Active locally, and the caller doesn't care about exclusive */
|
/* Active locally, and the caller doesn't care about exclusive or remotely */
|
||||||
if (l && !exclusive)
|
if (l && !exclusive && !remotely)
|
||||||
|
skip_cluster_query = 1;
|
||||||
|
|
||||||
|
if (skip_cluster_query)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if ((r = remote_lock_held(lv->lvid.s, &e)) >= 0)
|
if ((r = cluster_lock_held(lv->lvid.s, "", &e)) >= 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1381,10 +1393,13 @@ static int _lv_is_active(const struct logical_volume *lv,
|
|||||||
* New users of this function who specifically ask for 'exclusive'
|
* New users of this function who specifically ask for 'exclusive'
|
||||||
* will be given an error message.
|
* will be given an error message.
|
||||||
*/
|
*/
|
||||||
log_error("Unable to determine exclusivity of %s", lv->name);
|
log_error("Unable to determine exclusivity of %s.", display_lvname(lv));
|
||||||
|
|
||||||
e = 0;
|
e = 0;
|
||||||
|
|
||||||
|
/* Also set remotely as a precaution, as we don't know */
|
||||||
|
r = 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We used to attempt activate_lv_excl_local(lv->vg->cmd, lv) here,
|
* We used to attempt activate_lv_excl_local(lv->vg->cmd, lv) here,
|
||||||
* but it's unreliable.
|
* but it's unreliable.
|
||||||
@@ -1395,53 +1410,65 @@ out:
|
|||||||
*locally = l;
|
*locally = l;
|
||||||
if (exclusive)
|
if (exclusive)
|
||||||
*exclusive = e;
|
*exclusive = e;
|
||||||
|
if (remotely)
|
||||||
|
*remotely = r;
|
||||||
|
|
||||||
log_very_verbose("%s/%s is %sactive%s%s",
|
log_very_verbose("%s is %sactive%s%s%s%s",
|
||||||
lv->vg->name, lv->name,
|
display_lvname(lv),
|
||||||
(r || l) ? "" : "not ",
|
(r || l) ? "" : "not ",
|
||||||
(exclusive && e) ? " exclusive" : "",
|
(exclusive && e) ? " exclusive" : "",
|
||||||
e ? (l ? " locally" : " remotely") : "");
|
l ? " locally" : "",
|
||||||
|
(!skip_cluster_query && l && r) ? " and" : "",
|
||||||
|
(!skip_cluster_query && r) ? " remotely" : "");
|
||||||
|
|
||||||
return r || l;
|
return r || l;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lv_is_active(const struct logical_volume *lv)
|
int lv_is_active(const struct logical_volume *lv)
|
||||||
{
|
{
|
||||||
return _lv_is_active(lv, NULL, NULL);
|
return _lv_is_active(lv, NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int lv_is_active_locally(const struct logical_volume *lv)
|
int lv_is_active_locally(const struct logical_volume *lv)
|
||||||
{
|
{
|
||||||
int l;
|
int l;
|
||||||
|
|
||||||
return _lv_is_active(lv, &l, NULL) && l;
|
return _lv_is_active(lv, &l, NULL, NULL) && l;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lv_is_active_remotely(const struct logical_volume *lv)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
|
||||||
|
return _lv_is_active(lv, NULL, &r, NULL) && r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lv_is_active_but_not_locally(const struct logical_volume *lv)
|
int lv_is_active_but_not_locally(const struct logical_volume *lv)
|
||||||
{
|
{
|
||||||
int l;
|
int l;
|
||||||
return _lv_is_active(lv, &l, NULL) && !l;
|
|
||||||
|
return _lv_is_active(lv, &l, NULL, NULL) && !l;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lv_is_active_exclusive(const struct logical_volume *lv)
|
int lv_is_active_exclusive(const struct logical_volume *lv)
|
||||||
{
|
{
|
||||||
int e;
|
int e;
|
||||||
|
|
||||||
return _lv_is_active(lv, NULL, &e) && e;
|
return _lv_is_active(lv, NULL, NULL, &e) && e;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lv_is_active_exclusive_locally(const struct logical_volume *lv)
|
int lv_is_active_exclusive_locally(const struct logical_volume *lv)
|
||||||
{
|
{
|
||||||
int l, e;
|
int l, e;
|
||||||
|
|
||||||
return _lv_is_active(lv, &l, &e) && l && e;
|
return _lv_is_active(lv, &l, NULL, &e) && l && e;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lv_is_active_exclusive_remotely(const struct logical_volume *lv)
|
int lv_is_active_exclusive_remotely(const struct logical_volume *lv)
|
||||||
{
|
{
|
||||||
int l, e;
|
int l, e;
|
||||||
|
|
||||||
return _lv_is_active(lv, &l, &e) && !l && e;
|
return _lv_is_active(lv, &l, NULL, &e) && !l && e;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DMEVENTD
|
#ifdef DMEVENTD
|
||||||
@@ -1606,14 +1633,14 @@ int monitor_dev_for_events(struct cmd_context *cmd, const struct logical_volume
|
|||||||
if (laopts->skip_in_use && lv_is_thin_pool(lv) &&
|
if (laopts->skip_in_use && lv_is_thin_pool(lv) &&
|
||||||
lv_info(lv->vg->cmd, lv, 1, &info, 1, 0) && (info.open_count > 1)) {
|
lv_info(lv->vg->cmd, lv, 1, &info, 1, 0) && (info.open_count > 1)) {
|
||||||
log_debug_activation("Skipping unmonitor of opened %s (open:%d)",
|
log_debug_activation("Skipping unmonitor of opened %s (open:%d)",
|
||||||
lv->name, info.open_count);
|
display_lvname(lv), info.open_count);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do not monitor snapshot that already covers origin */
|
/* Do not monitor snapshot that already covers origin */
|
||||||
if (monitor && lv_is_cow_covering_origin(lv)) {
|
if (monitor && lv_is_cow_covering_origin(lv)) {
|
||||||
log_debug_activation("Skipping monitor of snapshot larger "
|
log_debug_activation("Skipping monitor of snapshot larger "
|
||||||
"then origin %s.", lv->name);
|
"then origin %s.", display_lvname(lv));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1661,7 +1688,7 @@ int monitor_dev_for_events(struct cmd_context *cmd, const struct logical_volume
|
|||||||
monitor)) {
|
monitor)) {
|
||||||
log_error("Failed to %smonitor %s",
|
log_error("Failed to %smonitor %s",
|
||||||
monitor ? "" : "un",
|
monitor ? "" : "un",
|
||||||
seg_lv(seg, s)->name);
|
display_lvname(seg_lv(seg, s)));
|
||||||
r = 0;
|
r = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1698,12 +1725,12 @@ int monitor_dev_for_events(struct cmd_context *cmd, const struct logical_volume
|
|||||||
|
|
||||||
if (monitor) {
|
if (monitor) {
|
||||||
if (monitored)
|
if (monitored)
|
||||||
log_verbose("%s/%s already monitored.", lv->vg->name, lv->name);
|
log_verbose("%s already monitored.", display_lvname(lv));
|
||||||
else if (seg->segtype->ops->target_monitor_events)
|
else if (seg->segtype->ops->target_monitor_events)
|
||||||
monitor_fn = seg->segtype->ops->target_monitor_events;
|
monitor_fn = seg->segtype->ops->target_monitor_events;
|
||||||
} else {
|
} else {
|
||||||
if (!monitored)
|
if (!monitored)
|
||||||
log_verbose("%s/%s already not monitored.", lv->vg->name, lv->name);
|
log_verbose("%s already not monitored.", display_lvname(lv));
|
||||||
else if (seg->segtype->ops->target_unmonitor_events)
|
else if (seg->segtype->ops->target_unmonitor_events)
|
||||||
monitor_fn = seg->segtype->ops->target_unmonitor_events;
|
monitor_fn = seg->segtype->ops->target_unmonitor_events;
|
||||||
}
|
}
|
||||||
@@ -1712,7 +1739,7 @@ int monitor_dev_for_events(struct cmd_context *cmd, const struct logical_volume
|
|||||||
if (!monitor_fn)
|
if (!monitor_fn)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
log_verbose("%sonitoring %s/%s%s", monitor ? "M" : "Not m", lv->vg->name, lv->name,
|
log_verbose("%sonitoring %s%s", monitor ? "M" : "Not m", display_lvname(lv),
|
||||||
test_mode() ? " [Test mode: skipping this]" : "");
|
test_mode() ? " [Test mode: skipping this]" : "");
|
||||||
|
|
||||||
/* FIXME Test mode should really continue a bit further. */
|
/* FIXME Test mode should really continue a bit further. */
|
||||||
@@ -1721,8 +1748,8 @@ int monitor_dev_for_events(struct cmd_context *cmd, const struct logical_volume
|
|||||||
|
|
||||||
/* FIXME specify events */
|
/* FIXME specify events */
|
||||||
if (!monitor_fn(seg, 0)) {
|
if (!monitor_fn(seg, 0)) {
|
||||||
log_error("%s/%s: %s segment monitoring function failed.",
|
log_error("%s: %s segment monitoring function failed.",
|
||||||
lv->vg->name, lv->name, seg->segtype->name);
|
display_lvname(lv), seg->segtype->name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1734,8 +1761,8 @@ int monitor_dev_for_events(struct cmd_context *cmd, const struct logical_volume
|
|||||||
if (pending ||
|
if (pending ||
|
||||||
(!monitored && monitor) ||
|
(!monitored && monitor) ||
|
||||||
(monitored && !monitor))
|
(monitored && !monitor))
|
||||||
log_very_verbose("%s/%s %smonitoring still pending: waiting...",
|
log_very_verbose("%s %smonitoring still pending: waiting...",
|
||||||
lv->vg->name, lv->name, monitor ? "" : "un");
|
display_lvname(lv), monitor ? "" : "un");
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
usleep(10000 * i);
|
usleep(10000 * i);
|
||||||
@@ -1746,8 +1773,8 @@ int monitor_dev_for_events(struct cmd_context *cmd, const struct logical_volume
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!r && !error_message_produced())
|
if (!r && !error_message_produced())
|
||||||
log_error("%sonitoring %s/%s failed.", monitor ? "M" : "Not m",
|
log_error("%sonitoring %s failed.", monitor ? "M" : "Not m",
|
||||||
lv->vg->name, lv->name);
|
display_lvname(lv));
|
||||||
return r;
|
return r;
|
||||||
#else
|
#else
|
||||||
return 1;
|
return 1;
|
||||||
@@ -1763,25 +1790,28 @@ struct detached_lv_data {
|
|||||||
static int _preload_detached_lv(struct logical_volume *lv, void *data)
|
static int _preload_detached_lv(struct logical_volume *lv, void *data)
|
||||||
{
|
{
|
||||||
struct detached_lv_data *detached = data;
|
struct detached_lv_data *detached = data;
|
||||||
struct lv_list *lvl_pre;
|
struct logical_volume *lv_pre;
|
||||||
|
|
||||||
/* Check and preload removed raid image leg or metadata */
|
/* Check and preload removed raid image leg or metadata */
|
||||||
if (lv_is_raid_image(lv)) {
|
if (lv_is_raid_image(lv)) {
|
||||||
if ((lvl_pre = find_lv_in_vg_by_lvid(detached->lv_pre->vg, &lv->lvid)) &&
|
if ((lv_pre = find_lv_in_vg_by_lvid(detached->lv_pre->vg, &lv->lvid)) &&
|
||||||
!lv_is_raid_image(lvl_pre->lv) && lv_is_active(lv) &&
|
!lv_is_raid_image(lv_pre) && lv_is_active(lv) &&
|
||||||
!_lv_preload(lvl_pre->lv, detached->laopts, detached->flush_required))
|
!_lv_preload(lv_pre, detached->laopts, detached->flush_required))
|
||||||
return_0;
|
return_0;
|
||||||
} else if (lv_is_raid_metadata(lv)) {
|
} else if (lv_is_raid_metadata(lv)) {
|
||||||
if ((lvl_pre = find_lv_in_vg_by_lvid(detached->lv_pre->vg, &lv->lvid)) &&
|
if ((lv_pre = find_lv_in_vg_by_lvid(detached->lv_pre->vg, &lv->lvid)) &&
|
||||||
!lv_is_raid_metadata(lvl_pre->lv) && lv_is_active(lv) &&
|
!lv_is_raid_metadata(lv_pre) && lv_is_active(lv) &&
|
||||||
!_lv_preload(lvl_pre->lv, detached->laopts, detached->flush_required))
|
!_lv_preload(lv_pre, detached->laopts, detached->flush_required))
|
||||||
return_0;
|
return_0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((lvl_pre = find_lv_in_vg(detached->lv_pre->vg, lv->name))) {
|
/* FIXME: condition here should be far more limiting to really
|
||||||
if (lv_is_visible(lvl_pre->lv) && lv_is_active(lv) &&
|
* detect detached LVs */
|
||||||
(!lv_is_cow(lv) || !lv_is_cow(lvl_pre->lv)) &&
|
if ((lv_pre = find_lv(detached->lv_pre->vg, lv->name))) {
|
||||||
!_lv_preload(lvl_pre->lv, detached->laopts, detached->flush_required))
|
if (lv_is_visible(lv_pre) && lv_is_active(lv) &&
|
||||||
|
!lv_is_pool(lv) &&
|
||||||
|
(!lv_is_cow(lv) || !lv_is_cow(lv_pre)) &&
|
||||||
|
!_lv_preload(lv_pre, detached->laopts, detached->flush_required))
|
||||||
return_0;
|
return_0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1790,12 +1820,12 @@ static int _preload_detached_lv(struct logical_volume *lv, void *data)
|
|||||||
|
|
||||||
static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
|
static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
|
||||||
struct lv_activate_opts *laopts, int error_if_not_suspended,
|
struct lv_activate_opts *laopts, int error_if_not_suspended,
|
||||||
const struct logical_volume *ondisk_lv, const struct logical_volume *incore_lv)
|
const struct logical_volume *lv, const struct logical_volume *lv_pre)
|
||||||
{
|
{
|
||||||
const struct logical_volume *pvmove_lv = NULL;
|
const struct logical_volume *pvmove_lv = NULL;
|
||||||
const struct logical_volume *ondisk_lv_to_free = NULL;
|
const struct logical_volume *lv_to_free = NULL;
|
||||||
const struct logical_volume *incore_lv_to_free = NULL;
|
const struct logical_volume *lv_pre_to_free = NULL;
|
||||||
struct lv_list *lvl_pre;
|
struct logical_volume *lv_pre_tmp;
|
||||||
struct seg_list *sl;
|
struct seg_list *sl;
|
||||||
struct lv_segment *snap_seg;
|
struct lv_segment *snap_seg;
|
||||||
struct lvinfo info;
|
struct lvinfo info;
|
||||||
@@ -1805,27 +1835,28 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
|
|||||||
if (!activation())
|
if (!activation())
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (!ondisk_lv && !(ondisk_lv_to_free = ondisk_lv = lv_from_lvid(cmd, lvid_s, 0)))
|
/* lv comes from committed metadata */
|
||||||
|
if (!lv && !(lv_to_free = lv = lv_from_lvid(cmd, lvid_s, 0)))
|
||||||
goto_out;
|
goto_out;
|
||||||
|
|
||||||
/* Use precommitted metadata if present */
|
/* Use precommitted metadata if present */
|
||||||
if (!incore_lv && !(incore_lv_to_free = incore_lv = lv_from_lvid(cmd, lvid_s, 1)))
|
if (!lv_pre && !(lv_pre_to_free = lv_pre = lv_from_lvid(cmd, lvid_s, 1)))
|
||||||
goto_out;
|
goto_out;
|
||||||
|
|
||||||
/* Ignore origin_only unless LV is origin in both old and new metadata */
|
/* Ignore origin_only unless LV is origin in both old and new metadata */
|
||||||
/* or LV is thin or thin pool volume */
|
/* or LV is thin or thin pool volume */
|
||||||
if (!lv_is_thin_volume(ondisk_lv) && !lv_is_thin_pool(ondisk_lv) &&
|
if (!lv_is_thin_volume(lv) && !lv_is_thin_pool(lv) &&
|
||||||
!(lv_is_origin(ondisk_lv) && lv_is_origin(incore_lv)))
|
!(lv_is_origin(lv) && lv_is_origin(lv_pre)))
|
||||||
laopts->origin_only = 0;
|
laopts->origin_only = 0;
|
||||||
|
|
||||||
if (test_mode()) {
|
if (test_mode()) {
|
||||||
_skip("Suspending %s%s.", ondisk_lv->name,
|
_skip("Suspending %s%s.", display_lvname(lv),
|
||||||
laopts->origin_only ? " origin without snapshots" : "");
|
laopts->origin_only ? " origin without snapshots" : "");
|
||||||
r = 1;
|
r = 1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!lv_info(cmd, ondisk_lv, laopts->origin_only, &info, 0, 0))
|
if (!lv_info(cmd, lv, laopts->origin_only, &info, 0, 0))
|
||||||
goto_out;
|
goto_out;
|
||||||
|
|
||||||
if (!info.exists || info.suspended) {
|
if (!info.exists || info.suspended) {
|
||||||
@@ -1837,10 +1868,10 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!lv_read_replicator_vgs(ondisk_lv))
|
if (!lv_read_replicator_vgs(lv))
|
||||||
goto_out;
|
goto_out;
|
||||||
|
|
||||||
lv_calculate_readahead(ondisk_lv, NULL);
|
lv_calculate_readahead(lv, NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Preload devices for the LV.
|
* Preload devices for the LV.
|
||||||
@@ -1849,58 +1880,60 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
|
|||||||
* tables for all the changed LVs here, as the relationships
|
* tables for all the changed LVs here, as the relationships
|
||||||
* are not found by walking the new metadata.
|
* are not found by walking the new metadata.
|
||||||
*/
|
*/
|
||||||
if (!lv_is_locked(incore_lv) &&
|
if (lv_is_locked(lv) && !lv_is_locked(lv_pre) &&
|
||||||
lv_is_locked(ondisk_lv) &&
|
(pvmove_lv = find_pvmove_lv_in_lv(lv))) {
|
||||||
(pvmove_lv = find_pvmove_lv_in_lv(ondisk_lv))) {
|
|
||||||
/* Preload all the LVs above the PVMOVE LV */
|
/* Preload all the LVs above the PVMOVE LV */
|
||||||
dm_list_iterate_items(sl, &pvmove_lv->segs_using_this_lv) {
|
dm_list_iterate_items(sl, &pvmove_lv->segs_using_this_lv) {
|
||||||
if (!(lvl_pre = find_lv_in_vg(incore_lv->vg, sl->seg->lv->name))) {
|
if (!(lv_pre_tmp = find_lv(lv_pre->vg, sl->seg->lv->name))) {
|
||||||
log_error(INTERNAL_ERROR "LV %s missing from preload metadata", sl->seg->lv->name);
|
log_error(INTERNAL_ERROR "LV %s missing from preload metadata.",
|
||||||
|
display_lvname(sl->seg->lv));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (!_lv_preload(lvl_pre->lv, laopts, &flush_required))
|
if (!_lv_preload(lv_pre_tmp, laopts, &flush_required))
|
||||||
goto_out;
|
goto_out;
|
||||||
}
|
}
|
||||||
/* Now preload the PVMOVE LV itself */
|
/* Now preload the PVMOVE LV itself */
|
||||||
if (!(lvl_pre = find_lv_in_vg(incore_lv->vg, pvmove_lv->name))) {
|
if (!(lv_pre_tmp = find_lv(lv_pre->vg, pvmove_lv->name))) {
|
||||||
log_error(INTERNAL_ERROR "LV %s missing from preload metadata", pvmove_lv->name);
|
log_error(INTERNAL_ERROR "LV %s missing from preload metadata.",
|
||||||
|
display_lvname(pvmove_lv));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (!_lv_preload(lvl_pre->lv, laopts, &flush_required))
|
if (!_lv_preload(lv_pre_tmp, laopts, &flush_required))
|
||||||
goto_out;
|
goto_out;
|
||||||
} else {
|
} else {
|
||||||
if (!_lv_preload(incore_lv, laopts, &flush_required))
|
if (!_lv_preload(lv_pre, laopts, &flush_required))
|
||||||
/* FIXME Revert preloading */
|
/* FIXME Revert preloading */
|
||||||
goto_out;
|
goto_out;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Search for existing LVs that have become detached and preload them.
|
* Search for existing LVs that have become detached and preload them.
|
||||||
*/
|
*/
|
||||||
detached.lv_pre = incore_lv;
|
detached.lv_pre = lv_pre;
|
||||||
detached.laopts = laopts;
|
detached.laopts = laopts;
|
||||||
detached.flush_required = &flush_required;
|
detached.flush_required = &flush_required;
|
||||||
|
|
||||||
if (!for_each_sub_lv((struct logical_volume *)ondisk_lv, &_preload_detached_lv, &detached))
|
if (!for_each_sub_lv((struct logical_volume *)lv, &_preload_detached_lv, &detached))
|
||||||
goto_out;
|
goto_out;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Preload any snapshots that are being removed.
|
* Preload any snapshots that are being removed.
|
||||||
*/
|
*/
|
||||||
if (!laopts->origin_only && lv_is_origin(ondisk_lv)) {
|
if (!laopts->origin_only && lv_is_origin(lv)) {
|
||||||
dm_list_iterate_items_gen(snap_seg, &ondisk_lv->snapshot_segs, origin_list) {
|
dm_list_iterate_items_gen(snap_seg, &lv->snapshot_segs, origin_list) {
|
||||||
if (!(lvl_pre = find_lv_in_vg_by_lvid(incore_lv->vg, &snap_seg->cow->lvid))) {
|
if (!(lv_pre_tmp = find_lv_in_vg_by_lvid(lv_pre->vg, &snap_seg->cow->lvid))) {
|
||||||
log_error(INTERNAL_ERROR "LV %s (%s) missing from preload metadata",
|
log_error(INTERNAL_ERROR "LV %s (%s) missing from preload metadata.",
|
||||||
snap_seg->cow->name, snap_seg->cow->lvid.id[1].uuid);
|
display_lvname(snap_seg->cow),
|
||||||
|
snap_seg->cow->lvid.id[1].uuid);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (!lv_is_cow(lvl_pre->lv) &&
|
if (!lv_is_cow(lv_pre_tmp) &&
|
||||||
!_lv_preload(lvl_pre->lv, laopts, &flush_required))
|
!_lv_preload(lv_pre_tmp, laopts, &flush_required))
|
||||||
goto_out;
|
goto_out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!monitor_dev_for_events(cmd, ondisk_lv, laopts, 0))
|
if (!monitor_dev_for_events(cmd, lv, laopts, 0))
|
||||||
/* FIXME Consider aborting here */
|
/* FIXME Consider aborting here */
|
||||||
stack;
|
stack;
|
||||||
|
|
||||||
@@ -1909,14 +1942,14 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
|
|||||||
critical_section_inc(cmd, "suspending pvmove LV");
|
critical_section_inc(cmd, "suspending pvmove LV");
|
||||||
|
|
||||||
if (!laopts->origin_only &&
|
if (!laopts->origin_only &&
|
||||||
(lv_is_origin(incore_lv) || lv_is_cow(incore_lv)))
|
(lv_is_origin(lv_pre) || lv_is_cow(lv_pre)))
|
||||||
lockfs = 1;
|
lockfs = 1;
|
||||||
|
|
||||||
/* Converting non-thin LV to thin external origin ? */
|
/* Converting non-thin LV to thin external origin ? */
|
||||||
if (!lv_is_thin_volume(ondisk_lv) && lv_is_thin_volume(incore_lv))
|
if (!lv_is_thin_volume(lv) && lv_is_thin_volume(lv_pre))
|
||||||
lockfs = 1; /* Sync before conversion */
|
lockfs = 1; /* Sync before conversion */
|
||||||
|
|
||||||
if (laopts->origin_only && lv_is_thin_volume(ondisk_lv) && lv_is_thin_volume(incore_lv))
|
if (laopts->origin_only && lv_is_thin_volume(lv) && lv_is_thin_volume(lv_pre))
|
||||||
lockfs = 1;
|
lockfs = 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1927,9 +1960,9 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
|
|||||||
* inactive table to load or not instead so lv_suspend
|
* inactive table to load or not instead so lv_suspend
|
||||||
* can be called separately for each LV safely.
|
* can be called separately for each LV safely.
|
||||||
*/
|
*/
|
||||||
if ((incore_lv->vg->status & PRECOMMITTED) &&
|
if ((lv_pre->vg->status & PRECOMMITTED) &&
|
||||||
lv_is_locked(incore_lv) && find_pvmove_lv_in_lv(incore_lv)) {
|
lv_is_locked(lv_pre) && find_pvmove_lv_in_lv(lv_pre)) {
|
||||||
if (!_lv_suspend_lv(incore_lv, laopts, lockfs, flush_required)) {
|
if (!_lv_suspend_lv(lv_pre, laopts, lockfs, flush_required)) {
|
||||||
critical_section_dec(cmd, "failed precommitted suspend");
|
critical_section_dec(cmd, "failed precommitted suspend");
|
||||||
if (pvmove_lv)
|
if (pvmove_lv)
|
||||||
critical_section_dec(cmd, "failed precommitted suspend (pvmove)");
|
critical_section_dec(cmd, "failed precommitted suspend (pvmove)");
|
||||||
@@ -1937,7 +1970,7 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Normal suspend */
|
/* Normal suspend */
|
||||||
if (!_lv_suspend_lv(ondisk_lv, laopts, lockfs, flush_required)) {
|
if (!_lv_suspend_lv(lv, laopts, lockfs, flush_required)) {
|
||||||
critical_section_dec(cmd, "failed suspend");
|
critical_section_dec(cmd, "failed suspend");
|
||||||
if (pvmove_lv)
|
if (pvmove_lv)
|
||||||
critical_section_dec(cmd, "failed suspend (pvmove)");
|
critical_section_dec(cmd, "failed suspend (pvmove)");
|
||||||
@@ -1947,11 +1980,11 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
|
|||||||
|
|
||||||
r = 1;
|
r = 1;
|
||||||
out:
|
out:
|
||||||
if (incore_lv_to_free)
|
if (lv_pre_to_free)
|
||||||
release_vg(incore_lv_to_free->vg);
|
release_vg(lv_pre_to_free->vg);
|
||||||
if (ondisk_lv_to_free) {
|
if (lv_to_free) {
|
||||||
lv_release_replicator_vgs(ondisk_lv_to_free);
|
lv_release_replicator_vgs(lv_to_free);
|
||||||
release_vg(ondisk_lv_to_free->vg);
|
release_vg(lv_to_free->vg);
|
||||||
}
|
}
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
@@ -1964,23 +1997,16 @@ out:
|
|||||||
* Returns success if the device is not active
|
* Returns success if the device is not active
|
||||||
*/
|
*/
|
||||||
int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only, unsigned exclusive,
|
int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only, unsigned exclusive,
|
||||||
const struct logical_volume *ondisk_lv, const struct logical_volume *incore_lv)
|
const struct logical_volume *lv, const struct logical_volume *lv_pre)
|
||||||
{
|
{
|
||||||
struct lv_activate_opts laopts = {
|
struct lv_activate_opts laopts = {
|
||||||
.origin_only = origin_only,
|
.origin_only = origin_only,
|
||||||
.exclusive = exclusive
|
.exclusive = exclusive
|
||||||
};
|
};
|
||||||
|
|
||||||
return _lv_suspend(cmd, lvid_s, &laopts, 0, ondisk_lv, incore_lv);
|
return _lv_suspend(cmd, lvid_s, &laopts, 0, lv, lv_pre);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No longer used */
|
|
||||||
/***********
|
|
||||||
int lv_suspend(struct cmd_context *cmd, const char *lvid_s)
|
|
||||||
{
|
|
||||||
return _lv_suspend(cmd, lvid_s, 1);
|
|
||||||
}
|
|
||||||
***********/
|
|
||||||
|
|
||||||
static int _lv_resume(struct cmd_context *cmd, const char *lvid_s,
|
static int _lv_resume(struct cmd_context *cmd, const char *lvid_s,
|
||||||
struct lv_activate_opts *laopts, int error_if_not_active,
|
struct lv_activate_opts *laopts, int error_if_not_active,
|
||||||
@@ -2000,13 +2026,14 @@ static int _lv_resume(struct cmd_context *cmd, const char *lvid_s,
|
|||||||
laopts->origin_only = 0;
|
laopts->origin_only = 0;
|
||||||
|
|
||||||
if (test_mode()) {
|
if (test_mode()) {
|
||||||
_skip("Resuming %s%s%s.", lv->name, laopts->origin_only ? " without snapshots" : "",
|
_skip("Resuming %s%s%s.", display_lvname(lv),
|
||||||
|
laopts->origin_only ? " without snapshots" : "",
|
||||||
laopts->revert ? " (reverting)" : "");
|
laopts->revert ? " (reverting)" : "");
|
||||||
r = 1;
|
r = 1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_debug_activation("Resuming LV %s/%s%s%s%s.", lv->vg->name, lv->name,
|
log_debug_activation("Resuming LV %s%s%s%s.", display_lvname(lv),
|
||||||
error_if_not_active ? "" : " if active",
|
error_if_not_active ? "" : " if active",
|
||||||
laopts->origin_only ?
|
laopts->origin_only ?
|
||||||
(lv_is_thin_pool(lv) ? " pool only" :
|
(lv_is_thin_pool(lv) ? " pool only" :
|
||||||
@@ -2084,8 +2111,8 @@ static int _lv_has_open_snapshots(const struct logical_volume *lv)
|
|||||||
r++;
|
r++;
|
||||||
|
|
||||||
if (r)
|
if (r)
|
||||||
log_error("LV %s/%s has open %d snapshot(s), not deactivating.",
|
log_error("LV %s has open %d snapshot(s), not deactivating.",
|
||||||
lv->vg->name, lv->name, r);
|
display_lvname(lv), r);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@@ -2105,12 +2132,12 @@ int lv_deactivate(struct cmd_context *cmd, const char *lvid_s, const struct logi
|
|||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (test_mode()) {
|
if (test_mode()) {
|
||||||
_skip("Deactivating '%s'.", lv->name);
|
_skip("Deactivating %s.", display_lvname(lv));
|
||||||
r = 1;
|
r = 1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_debug_activation("Deactivating %s/%s.", lv->vg->name, lv->name);
|
log_debug_activation("Deactivating %s.", display_lvname(lv));
|
||||||
|
|
||||||
if (!lv_info(cmd, lv, 0, &info, 0, 0))
|
if (!lv_info(cmd, lv, 0, &info, 0, 0))
|
||||||
goto_out;
|
goto_out;
|
||||||
@@ -2179,11 +2206,11 @@ int lv_activation_filter(struct cmd_context *cmd, const char *lvid_s,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!lv && !(lv_to_free = lv = lv_from_lvid(cmd, lvid_s, 0)))
|
if (!lv && !(lv_to_free = lv = lv_from_lvid(cmd, lvid_s, 0)))
|
||||||
goto out;
|
goto_out;
|
||||||
|
|
||||||
if (!_passes_activation_filter(cmd, lv)) {
|
if (!_passes_activation_filter(cmd, lv)) {
|
||||||
log_verbose("Not activating %s/%s since it does not pass "
|
log_verbose("Not activating %s since it does not pass "
|
||||||
"activation filter.", lv->vg->name, lv->name);
|
"activation filter.", display_lvname(lv));
|
||||||
*activate_lv = 0;
|
*activate_lv = 0;
|
||||||
} else
|
} else
|
||||||
*activate_lv = 1;
|
*activate_lv = 1;
|
||||||
@@ -2210,8 +2237,8 @@ static int _lv_activate(struct cmd_context *cmd, const char *lvid_s,
|
|||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (filter && !_passes_activation_filter(cmd, lv)) {
|
if (filter && !_passes_activation_filter(cmd, lv)) {
|
||||||
log_verbose("Not activating %s/%s since it does not pass "
|
log_verbose("Not activating %s since it does not pass "
|
||||||
"activation filter.", lv->vg->name, lv->name);
|
"activation filter.", display_lvname(lv));
|
||||||
r = 1;
|
r = 1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -2234,7 +2261,7 @@ static int _lv_activate(struct cmd_context *cmd, const char *lvid_s,
|
|||||||
|
|
||||||
if (lv_has_unknown_segments(lv)) {
|
if (lv_has_unknown_segments(lv)) {
|
||||||
log_error("Refusing activation of LV %s containing "
|
log_error("Refusing activation of LV %s containing "
|
||||||
"an unrecognised segment.", lv->name);
|
"an unrecognised segment.", display_lvname(lv));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2249,7 +2276,7 @@ static int _lv_activate(struct cmd_context *cmd, const char *lvid_s,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (test_mode()) {
|
if (test_mode()) {
|
||||||
_skip("Activating '%s'.", lv->name);
|
_skip("Activating %s.", display_lvname(lv));
|
||||||
r = 1;
|
r = 1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -2257,7 +2284,7 @@ static int _lv_activate(struct cmd_context *cmd, const char *lvid_s,
|
|||||||
if (filter)
|
if (filter)
|
||||||
laopts->read_only = _passes_readonly_filter(cmd, lv);
|
laopts->read_only = _passes_readonly_filter(cmd, lv);
|
||||||
|
|
||||||
log_debug_activation("Activating %s/%s%s%s%s%s.", lv->vg->name, lv->name,
|
log_debug_activation("Activating %s%s%s%s%s.", display_lvname(lv),
|
||||||
laopts->exclusive ? " exclusively" : "",
|
laopts->exclusive ? " exclusively" : "",
|
||||||
laopts->read_only ? " read-only" : "",
|
laopts->read_only ? " read-only" : "",
|
||||||
laopts->noscan ? " noscan" : "",
|
laopts->noscan ? " noscan" : "",
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef LVM_ACTIVATE_H
|
#ifndef LVM_ACTIVATE_H
|
||||||
@@ -106,7 +106,7 @@ void activation_exit(void);
|
|||||||
|
|
||||||
/* int lv_suspend(struct cmd_context *cmd, const char *lvid_s); */
|
/* int lv_suspend(struct cmd_context *cmd, const char *lvid_s); */
|
||||||
int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only, unsigned exclusive,
|
int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only, unsigned exclusive,
|
||||||
const struct logical_volume *lv_ondisk, const struct logical_volume *lv_incore);
|
const struct logical_volume *lv, const struct logical_volume *lv_pre);
|
||||||
int lv_resume(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only, const struct logical_volume *lv);
|
int lv_resume(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only, const struct logical_volume *lv);
|
||||||
int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s,
|
int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s,
|
||||||
unsigned origin_only, unsigned exclusive, unsigned revert, const struct logical_volume *lv);
|
unsigned origin_only, unsigned exclusive, unsigned revert, const struct logical_volume *lv);
|
||||||
@@ -189,6 +189,7 @@ int lvs_in_vg_opened(const struct volume_group *vg);
|
|||||||
|
|
||||||
int lv_is_active(const struct logical_volume *lv);
|
int lv_is_active(const struct logical_volume *lv);
|
||||||
int lv_is_active_locally(const struct logical_volume *lv);
|
int lv_is_active_locally(const struct logical_volume *lv);
|
||||||
|
int lv_is_active_remotely(const struct logical_volume *lv);
|
||||||
int lv_is_active_but_not_locally(const struct logical_volume *lv);
|
int lv_is_active_but_not_locally(const struct logical_volume *lv);
|
||||||
int lv_is_active_exclusive(const struct logical_volume *lv);
|
int lv_is_active_exclusive(const struct logical_volume *lv);
|
||||||
int lv_is_active_exclusive_locally(const struct logical_volume *lv);
|
int lv_is_active_exclusive_locally(const struct logical_volume *lv);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
|
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
|
||||||
* Copyright (C) 2004-2014 Red Hat, Inc. All rights reserved.
|
* Copyright (C) 2004-2015 Red Hat, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* This file is part of LVM2.
|
* This file is part of LVM2.
|
||||||
*
|
*
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "lib.h"
|
#include "lib.h"
|
||||||
@@ -66,7 +66,7 @@ struct dev_manager {
|
|||||||
unsigned track_pending_delete;
|
unsigned track_pending_delete;
|
||||||
unsigned track_pvmove_deps;
|
unsigned track_pvmove_deps;
|
||||||
|
|
||||||
char *vg_name;
|
const char *vg_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct lv_layer {
|
struct lv_layer {
|
||||||
@@ -143,23 +143,23 @@ static int _get_segment_status_from_target_params(const char *target_name,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(segtype->name, "cache")) {
|
if (segtype_is_cache(segtype)) {
|
||||||
if (!dm_get_status_cache(seg_status->mem, params, &(seg_status->cache)))
|
if (!dm_get_status_cache(seg_status->mem, params, &(seg_status->cache)))
|
||||||
return_0;
|
return_0;
|
||||||
seg_status->type = SEG_STATUS_CACHE;
|
seg_status->type = SEG_STATUS_CACHE;
|
||||||
} else if (!strcmp(segtype->name, "raid")) {
|
} else if (segtype_is_raid(segtype)) {
|
||||||
if (!dm_get_status_raid(seg_status->mem, params, &seg_status->raid))
|
if (!dm_get_status_raid(seg_status->mem, params, &seg_status->raid))
|
||||||
return_0;
|
return_0;
|
||||||
seg_status->type = SEG_STATUS_RAID;
|
seg_status->type = SEG_STATUS_RAID;
|
||||||
} else if (!strcmp(segtype->name, "thin")) {
|
} else if (segtype_is_thin_volume(segtype)) {
|
||||||
if (!dm_get_status_thin(seg_status->mem, params, &seg_status->thin))
|
if (!dm_get_status_thin(seg_status->mem, params, &seg_status->thin))
|
||||||
return_0;
|
return_0;
|
||||||
seg_status->type = SEG_STATUS_THIN;
|
seg_status->type = SEG_STATUS_THIN;
|
||||||
} else if (!strcmp(segtype->name, "thin-pool")) {
|
} else if (segtype_is_thin_pool(segtype)) {
|
||||||
if (!dm_get_status_thin_pool(seg_status->mem, params, &seg_status->thin_pool))
|
if (!dm_get_status_thin_pool(seg_status->mem, params, &seg_status->thin_pool))
|
||||||
return_0;
|
return_0;
|
||||||
seg_status->type = SEG_STATUS_THIN_POOL;
|
seg_status->type = SEG_STATUS_THIN_POOL;
|
||||||
} else if (!strcmp(segtype->name, "snapshot")) {
|
} else if (segtype_is_snapshot(segtype)) {
|
||||||
if (!dm_get_status_snapshot(seg_status->mem, params, &seg_status->snapshot))
|
if (!dm_get_status_snapshot(seg_status->mem, params, &seg_status->snapshot))
|
||||||
return_0;
|
return_0;
|
||||||
seg_status->type = SEG_STATUS_SNAPSHOT;
|
seg_status->type = SEG_STATUS_SNAPSHOT;
|
||||||
@@ -246,79 +246,6 @@ static int _info_run(info_type_t type, const char *name, const char *dlid,
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* _parse_mirror_status
|
|
||||||
* @mirror_status_string
|
|
||||||
* @image_health: return for allocated copy of image health characters
|
|
||||||
* @log_device: return for 'dev_t' of log device
|
|
||||||
* @log_health: NULL if corelog, otherwise dm_malloc'ed log health char which
|
|
||||||
* the caller must free
|
|
||||||
*
|
|
||||||
* This function takes the mirror status string, breaks it up and returns
|
|
||||||
* its components. For now, we only return the health characters. This
|
|
||||||
* is an internal function. If there are more things we want to return
|
|
||||||
* later, we can do that then.
|
|
||||||
*
|
|
||||||
* Returns: 1 on success, 0 on failure
|
|
||||||
*/
|
|
||||||
static int _parse_mirror_status(char *mirror_status_str,
|
|
||||||
char **images_health,
|
|
||||||
dev_t *log_dev, char **log_health)
|
|
||||||
{
|
|
||||||
int major, minor;
|
|
||||||
char *p = NULL;
|
|
||||||
char **args, **log_args;
|
|
||||||
unsigned num_devs, log_argc;
|
|
||||||
|
|
||||||
*images_health = NULL;
|
|
||||||
*log_health = NULL;
|
|
||||||
*log_dev = 0;
|
|
||||||
|
|
||||||
if (!dm_split_words(mirror_status_str, 1, 0, &p) ||
|
|
||||||
!(num_devs = (unsigned) atoi(p)))
|
|
||||||
/* On errors, we must assume the mirror is to be avoided */
|
|
||||||
return_0;
|
|
||||||
|
|
||||||
p += strlen(p) + 1;
|
|
||||||
args = alloca((num_devs + 5) * sizeof(char *));
|
|
||||||
|
|
||||||
if ((unsigned)dm_split_words(p, num_devs + 4, 0, args) < num_devs + 4)
|
|
||||||
return_0;
|
|
||||||
|
|
||||||
log_argc = (unsigned) atoi(args[3 + num_devs]);
|
|
||||||
log_args = alloca(log_argc * sizeof(char *));
|
|
||||||
|
|
||||||
if ((unsigned)dm_split_words(args[3 + num_devs] + strlen(args[3 + num_devs]) + 1,
|
|
||||||
log_argc, 0, log_args) < log_argc)
|
|
||||||
return_0;
|
|
||||||
|
|
||||||
if (!strcmp(log_args[0], "disk")) {
|
|
||||||
if (!(*log_health = dm_strdup(log_args[2]))) {
|
|
||||||
log_error("Allocation of log string failed.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (sscanf(log_args[1], "%d:%d", &major, &minor) != 2) {
|
|
||||||
log_error("Failed to parse log's device number from %s.", log_args[1]);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
*log_dev = MKDEV((dev_t)major, minor);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(*images_health = dm_strdup(args[2 + num_devs]))) {
|
|
||||||
log_error("Allocation of images string failed.");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
out:
|
|
||||||
dm_free(*log_health);
|
|
||||||
*log_health = NULL;
|
|
||||||
*log_dev = 0;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ignore_blocked_mirror_devices
|
* ignore_blocked_mirror_devices
|
||||||
* @dev
|
* @dev
|
||||||
@@ -349,51 +276,53 @@ static int _ignore_blocked_mirror_devices(struct device *dev,
|
|||||||
uint64_t start, uint64_t length,
|
uint64_t start, uint64_t length,
|
||||||
char *mirror_status_str)
|
char *mirror_status_str)
|
||||||
{
|
{
|
||||||
|
struct dm_pool *mem;
|
||||||
|
struct dm_status_mirror *sm;
|
||||||
unsigned i, check_for_blocking = 0;
|
unsigned i, check_for_blocking = 0;
|
||||||
dev_t log_dev;
|
|
||||||
char *images_health, *log_health;
|
|
||||||
uint64_t s,l;
|
uint64_t s,l;
|
||||||
char *p, *params, *target_type = NULL;
|
char *p, *params, *target_type = NULL;
|
||||||
void *next = NULL;
|
void *next = NULL;
|
||||||
struct dm_task *dmt = NULL;
|
struct dm_task *dmt = NULL;
|
||||||
int r = 0;
|
int r = 0;
|
||||||
|
struct device *tmp_dev;
|
||||||
|
char buf[16];
|
||||||
|
|
||||||
if (!_parse_mirror_status(mirror_status_str,
|
if (!(mem = dm_pool_create("blocked_mirrors", 128)))
|
||||||
&images_health, &log_dev, &log_health))
|
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
for (i = 0; images_health[i]; i++)
|
if (!dm_get_status_mirror(mem, mirror_status_str, &sm))
|
||||||
if (images_health[i] != 'A') {
|
goto_out;
|
||||||
|
|
||||||
|
for (i = 0; i < sm->dev_count; ++i)
|
||||||
|
if (sm->devs[i].health != DM_STATUS_MIRROR_ALIVE) {
|
||||||
log_debug_activation("%s: Mirror image %d marked as failed",
|
log_debug_activation("%s: Mirror image %d marked as failed",
|
||||||
dev_name(dev), i);
|
dev_name(dev), i);
|
||||||
check_for_blocking = 1;
|
check_for_blocking = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!check_for_blocking && log_dev) {
|
if (!check_for_blocking && sm->log_count) {
|
||||||
if (log_health[0] != 'A') {
|
if (sm->logs[0].health != DM_STATUS_MIRROR_ALIVE) {
|
||||||
log_debug_activation("%s: Mirror log device marked as failed",
|
log_debug_activation("%s: Mirror log device marked as failed",
|
||||||
dev_name(dev));
|
dev_name(dev));
|
||||||
check_for_blocking = 1;
|
check_for_blocking = 1;
|
||||||
} else {
|
} else {
|
||||||
struct device *tmp_dev;
|
|
||||||
char buf[16];
|
|
||||||
|
|
||||||
if (dm_snprintf(buf, sizeof(buf), "%d:%d",
|
if (dm_snprintf(buf, sizeof(buf), "%u:%u",
|
||||||
(int)MAJOR(log_dev),
|
sm->logs[0].major, sm->logs[0].minor) < 0)
|
||||||
(int)MINOR(log_dev)) < 0)
|
|
||||||
goto_out;
|
goto_out;
|
||||||
|
|
||||||
if (!(tmp_dev = dev_create_file(buf, NULL, NULL, 0)))
|
if (!(tmp_dev = dev_create_file(buf, NULL, NULL, 0)))
|
||||||
goto_out;
|
goto_out;
|
||||||
|
|
||||||
tmp_dev->dev = log_dev;
|
tmp_dev->dev = MKDEV((dev_t)sm->logs[0].major, sm->logs[0].minor);
|
||||||
if (device_is_usable(tmp_dev, (struct dev_usable_check_params)
|
if (device_is_usable(tmp_dev, (struct dev_usable_check_params)
|
||||||
{ .check_empty = 1,
|
{ .check_empty = 1,
|
||||||
.check_blocked = 1,
|
.check_blocked = 1,
|
||||||
.check_suspended = ignore_suspended_devices(),
|
.check_suspended = ignore_suspended_devices(),
|
||||||
.check_error_target = 1,
|
.check_error_target = 1,
|
||||||
.check_reserved = 0 }))
|
.check_reserved = 0 }))
|
||||||
goto_out;
|
goto out; /* safe to use */
|
||||||
|
stack;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -440,8 +369,8 @@ static int _ignore_blocked_mirror_devices(struct device *dev,
|
|||||||
out:
|
out:
|
||||||
if (dmt)
|
if (dmt)
|
||||||
dm_task_destroy(dmt);
|
dm_task_destroy(dmt);
|
||||||
dm_free(log_health);
|
|
||||||
dm_free(images_health);
|
dm_pool_destroy(mem);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@@ -498,14 +427,14 @@ static int _ignore_suspended_snapshot_component(struct device *dev)
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
next = dm_get_next_target(dmt, next, &start, &length, &target_type, ¶ms);
|
next = dm_get_next_target(dmt, next, &start, &length, &target_type, ¶ms);
|
||||||
if (!strcmp(target_type, "snapshot")) {
|
if (!target_type || !strcmp(target_type, "snapshot")) {
|
||||||
if (sscanf(params, "%d:%d %d:%d", &major1, &minor1, &major2, &minor2) != 4) {
|
if (!params || sscanf(params, "%d:%d %d:%d", &major1, &minor1, &major2, &minor2) != 4) {
|
||||||
log_error("Incorrect snapshot table found");
|
log_error("Incorrect snapshot table found");
|
||||||
goto_out;
|
goto_out;
|
||||||
}
|
}
|
||||||
r = r || _device_is_suspended(major1, minor1) || _device_is_suspended(major2, minor2);
|
r = r || _device_is_suspended(major1, minor1) || _device_is_suspended(major2, minor2);
|
||||||
} else if (!strcmp(target_type, "snapshot-origin")) {
|
} else if (!strcmp(target_type, "snapshot-origin")) {
|
||||||
if (sscanf(params, "%d:%d", &major1, &minor1) != 2) {
|
if (!params || sscanf(params, "%d:%d", &major1, &minor1) != 2) {
|
||||||
log_error("Incorrect snapshot-origin table found");
|
log_error("Incorrect snapshot-origin table found");
|
||||||
goto_out;
|
goto_out;
|
||||||
}
|
}
|
||||||
@@ -518,6 +447,73 @@ out:
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _ignore_unusable_thins(struct device *dev)
|
||||||
|
{
|
||||||
|
/* TODO make function for thin testing */
|
||||||
|
struct dm_pool *mem;
|
||||||
|
struct dm_status_thin_pool *status;
|
||||||
|
struct dm_task *dmt = NULL;
|
||||||
|
void *next = NULL;
|
||||||
|
uint64_t start, length;
|
||||||
|
char *target_type = NULL;
|
||||||
|
char *params;
|
||||||
|
int minor, major;
|
||||||
|
int r = 0;
|
||||||
|
|
||||||
|
if (!(mem = dm_pool_create("unusable_thins", 128)))
|
||||||
|
return_0;
|
||||||
|
|
||||||
|
if (!(dmt = dm_task_create(DM_DEVICE_TABLE)))
|
||||||
|
goto_out;
|
||||||
|
if (!dm_task_no_open_count(dmt))
|
||||||
|
goto_out;
|
||||||
|
if (!dm_task_set_major_minor(dmt, MAJOR(dev->dev), MINOR(dev->dev), 1))
|
||||||
|
goto_out;
|
||||||
|
if (!dm_task_run(dmt)) {
|
||||||
|
log_error("Failed to get state of mapped device.");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
dm_get_next_target(dmt, next, &start, &length, &target_type, ¶ms);
|
||||||
|
if (!params || sscanf(params, "%d:%d", &minor, &major) != 2) {
|
||||||
|
log_error("Failed to get thin-pool major:minor for thin device %d:%d.",
|
||||||
|
(int)MAJOR(dev->dev), (int)MINOR(dev->dev));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
dm_task_destroy(dmt);
|
||||||
|
|
||||||
|
if (!(dmt = dm_task_create(DM_DEVICE_STATUS)))
|
||||||
|
goto_out;
|
||||||
|
if (!dm_task_no_flush(dmt))
|
||||||
|
log_warn("Can't set no_flush.");
|
||||||
|
if (!dm_task_no_open_count(dmt))
|
||||||
|
goto_out;
|
||||||
|
if (!dm_task_set_major_minor(dmt, minor, major, 1))
|
||||||
|
goto_out;
|
||||||
|
if (!dm_task_run(dmt)) {
|
||||||
|
log_error("Failed to get state of mapped device.");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
dm_get_next_target(dmt, next, &start, &length, &target_type, ¶ms);
|
||||||
|
if (!dm_get_status_thin_pool(mem, params, &status))
|
||||||
|
goto_out;
|
||||||
|
|
||||||
|
if (status->read_only || status->out_of_data_space) {
|
||||||
|
log_warn("WARNING: %s: Thin's thin-pool needs inspection.",
|
||||||
|
dev_name(dev));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = 1;
|
||||||
|
out:
|
||||||
|
if (dmt)
|
||||||
|
dm_task_destroy(dmt);
|
||||||
|
|
||||||
|
dm_pool_destroy(mem);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* device_is_usable
|
* device_is_usable
|
||||||
* @dev
|
* @dev
|
||||||
@@ -646,6 +642,13 @@ int device_is_usable(struct device *dev, struct dev_usable_check_params check)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO: extend check struct ? */
|
||||||
|
if (target_type && !strcmp(target_type, "thin") &&
|
||||||
|
!_ignore_unusable_thins(dev)) {
|
||||||
|
log_debug_activation("%s: %s device %s not usable.", dev_name(dev), target_type, name);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (target_type && strcmp(target_type, "error"))
|
if (target_type && strcmp(target_type, "error"))
|
||||||
only_error_target = 0;
|
only_error_target = 0;
|
||||||
} while (next);
|
} while (next);
|
||||||
@@ -720,15 +723,12 @@ int dev_manager_info(struct dm_pool *mem, const struct logical_volume *lv,
|
|||||||
char *dlid, *name;
|
char *dlid, *name;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (!(name = dm_build_dm_name(mem, lv->vg->name, lv->name, layer))) {
|
if (!(name = dm_build_dm_name(mem, lv->vg->name, lv->name, layer)))
|
||||||
log_error("name build failed for %s", lv->name);
|
return_0;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(dlid = build_dm_uuid(mem, lv, layer))) {
|
if (!(dlid = build_dm_uuid(mem, lv, layer))) {
|
||||||
log_error("dlid build failed for %s", name);
|
|
||||||
r = 0;
|
r = 0;
|
||||||
goto out;
|
goto_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_debug_activation("Getting device info for %s [%s]", name, dlid);
|
log_debug_activation("Getting device info for %s [%s]", name, dlid);
|
||||||
@@ -749,16 +749,15 @@ static const struct dm_info *_cached_dm_info(struct dm_pool *mem,
|
|||||||
const struct dm_tree_node *dnode;
|
const struct dm_tree_node *dnode;
|
||||||
const struct dm_info *dinfo = NULL;
|
const struct dm_info *dinfo = NULL;
|
||||||
|
|
||||||
if (!(dlid = build_dm_uuid(mem, lv, layer))) {
|
if (!(dlid = build_dm_uuid(mem, lv, layer)))
|
||||||
log_error("Failed to build dlid for %s.", lv->name);
|
return_NULL;
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(dnode = dm_tree_find_node_by_uuid(dtree, dlid)))
|
if (!(dnode = dm_tree_find_node_by_uuid(dtree, dlid)))
|
||||||
goto_out;
|
goto_out;
|
||||||
|
|
||||||
if (!(dinfo = dm_tree_node_get_info(dnode))) {
|
if (!(dinfo = dm_tree_node_get_info(dnode))) {
|
||||||
log_error("Failed to get info from tree node for %s.", lv->name);
|
log_error("Failed to get info from tree node for %s.",
|
||||||
|
display_lvname(lv));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -770,83 +769,6 @@ out:
|
|||||||
return dinfo;
|
return dinfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* FIXME Interface must cope with multiple targets */
|
|
||||||
static int _status_run(const char *name, const char *uuid,
|
|
||||||
unsigned long long *s, unsigned long long *l,
|
|
||||||
char **t, uint32_t t_size, char **p, uint32_t p_size)
|
|
||||||
{
|
|
||||||
int r = 0;
|
|
||||||
struct dm_task *dmt;
|
|
||||||
struct dm_info info;
|
|
||||||
void *next = NULL;
|
|
||||||
uint64_t start, length;
|
|
||||||
char *type = NULL;
|
|
||||||
char *params = NULL;
|
|
||||||
|
|
||||||
if (!(dmt = _setup_task(name, uuid, 0, DM_DEVICE_STATUS, 0, 0, 0)))
|
|
||||||
return_0;
|
|
||||||
|
|
||||||
if (!dm_task_run(dmt))
|
|
||||||
goto_out;
|
|
||||||
|
|
||||||
if (!dm_task_get_info(dmt, &info) || !info.exists)
|
|
||||||
goto_out;
|
|
||||||
|
|
||||||
do {
|
|
||||||
next = dm_get_next_target(dmt, next, &start, &length,
|
|
||||||
&type, ¶ms);
|
|
||||||
if (type) {
|
|
||||||
*s = start;
|
|
||||||
*l = length;
|
|
||||||
/* Make sure things are null terminated */
|
|
||||||
strncpy(*t, type, t_size);
|
|
||||||
(*t)[t_size - 1] = '\0';
|
|
||||||
strncpy(*p, params, p_size);
|
|
||||||
(*p)[p_size - 1] = '\0';
|
|
||||||
|
|
||||||
r = 1;
|
|
||||||
/* FIXME Cope with multiple targets! */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
} while (next);
|
|
||||||
|
|
||||||
out:
|
|
||||||
dm_task_destroy(dmt);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _status(const char *name, const char *uuid,
|
|
||||||
unsigned long long *start, unsigned long long *length,
|
|
||||||
char **type, uint32_t type_size, char **params,
|
|
||||||
uint32_t param_size) __attribute__ ((unused));
|
|
||||||
|
|
||||||
static int _status(const char *name, const char *uuid,
|
|
||||||
unsigned long long *start, unsigned long long *length,
|
|
||||||
char **type, uint32_t type_size, char **params,
|
|
||||||
uint32_t param_size)
|
|
||||||
{
|
|
||||||
if (uuid && *uuid) {
|
|
||||||
if (_status_run(NULL, uuid, start, length, type,
|
|
||||||
type_size, params, param_size) &&
|
|
||||||
*params)
|
|
||||||
return 1;
|
|
||||||
else if (_status_run(NULL, uuid + sizeof(UUID_PREFIX) - 1, start,
|
|
||||||
length, type, type_size, params,
|
|
||||||
param_size) &&
|
|
||||||
*params)
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (name && _status_run(name, NULL, start, length, type, type_size,
|
|
||||||
params, param_size))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int lv_has_target_type(struct dm_pool *mem, const struct logical_volume *lv,
|
int lv_has_target_type(struct dm_pool *mem, const struct logical_volume *lv,
|
||||||
const char *layer, const char *target_type)
|
const char *layer, const char *target_type)
|
||||||
{
|
{
|
||||||
@@ -971,6 +893,11 @@ static int _percent_run(struct dev_manager *dm, const char *name,
|
|||||||
wait ? DM_DEVICE_WAITEVENT : DM_DEVICE_STATUS, 0, 0, 0)))
|
wait ? DM_DEVICE_WAITEVENT : DM_DEVICE_STATUS, 0, 0, 0)))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
|
/* No freeze on overfilled thin-pool, read existing slightly outdated data */
|
||||||
|
if (lv && lv_is_thin_pool(lv) &&
|
||||||
|
!dm_task_no_flush(dmt))
|
||||||
|
log_warn("Can't set no_flush flag."); /* Non fatal */
|
||||||
|
|
||||||
if (!dm_task_run(dmt))
|
if (!dm_task_run(dmt))
|
||||||
goto_out;
|
goto_out;
|
||||||
|
|
||||||
@@ -986,7 +913,8 @@ static int _percent_run(struct dev_manager *dm, const char *name,
|
|||||||
if (lv) {
|
if (lv) {
|
||||||
if (!(segh = dm_list_next(&lv->segments, segh))) {
|
if (!(segh = dm_list_next(&lv->segments, segh))) {
|
||||||
log_error("Number of segments in active LV %s "
|
log_error("Number of segments in active LV %s "
|
||||||
"does not match metadata", lv->name);
|
"does not match metadata.",
|
||||||
|
display_lvname(lv));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
seg = dm_list_item(segh, struct lv_segment);
|
seg = dm_list_item(segh, struct lv_segment);
|
||||||
@@ -1026,7 +954,7 @@ static int _percent_run(struct dev_manager *dm, const char *name,
|
|||||||
|
|
||||||
if (lv && dm_list_next(&lv->segments, segh)) {
|
if (lv && dm_list_next(&lv->segments, segh)) {
|
||||||
log_error("Number of segments in active LV %s does not "
|
log_error("Number of segments in active LV %s does not "
|
||||||
"match metadata", lv->name);
|
"match metadata.", display_lvname(lv));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1038,7 +966,7 @@ static int _percent_run(struct dev_manager *dm, const char *name,
|
|||||||
goto_out;
|
goto_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_debug_activation("LV percent: %f", dm_percent_to_float(*overall_percent));
|
log_debug_activation("LV percent: %.2f", dm_percent_to_float(*overall_percent));
|
||||||
r = 1;
|
r = 1;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
@@ -1101,7 +1029,7 @@ int dev_manager_transient(struct dev_manager *dm, const struct logical_volume *l
|
|||||||
|
|
||||||
if (!(segh = dm_list_next(&lv->segments, segh))) {
|
if (!(segh = dm_list_next(&lv->segments, segh))) {
|
||||||
log_error("Number of segments in active LV %s "
|
log_error("Number of segments in active LV %s "
|
||||||
"does not match metadata", lv->name);
|
"does not match metadata.", display_lvname(lv));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
seg = dm_list_item(segh, struct lv_segment);
|
seg = dm_list_item(segh, struct lv_segment);
|
||||||
@@ -1115,14 +1043,14 @@ int dev_manager_transient(struct dev_manager *dm, const struct logical_volume *l
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (seg->segtype->ops->check_transient_status &&
|
if (seg->segtype->ops->check_transient_status &&
|
||||||
!seg->segtype->ops->check_transient_status(seg, params))
|
!seg->segtype->ops->check_transient_status(dm->mem, seg, params))
|
||||||
goto_out;
|
goto_out;
|
||||||
|
|
||||||
} while (next);
|
} while (next);
|
||||||
|
|
||||||
if (dm_list_next(&lv->segments, segh)) {
|
if (dm_list_next(&lv->segments, segh)) {
|
||||||
log_error("Number of segments in active LV %s does not "
|
log_error("Number of segments in active LV %s does not "
|
||||||
"match metadata", lv->name);
|
"match metadata.", display_lvname(lv));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1151,9 +1079,7 @@ struct dev_manager *dev_manager_create(struct cmd_context *cmd,
|
|||||||
|
|
||||||
dm->cmd = cmd;
|
dm->cmd = cmd;
|
||||||
dm->mem = mem;
|
dm->mem = mem;
|
||||||
|
dm->vg_name = vg_name;
|
||||||
if (!(dm->vg_name = dm_pool_strdup(dm->mem, vg_name)))
|
|
||||||
goto_bad;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When we manipulate (normally suspend/resume) the PVMOVE
|
* When we manipulate (normally suspend/resume) the PVMOVE
|
||||||
@@ -1256,10 +1182,8 @@ int dev_manager_mirror_percent(struct dev_manager *dm,
|
|||||||
if (!(name = dm_build_dm_name(dm->mem, lv->vg->name, lv->name, layer)))
|
if (!(name = dm_build_dm_name(dm->mem, lv->vg->name, lv->name, layer)))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
if (!(dlid = build_dm_uuid(dm->mem, lv, layer))) {
|
if (!(dlid = build_dm_uuid(dm->mem, lv, layer)))
|
||||||
log_error("dlid build failed for %s", lv->name);
|
return_0;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
log_debug_activation("Getting device %s status percentage for %s",
|
log_debug_activation("Getting device %s status percentage for %s",
|
||||||
target_type, name);
|
target_type, name);
|
||||||
@@ -1325,20 +1249,20 @@ int dev_manager_raid_message(struct dev_manager *dm,
|
|||||||
const char *layer = lv_layer(lv);
|
const char *layer = lv_layer(lv);
|
||||||
|
|
||||||
if (!lv_is_raid(lv)) {
|
if (!lv_is_raid(lv)) {
|
||||||
log_error(INTERNAL_ERROR "%s/%s is not a RAID logical volume",
|
log_error(INTERNAL_ERROR "%s is not a RAID logical volume",
|
||||||
lv->vg->name, lv->name);
|
display_lvname(lv));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* These are the supported RAID messages for dm-raid v1.5.0 */
|
/* These are the supported RAID messages for dm-raid v1.5.0 */
|
||||||
if (!strcmp(msg, "idle") &&
|
if (strcmp(msg, "idle") &&
|
||||||
!strcmp(msg, "frozen") &&
|
strcmp(msg, "frozen") &&
|
||||||
!strcmp(msg, "resync") &&
|
strcmp(msg, "resync") &&
|
||||||
!strcmp(msg, "recover") &&
|
strcmp(msg, "recover") &&
|
||||||
!strcmp(msg, "check") &&
|
strcmp(msg, "check") &&
|
||||||
!strcmp(msg, "repair") &&
|
strcmp(msg, "repair") &&
|
||||||
!strcmp(msg, "reshape")) {
|
strcmp(msg, "reshape")) {
|
||||||
log_error("Unknown RAID message: %s", msg);
|
log_error(INTERNAL_ERROR "Unknown RAID message: %s", msg);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1420,66 +1344,6 @@ out:
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
//FIXME: Can we get rid of this crap below?
|
|
||||||
#if 0
|
|
||||||
log_very_verbose("%s %s", sus ? "Suspending" : "Resuming", name);
|
|
||||||
|
|
||||||
log_verbose("Loading %s", dl->name);
|
|
||||||
log_very_verbose("Activating %s read-only", dl->name);
|
|
||||||
log_very_verbose("Activated %s %s %03u:%03u", dl->name,
|
|
||||||
dl->dlid, dl->info.major, dl->info.minor);
|
|
||||||
|
|
||||||
if (_get_flag(dl, VISIBLE))
|
|
||||||
log_verbose("Removing %s", dl->name);
|
|
||||||
else
|
|
||||||
log_very_verbose("Removing %s", dl->name);
|
|
||||||
|
|
||||||
log_debug_activation("Adding target: %" PRIu64 " %" PRIu64 " %s %s",
|
|
||||||
extent_size * seg->le, extent_size * seg->len, target, params);
|
|
||||||
|
|
||||||
log_debug_activation("Adding target: 0 %" PRIu64 " snapshot-origin %s",
|
|
||||||
dl->lv->size, params);
|
|
||||||
log_debug_activation("Adding target: 0 %" PRIu64 " snapshot %s", size, params);
|
|
||||||
log_debug_activation("Getting device info for %s", dl->name);
|
|
||||||
|
|
||||||
/* Rename? */
|
|
||||||
if ((suffix = strrchr(dl->dlid + sizeof(UUID_PREFIX) - 1, '-')))
|
|
||||||
suffix++;
|
|
||||||
new_name = dm_build_dm_name(dm->mem, dm->vg_name, dl->lv->name,
|
|
||||||
suffix);
|
|
||||||
|
|
||||||
static int _belong_to_vg(const char *vgname, const char *name)
|
|
||||||
{
|
|
||||||
const char *v = vgname, *n = name;
|
|
||||||
|
|
||||||
while (*v) {
|
|
||||||
if ((*v != *n) || (*v == '-' && *(++n) != '-'))
|
|
||||||
return 0;
|
|
||||||
v++, n++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*n == '-' && *(n + 1) != '-')
|
|
||||||
return 1;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(snap_seg = find_snapshot(lv)))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
old_origin = snap_seg->origin;
|
|
||||||
|
|
||||||
/* Was this the last active snapshot with this origin? */
|
|
||||||
dm_list_iterate_items(lvl, active_head) {
|
|
||||||
active = lvl->lv;
|
|
||||||
if ((snap_seg = find_snapshot(active)) &&
|
|
||||||
snap_seg->origin == old_origin) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int dev_manager_thin_pool_status(struct dev_manager *dm,
|
int dev_manager_thin_pool_status(struct dev_manager *dm,
|
||||||
const struct logical_volume *lv,
|
const struct logical_volume *lv,
|
||||||
struct dm_status_thin_pool **status,
|
struct dm_status_thin_pool **status,
|
||||||
@@ -1595,17 +1459,20 @@ int dev_manager_thin_device_id(struct dev_manager *dm,
|
|||||||
|
|
||||||
if (dm_get_next_target(dmt, NULL, &start, &length,
|
if (dm_get_next_target(dmt, NULL, &start, &length,
|
||||||
&target_type, ¶ms)) {
|
&target_type, ¶ms)) {
|
||||||
log_error("More then one table line found for %s.", lv->name);
|
log_error("More then one table line found for %s.",
|
||||||
|
display_lvname(lv));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(target_type, "thin")) {
|
if (!target_type || strcmp(target_type, "thin")) {
|
||||||
log_error("Unexpected target type %s found for thin %s.", target_type, lv->name);
|
log_error("Unexpected target type %s found for thin %s.",
|
||||||
|
target_type, display_lvname(lv));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sscanf(params, "%*u:%*u %u", device_id) != 1) {
|
if (!params || sscanf(params, "%*u:%*u %u", device_id) != 1) {
|
||||||
log_error("Cannot parse table like parameters %s for %s.", params, lv->name);
|
log_error("Cannot parse table like parameters %s for %s.",
|
||||||
|
params, display_lvname(lv));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1805,7 +1672,8 @@ static int _add_dev_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
|
|||||||
log_error("Volume %s (%" PRIu32 ":%" PRIu32")"
|
log_error("Volume %s (%" PRIu32 ":%" PRIu32")"
|
||||||
" differs from already active device "
|
" differs from already active device "
|
||||||
"(%" PRIu32 ":%" PRIu32")",
|
"(%" PRIu32 ":%" PRIu32")",
|
||||||
lv->name, lv->major, lv->minor, info.major, info.minor);
|
display_lvname(lv), lv->major, lv->minor,
|
||||||
|
info.major, info.minor);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!info.exists && _info_by_dev(lv->major, lv->minor, &info2) &&
|
if (!info.exists && _info_by_dev(lv->major, lv->minor, &info2) &&
|
||||||
@@ -1825,7 +1693,8 @@ static int _add_dev_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (info.exists && dm->track_pending_delete) {
|
if (info.exists && dm->track_pending_delete) {
|
||||||
log_debug_activation("Tracking pending delete for %s (%s).", lv->name, dlid);
|
log_debug_activation("Tracking pending delete for %s (%s).",
|
||||||
|
display_lvname(lv), dlid);
|
||||||
if (!str_list_add(dm->mem, &dm->pending_delete, dlid))
|
if (!str_list_add(dm->mem, &dm->pending_delete, dlid))
|
||||||
return_0;
|
return_0;
|
||||||
}
|
}
|
||||||
@@ -2232,7 +2101,8 @@ static int _add_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
|
|||||||
return_0;
|
return_0;
|
||||||
if (seg->pool_lv &&
|
if (seg->pool_lv &&
|
||||||
(lv_is_cache_pool(seg->pool_lv) || !dm->skip_external_lv) &&
|
(lv_is_cache_pool(seg->pool_lv) || !dm->skip_external_lv) &&
|
||||||
!_add_lv_to_dtree(dm, dtree, seg->pool_lv, 1)) /* stack */
|
/* When activating and not origin_only detect linear 'overlay' over pool */
|
||||||
|
!_add_lv_to_dtree(dm, dtree, seg->pool_lv, dm->activation ? origin_only : 1))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
for (s = 0; s < seg->area_count; s++) {
|
for (s = 0; s < seg->area_count; s++) {
|
||||||
@@ -2260,7 +2130,8 @@ static struct dm_tree *_create_partial_dtree(struct dev_manager *dm, const struc
|
|||||||
struct dm_tree *dtree;
|
struct dm_tree *dtree;
|
||||||
|
|
||||||
if (!(dtree = dm_tree_create())) {
|
if (!(dtree = dm_tree_create())) {
|
||||||
log_debug_activation("Partial dtree creation failed for %s.", lv->name);
|
log_debug_activation("Partial dtree creation failed for %s.",
|
||||||
|
display_lvname(lv));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2377,7 +2248,8 @@ int add_areas_line(struct dev_manager *dm, struct lv_segment *seg,
|
|||||||
if (!seg->lv->vg->cmd->degraded_activation ||
|
if (!seg->lv->vg->cmd->degraded_activation ||
|
||||||
!lv_is_raid_type(seg->lv)) {
|
!lv_is_raid_type(seg->lv)) {
|
||||||
log_error("Aborting. LV %s is now incomplete "
|
log_error("Aborting. LV %s is now incomplete "
|
||||||
"and '--activationmode partial' was not specified.", seg->lv->name);
|
"and '--activationmode partial' was not specified.",
|
||||||
|
display_lvname(seg->lv));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2428,7 +2300,7 @@ int add_areas_line(struct dev_manager *dm, struct lv_segment *seg,
|
|||||||
return_0;
|
return_0;
|
||||||
} else {
|
} else {
|
||||||
log_error(INTERNAL_ERROR "Unassigned area found in LV %s.",
|
log_error(INTERNAL_ERROR "Unassigned area found in LV %s.",
|
||||||
seg->lv->name);
|
display_lvname(seg->lv));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2436,8 +2308,8 @@ int add_areas_line(struct dev_manager *dm, struct lv_segment *seg,
|
|||||||
if (num_error_areas) {
|
if (num_error_areas) {
|
||||||
/* Thins currently do not support partial activation */
|
/* Thins currently do not support partial activation */
|
||||||
if (lv_is_thin_type(seg->lv)) {
|
if (lv_is_thin_type(seg->lv)) {
|
||||||
log_error("Cannot activate %s%s: pool incomplete.",
|
log_error("Cannot activate %s: pool incomplete.",
|
||||||
seg->lv->vg->name, seg->lv->name);
|
display_lvname(seg->lv));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2487,7 +2359,8 @@ static int _add_snapshot_merge_target_to_dtree(struct dev_manager *dm,
|
|||||||
struct lv_segment *merging_snap_seg = find_snapshot(lv);
|
struct lv_segment *merging_snap_seg = find_snapshot(lv);
|
||||||
|
|
||||||
if (!lv_is_merging_origin(lv)) {
|
if (!lv_is_merging_origin(lv)) {
|
||||||
log_error(INTERNAL_ERROR "LV %s is not merging snapshot.", lv->name);
|
log_error(INTERNAL_ERROR "LV %s is not merging snapshot.",
|
||||||
|
display_lvname(lv));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2519,7 +2392,8 @@ static int _add_snapshot_target_to_dtree(struct dev_manager *dm,
|
|||||||
uint64_t size;
|
uint64_t size;
|
||||||
|
|
||||||
if (!(snap_seg = find_snapshot(lv))) {
|
if (!(snap_seg = find_snapshot(lv))) {
|
||||||
log_error("Couldn't find snapshot for '%s'.", lv->name);
|
log_error("Couldn't find snapshot for '%s'.",
|
||||||
|
display_lvname(lv));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2644,8 +2518,8 @@ static int _add_new_external_lv_to_dtree(struct dev_manager *dm,
|
|||||||
*/
|
*/
|
||||||
dm->skip_external_lv = 1;
|
dm->skip_external_lv = 1;
|
||||||
|
|
||||||
log_debug_activation("Adding external origin lv %s and all active users.",
|
log_debug_activation("Adding external origin LV %s and all active users.",
|
||||||
external_lv->name);
|
display_lvname(external_lv));
|
||||||
|
|
||||||
if (!_add_new_lv_to_dtree(dm, dtree, external_lv, laopts,
|
if (!_add_new_lv_to_dtree(dm, dtree, external_lv, laopts,
|
||||||
lv_layer(external_lv)))
|
lv_layer(external_lv)))
|
||||||
@@ -2656,7 +2530,6 @@ static int _add_new_external_lv_to_dtree(struct dev_manager *dm,
|
|||||||
* needed because of conversion of thin which could have been
|
* needed because of conversion of thin which could have been
|
||||||
* also an old-snapshot to external origin.
|
* also an old-snapshot to external origin.
|
||||||
*/
|
*/
|
||||||
//if (lv_is_origin(external_lv))
|
|
||||||
dm_list_iterate_items(sl, &external_lv->segs_using_this_lv)
|
dm_list_iterate_items(sl, &external_lv->segs_using_this_lv)
|
||||||
if ((sl->seg->external_lv == external_lv) &&
|
if ((sl->seg->external_lv == external_lv) &&
|
||||||
/* Add only active layered devices (also avoids loop) */
|
/* Add only active layered devices (also avoids loop) */
|
||||||
@@ -2666,8 +2539,9 @@ static int _add_new_external_lv_to_dtree(struct dev_manager *dm,
|
|||||||
laopts, lv_layer(sl->seg->lv)))
|
laopts, lv_layer(sl->seg->lv)))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
log_debug_activation("Finished adding external origin lv %s and all active users.",
|
log_debug_activation("Finished adding external origin LV %s and all active users.",
|
||||||
external_lv->name);
|
display_lvname(external_lv));
|
||||||
|
|
||||||
dm->skip_external_lv = 0;
|
dm->skip_external_lv = 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@@ -2694,14 +2568,14 @@ static int _add_segment_to_dtree(struct dev_manager *dm,
|
|||||||
segtype->name);
|
segtype->name);
|
||||||
|
|
||||||
log_debug_activation("Checking kernel supports %s segment type for %s%s%s",
|
log_debug_activation("Checking kernel supports %s segment type for %s%s%s",
|
||||||
target_name, seg->lv->name,
|
target_name, display_lvname(seg->lv),
|
||||||
layer ? "-" : "", layer ? : "");
|
layer ? "-" : "", layer ? : "");
|
||||||
|
|
||||||
if (segtype->ops->target_present &&
|
if (segtype->ops->target_present &&
|
||||||
!segtype->ops->target_present(seg_present->lv->vg->cmd,
|
!segtype->ops->target_present(seg_present->lv->vg->cmd,
|
||||||
seg_present, NULL)) {
|
seg_present, NULL)) {
|
||||||
log_error("Can't process LV %s: %s target support missing "
|
log_error("Can't process LV %s: %s target support missing "
|
||||||
"from kernel?", seg->lv->name, target_name);
|
"from kernel?", display_lvname(seg->lv), target_name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2748,7 +2622,7 @@ static int _add_segment_to_dtree(struct dev_manager *dm,
|
|||||||
if (dm->track_pending_delete) {
|
if (dm->track_pending_delete) {
|
||||||
/* Replace target and all its used devs with error mapping */
|
/* Replace target and all its used devs with error mapping */
|
||||||
log_debug_activation("Using error for pending delete %s.",
|
log_debug_activation("Using error for pending delete %s.",
|
||||||
seg->lv->name);
|
display_lvname(seg->lv));
|
||||||
if (!dm_tree_node_add_error_target(dnode, (uint64_t)seg->lv->vg->extent_size * seg->len))
|
if (!dm_tree_node_add_error_target(dnode, (uint64_t)seg->lv->vg->extent_size * seg->len))
|
||||||
return_0;
|
return_0;
|
||||||
} else if (!_add_target_to_dtree(dm, dnode, seg, laopts))
|
} else if (!_add_target_to_dtree(dm, dnode, seg, laopts))
|
||||||
@@ -2757,59 +2631,6 @@ static int _add_segment_to_dtree(struct dev_manager *dm,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
static int _set_udev_flags_for_children(struct dev_manager *dm,
|
|
||||||
struct volume_group *vg,
|
|
||||||
struct dm_tree_node *dnode)
|
|
||||||
{
|
|
||||||
char *p;
|
|
||||||
const char *uuid;
|
|
||||||
void *handle = NULL;
|
|
||||||
struct dm_tree_node *child;
|
|
||||||
const struct dm_info *info;
|
|
||||||
struct lv_list *lvl;
|
|
||||||
|
|
||||||
while ((child = dm_tree_next_child(&handle, dnode, 0))) {
|
|
||||||
/* Ignore root node */
|
|
||||||
if (!(info = dm_tree_node_get_info(child)) || !info->exists)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!(uuid = dm_tree_node_get_uuid(child))) {
|
|
||||||
log_error(INTERNAL_ERROR
|
|
||||||
"Failed to get uuid for %" PRIu32 ":%" PRIu32,
|
|
||||||
info->major, info->minor);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ignore non-LVM devices */
|
|
||||||
if (!(p = strstr(uuid, UUID_PREFIX)))
|
|
||||||
continue;
|
|
||||||
p += strlen(UUID_PREFIX);
|
|
||||||
|
|
||||||
/* Ignore LVs that belong to different VGs (due to stacking) */
|
|
||||||
if (strncmp(p, (char *)vg->id.uuid, ID_LEN))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Ignore LVM devices with 'layer' suffixes */
|
|
||||||
if (strrchr(p, '-'))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!(lvl = find_lv_in_vg_by_lvid(vg, (const union lvid *)p))) {
|
|
||||||
log_error(INTERNAL_ERROR
|
|
||||||
"%s (%" PRIu32 ":%" PRIu32 ") not found in VG",
|
|
||||||
dm_tree_node_get_name(child),
|
|
||||||
info->major, info->minor);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
dm_tree_node_set_udev_flags(child,
|
|
||||||
_get_udev_flags(dm, lvl->lv, NULL, 0, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
|
static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
|
||||||
const struct logical_volume *lv, struct lv_activate_opts *laopts,
|
const struct logical_volume *lv, struct lv_activate_opts *laopts,
|
||||||
const char *layer)
|
const char *layer)
|
||||||
@@ -2882,7 +2703,7 @@ static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
|
|||||||
|
|
||||||
if (!(lvlayer = dm_pool_alloc(dm->mem, sizeof(*lvlayer)))) {
|
if (!(lvlayer = dm_pool_alloc(dm->mem, sizeof(*lvlayer)))) {
|
||||||
log_error("_add_new_lv_to_dtree: pool alloc failed for %s %s.",
|
log_error("_add_new_lv_to_dtree: pool alloc failed for %s %s.",
|
||||||
lv->name, layer);
|
display_lvname(lv), layer);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2995,12 +2816,6 @@ static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
|
|||||||
if (!_add_new_lv_to_dtree(dm, dtree, sl->seg->lv, laopts, NULL))
|
if (!_add_new_lv_to_dtree(dm, dtree, sl->seg->lv, laopts, NULL))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* Should not be needed, will be removed */
|
|
||||||
if (!_set_udev_flags_for_children(dm, lv->vg, dnode))
|
|
||||||
return_0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
dm->track_pending_delete = save_pending_delete; /* restore */
|
dm->track_pending_delete = save_pending_delete; /* restore */
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@@ -3158,7 +2973,8 @@ static int _tree_action(struct dev_manager *dm, const struct logical_volume *lv,
|
|||||||
/* Some LV can be used for top level tree */
|
/* Some LV can be used for top level tree */
|
||||||
/* TODO: add more.... */
|
/* TODO: add more.... */
|
||||||
if (lv_is_cache_pool(lv) && !dm_list_empty(&lv->segs_using_this_lv)) {
|
if (lv_is_cache_pool(lv) && !dm_list_empty(&lv->segs_using_this_lv)) {
|
||||||
log_error(INTERNAL_ERROR "Cannot create tree for %s.", lv->name);
|
log_error(INTERNAL_ERROR "Cannot create tree for %s.",
|
||||||
|
display_lvname(lv));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* Some targets may build bigger tree for activation */
|
/* Some targets may build bigger tree for activation */
|
||||||
@@ -3194,11 +3010,12 @@ static int _tree_action(struct dev_manager *dm, const struct logical_volume *lv,
|
|||||||
if (!dm_tree_deactivate_children(root, dlid, DLID_SIZE))
|
if (!dm_tree_deactivate_children(root, dlid, DLID_SIZE))
|
||||||
goto_out;
|
goto_out;
|
||||||
if (!_remove_lv_symlinks(dm, root))
|
if (!_remove_lv_symlinks(dm, root))
|
||||||
log_warn("Failed to remove all device symlinks associated with %s.", lv->name);
|
log_warn("Failed to remove all device symlinks associated with %s.",
|
||||||
|
display_lvname(lv));
|
||||||
break;
|
break;
|
||||||
case SUSPEND:
|
case SUSPEND:
|
||||||
dm_tree_skip_lockfs(root);
|
dm_tree_skip_lockfs(root);
|
||||||
if (!dm->flush_required && lv_is_mirror(lv) && !lv_is_pvmove(lv))
|
if (!dm->flush_required && !lv_is_pvmove(lv))
|
||||||
dm_tree_use_no_flush_suspend(root);
|
dm_tree_use_no_flush_suspend(root);
|
||||||
/* Fall through */
|
/* Fall through */
|
||||||
case SUSPEND_WITH_LOCKFS:
|
case SUSPEND_WITH_LOCKFS:
|
||||||
@@ -3217,14 +3034,22 @@ static int _tree_action(struct dev_manager *dm, const struct logical_volume *lv,
|
|||||||
if (!dm_tree_preload_children(root, dlid, DLID_SIZE))
|
if (!dm_tree_preload_children(root, dlid, DLID_SIZE))
|
||||||
goto_out;
|
goto_out;
|
||||||
|
|
||||||
if (dm_tree_node_size_changed(root))
|
if ((dm_tree_node_size_changed(root) < 0))
|
||||||
|
dm->flush_required = 1;
|
||||||
|
|
||||||
|
/* Currently keep the code require flush for any
|
||||||
|
* non 'thin pool/volume, mirror' or with any size change */
|
||||||
|
if (!lv_is_thin_volume(lv) &&
|
||||||
|
!lv_is_thin_pool(lv) &&
|
||||||
|
(!lv_is_mirror(lv) || dm_tree_node_size_changed(root)))
|
||||||
dm->flush_required = 1;
|
dm->flush_required = 1;
|
||||||
|
|
||||||
if (action == ACTIVATE) {
|
if (action == ACTIVATE) {
|
||||||
if (!dm_tree_activate_children(root, dlid, DLID_SIZE))
|
if (!dm_tree_activate_children(root, dlid, DLID_SIZE))
|
||||||
goto_out;
|
goto_out;
|
||||||
if (!_create_lv_symlinks(dm, root))
|
if (!_create_lv_symlinks(dm, root))
|
||||||
log_warn("Failed to create symlinks for %s.", lv->name);
|
log_warn("Failed to create symlinks for %s.",
|
||||||
|
display_lvname(lv));
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _LVM_DEV_MANAGER_H
|
#ifndef _LVM_DEV_MANAGER_H
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "lib.h"
|
#include "lib.h"
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _LVM_FS_H
|
#ifndef _LVM_FS_H
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _LVM_TARGETS_H
|
#ifndef _LVM_TARGETS_H
|
||||||
|
|||||||
190
lib/cache/lvmcache.c
vendored
190
lib/cache/lvmcache.c
vendored
@@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "lib.h"
|
#include "lib.h"
|
||||||
@@ -56,6 +56,7 @@ struct lvmcache_vginfo {
|
|||||||
char _padding[7];
|
char _padding[7];
|
||||||
struct lvmcache_vginfo *next; /* Another VG with same name? */
|
struct lvmcache_vginfo *next; /* Another VG with same name? */
|
||||||
char *creation_host;
|
char *creation_host;
|
||||||
|
char *system_id;
|
||||||
char *lock_type;
|
char *lock_type;
|
||||||
uint32_t mda_checksum;
|
uint32_t mda_checksum;
|
||||||
size_t mda_size;
|
size_t mda_size;
|
||||||
@@ -81,6 +82,7 @@ static int _has_scanned = 0;
|
|||||||
static int _vgs_locked = 0;
|
static int _vgs_locked = 0;
|
||||||
static int _vg_global_lock_held = 0; /* Global lock held when cache wiped? */
|
static int _vg_global_lock_held = 0; /* Global lock held when cache wiped? */
|
||||||
static int _found_duplicate_pvs = 0; /* If we never see a duplicate PV we can skip checking for them later. */
|
static int _found_duplicate_pvs = 0; /* If we never see a duplicate PV we can skip checking for them later. */
|
||||||
|
static int _suppress_lock_ordering = 0;
|
||||||
|
|
||||||
int lvmcache_init(void)
|
int lvmcache_init(void)
|
||||||
{
|
{
|
||||||
@@ -330,7 +332,7 @@ void lvmcache_commit_metadata(const char *vgname)
|
|||||||
|
|
||||||
void lvmcache_drop_metadata(const char *vgname, int drop_precommitted)
|
void lvmcache_drop_metadata(const char *vgname, int drop_precommitted)
|
||||||
{
|
{
|
||||||
if (lvmcache_vgname_is_locked(VG_GLOBAL) && !vg_write_lock_held())
|
if (lvmcache_vgname_is_locked(VG_GLOBAL))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* For VG_ORPHANS, we need to invalidate all labels on orphan PVs. */
|
/* For VG_ORPHANS, we need to invalidate all labels on orphan PVs. */
|
||||||
@@ -370,6 +372,11 @@ static int _vgname_order_correct(const char *vgname1, const char *vgname2)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lvmcache_lock_ordering(int enable)
|
||||||
|
{
|
||||||
|
_suppress_lock_ordering = !enable;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ensure VG locks are acquired in alphabetical order.
|
* Ensure VG locks are acquired in alphabetical order.
|
||||||
*/
|
*/
|
||||||
@@ -378,6 +385,9 @@ int lvmcache_verify_lock_order(const char *vgname)
|
|||||||
struct dm_hash_node *n;
|
struct dm_hash_node *n;
|
||||||
const char *vgname2;
|
const char *vgname2;
|
||||||
|
|
||||||
|
if (_suppress_lock_ordering)
|
||||||
|
return 1;
|
||||||
|
|
||||||
if (!_lock_hash)
|
if (!_lock_hash)
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
@@ -442,8 +452,10 @@ void lvmcache_unlock_vgname(const char *vgname)
|
|||||||
dm_hash_remove(_lock_hash, vgname);
|
dm_hash_remove(_lock_hash, vgname);
|
||||||
|
|
||||||
/* FIXME Do this per-VG */
|
/* FIXME Do this per-VG */
|
||||||
if (strcmp(vgname, VG_GLOBAL) && !--_vgs_locked)
|
if (strcmp(vgname, VG_GLOBAL) && !--_vgs_locked) {
|
||||||
dev_close_all();
|
dev_close_all();
|
||||||
|
dev_size_seqno_inc(); /* invalidate all cached dev sizes */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int lvmcache_vgs_locked(void)
|
int lvmcache_vgs_locked(void)
|
||||||
@@ -613,6 +625,23 @@ const char *lvmcache_vgname_from_vgid(struct dm_pool *mem, const char *vgid)
|
|||||||
return vgname;
|
return vgname;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *lvmcache_vgid_from_vgname(struct cmd_context *cmd, const char *vgname)
|
||||||
|
{
|
||||||
|
struct lvmcache_vginfo *vginfo;
|
||||||
|
|
||||||
|
if (!(vginfo = dm_hash_lookup(_vgname_hash, vgname)))
|
||||||
|
return_NULL;
|
||||||
|
|
||||||
|
if (!vginfo->next)
|
||||||
|
return dm_pool_strdup(cmd->mem, vginfo->vgid);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There are multiple VGs with this name to choose from.
|
||||||
|
* Return an error because we don't know which VG is intended.
|
||||||
|
*/
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static int _info_is_valid(struct lvmcache_info *info)
|
static int _info_is_valid(struct lvmcache_info *info)
|
||||||
{
|
{
|
||||||
if (info->status & CACHE_INVALID)
|
if (info->status & CACHE_INVALID)
|
||||||
@@ -725,12 +754,30 @@ static int _scan_invalid(void)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lvmcache_label_scan(struct cmd_context *cmd, int full_scan)
|
/*
|
||||||
|
* lvmcache_label_scan() remembers that it has already
|
||||||
|
* been called, and will not scan labels if it's called
|
||||||
|
* again. (It will rescan "INVALID" devices if called again.)
|
||||||
|
*
|
||||||
|
* To force lvmcache_label_scan() to rescan labels on all devices,
|
||||||
|
* call lvmcache_force_next_label_scan() before calling
|
||||||
|
* lvmcache_label_scan().
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int _force_label_scan;
|
||||||
|
|
||||||
|
void lvmcache_force_next_label_scan(void)
|
||||||
|
{
|
||||||
|
_force_label_scan = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lvmcache_label_scan(struct cmd_context *cmd)
|
||||||
{
|
{
|
||||||
struct label *label;
|
struct label *label;
|
||||||
struct dev_iter *iter;
|
struct dev_iter *iter;
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
struct format_type *fmt;
|
struct format_type *fmt;
|
||||||
|
int dev_count = 0;
|
||||||
|
|
||||||
int r = 0;
|
int r = 0;
|
||||||
|
|
||||||
@@ -748,24 +795,30 @@ int lvmcache_label_scan(struct cmd_context *cmd, int full_scan)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_has_scanned && !full_scan) {
|
if (_has_scanned && !_force_label_scan) {
|
||||||
r = _scan_invalid();
|
r = _scan_invalid();
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (full_scan == 2 && (cmd->full_filter && !cmd->full_filter->use_count) && !refresh_filters(cmd))
|
if (_force_label_scan && (cmd->full_filter && !cmd->full_filter->use_count) && !refresh_filters(cmd))
|
||||||
goto_out;
|
goto_out;
|
||||||
|
|
||||||
if (!cmd->full_filter || !(iter = dev_iter_create(cmd->full_filter, (full_scan == 2) ? 1 : 0))) {
|
if (!cmd->full_filter || !(iter = dev_iter_create(cmd->full_filter, _force_label_scan))) {
|
||||||
log_error("dev_iter creation failed");
|
log_error("dev_iter creation failed");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((dev = dev_iter_get(iter)))
|
log_very_verbose("Scanning device labels");
|
||||||
|
|
||||||
|
while ((dev = dev_iter_get(iter))) {
|
||||||
(void) label_read(dev, &label, UINT64_C(0));
|
(void) label_read(dev, &label, UINT64_C(0));
|
||||||
|
dev_count++;
|
||||||
|
}
|
||||||
|
|
||||||
dev_iter_destroy(iter);
|
dev_iter_destroy(iter);
|
||||||
|
|
||||||
|
log_very_verbose("Scanned %d device labels", dev_count);
|
||||||
|
|
||||||
_has_scanned = 1;
|
_has_scanned = 1;
|
||||||
|
|
||||||
/* Perform any format-specific scanning e.g. text files */
|
/* Perform any format-specific scanning e.g. text files */
|
||||||
@@ -778,7 +831,7 @@ int lvmcache_label_scan(struct cmd_context *cmd, int full_scan)
|
|||||||
* If we are a long-lived process, write out the updated persistent
|
* If we are a long-lived process, write out the updated persistent
|
||||||
* device cache for the benefit of short-lived processes.
|
* device cache for the benefit of short-lived processes.
|
||||||
*/
|
*/
|
||||||
if (full_scan == 2 && cmd->is_long_lived &&
|
if (_force_label_scan && cmd->is_long_lived &&
|
||||||
cmd->dump_filter && cmd->full_filter && cmd->full_filter->dump &&
|
cmd->dump_filter && cmd->full_filter && cmd->full_filter->dump &&
|
||||||
!cmd->full_filter->dump(cmd->full_filter, 0))
|
!cmd->full_filter->dump(cmd->full_filter, 0))
|
||||||
stack;
|
stack;
|
||||||
@@ -787,6 +840,7 @@ int lvmcache_label_scan(struct cmd_context *cmd, int full_scan)
|
|||||||
|
|
||||||
out:
|
out:
|
||||||
_scanning_in_progress = 0;
|
_scanning_in_progress = 0;
|
||||||
|
_force_label_scan = 0;
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@@ -912,7 +966,7 @@ int lvmcache_get_vgnameids(struct cmd_context *cmd, int include_internal,
|
|||||||
struct vgnameid_list *vgnl;
|
struct vgnameid_list *vgnl;
|
||||||
struct lvmcache_vginfo *vginfo;
|
struct lvmcache_vginfo *vginfo;
|
||||||
|
|
||||||
lvmcache_label_scan(cmd, 0);
|
lvmcache_label_scan(cmd);
|
||||||
|
|
||||||
dm_list_iterate_items(vginfo, &_vginfos) {
|
dm_list_iterate_items(vginfo, &_vginfos) {
|
||||||
if (!include_internal && is_orphan_vg(vginfo->vgname))
|
if (!include_internal && is_orphan_vg(vginfo->vgname))
|
||||||
@@ -944,7 +998,7 @@ struct dm_list *lvmcache_get_vgids(struct cmd_context *cmd,
|
|||||||
struct lvmcache_vginfo *vginfo;
|
struct lvmcache_vginfo *vginfo;
|
||||||
|
|
||||||
// TODO plug into lvmetad here automagically?
|
// TODO plug into lvmetad here automagically?
|
||||||
lvmcache_label_scan(cmd, 0);
|
lvmcache_label_scan(cmd);
|
||||||
|
|
||||||
if (!(vgids = str_list_create(cmd->mem))) {
|
if (!(vgids = str_list_create(cmd->mem))) {
|
||||||
log_error("vgids list allocation failed");
|
log_error("vgids list allocation failed");
|
||||||
@@ -971,7 +1025,7 @@ struct dm_list *lvmcache_get_vgnames(struct cmd_context *cmd,
|
|||||||
struct dm_list *vgnames;
|
struct dm_list *vgnames;
|
||||||
struct lvmcache_vginfo *vginfo;
|
struct lvmcache_vginfo *vginfo;
|
||||||
|
|
||||||
lvmcache_label_scan(cmd, 0);
|
lvmcache_label_scan(cmd);
|
||||||
|
|
||||||
if (!(vgnames = str_list_create(cmd->mem))) {
|
if (!(vgnames = str_list_create(cmd->mem))) {
|
||||||
log_errno(ENOMEM, "vgnames list allocation failed");
|
log_errno(ENOMEM, "vgnames list allocation failed");
|
||||||
@@ -1053,7 +1107,7 @@ struct device *lvmcache_device_from_pvid(struct cmd_context *cmd, const struct i
|
|||||||
if (dev)
|
if (dev)
|
||||||
return dev;
|
return dev;
|
||||||
|
|
||||||
lvmcache_label_scan(cmd, 0);
|
lvmcache_label_scan(cmd);
|
||||||
|
|
||||||
/* Try again */
|
/* Try again */
|
||||||
dev = _device_from_pvid(pvid, label_sector);
|
dev = _device_from_pvid(pvid, label_sector);
|
||||||
@@ -1063,7 +1117,8 @@ struct device *lvmcache_device_from_pvid(struct cmd_context *cmd, const struct i
|
|||||||
if (critical_section() || (scan_done_once && *scan_done_once))
|
if (critical_section() || (scan_done_once && *scan_done_once))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
lvmcache_label_scan(cmd, 2);
|
lvmcache_force_next_label_scan();
|
||||||
|
lvmcache_label_scan(cmd);
|
||||||
if (scan_done_once)
|
if (scan_done_once)
|
||||||
*scan_done_once = 1;
|
*scan_done_once = 1;
|
||||||
|
|
||||||
@@ -1241,6 +1296,15 @@ static int _insert_vginfo(struct lvmcache_vginfo *new_vginfo, const char *vgid,
|
|||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
* vginfo is kept for each VG with the same name.
|
||||||
|
* They are saved with the vginfo->next list.
|
||||||
|
* These checks just decide the ordering of
|
||||||
|
* that list.
|
||||||
|
*
|
||||||
|
* FIXME: it should no longer matter what order
|
||||||
|
* the vginfo's are kept in, so we can probably
|
||||||
|
* remove these comparisons and reordering entirely.
|
||||||
|
*
|
||||||
* If Primary not exported, new exported => keep
|
* If Primary not exported, new exported => keep
|
||||||
* Else Primary exported, new not exported => change
|
* Else Primary exported, new not exported => change
|
||||||
* Else Primary has hostname for this machine => keep
|
* Else Primary has hostname for this machine => keep
|
||||||
@@ -1250,13 +1314,13 @@ static int _insert_vginfo(struct lvmcache_vginfo *new_vginfo, const char *vgid,
|
|||||||
*/
|
*/
|
||||||
if (!(primary_vginfo->status & EXPORTED_VG) &&
|
if (!(primary_vginfo->status & EXPORTED_VG) &&
|
||||||
(vgstatus & EXPORTED_VG))
|
(vgstatus & EXPORTED_VG))
|
||||||
log_warn("WARNING: Duplicate VG name %s: "
|
log_verbose("Cache: Duplicate VG name %s: "
|
||||||
"Existing %s takes precedence over "
|
"Existing %s takes precedence over "
|
||||||
"exported %s", new_vginfo->vgname,
|
"exported %s", new_vginfo->vgname,
|
||||||
uuid_primary, uuid_new);
|
uuid_primary, uuid_new);
|
||||||
else if ((primary_vginfo->status & EXPORTED_VG) &&
|
else if ((primary_vginfo->status & EXPORTED_VG) &&
|
||||||
!(vgstatus & EXPORTED_VG)) {
|
!(vgstatus & EXPORTED_VG)) {
|
||||||
log_warn("WARNING: Duplicate VG name %s: "
|
log_verbose("Cache: Duplicate VG name %s: "
|
||||||
"%s takes precedence over exported %s",
|
"%s takes precedence over exported %s",
|
||||||
new_vginfo->vgname, uuid_new,
|
new_vginfo->vgname, uuid_new,
|
||||||
uuid_primary);
|
uuid_primary);
|
||||||
@@ -1264,12 +1328,12 @@ static int _insert_vginfo(struct lvmcache_vginfo *new_vginfo, const char *vgid,
|
|||||||
} else if (primary_vginfo->creation_host &&
|
} else if (primary_vginfo->creation_host &&
|
||||||
!strcmp(primary_vginfo->creation_host,
|
!strcmp(primary_vginfo->creation_host,
|
||||||
primary_vginfo->fmt->cmd->hostname))
|
primary_vginfo->fmt->cmd->hostname))
|
||||||
log_warn("WARNING: Duplicate VG name %s: "
|
log_verbose("Cache: Duplicate VG name %s: "
|
||||||
"Existing %s (created here) takes precedence "
|
"Existing %s (created here) takes precedence "
|
||||||
"over %s", new_vginfo->vgname, uuid_primary,
|
"over %s", new_vginfo->vgname, uuid_primary,
|
||||||
uuid_new);
|
uuid_new);
|
||||||
else if (!primary_vginfo->creation_host && creation_host) {
|
else if (!primary_vginfo->creation_host && creation_host) {
|
||||||
log_warn("WARNING: Duplicate VG name %s: "
|
log_verbose("Cache: Duplicate VG name %s: "
|
||||||
"%s (with creation_host) takes precedence over %s",
|
"%s (with creation_host) takes precedence over %s",
|
||||||
new_vginfo->vgname, uuid_new,
|
new_vginfo->vgname, uuid_new,
|
||||||
uuid_primary);
|
uuid_primary);
|
||||||
@@ -1277,11 +1341,15 @@ static int _insert_vginfo(struct lvmcache_vginfo *new_vginfo, const char *vgid,
|
|||||||
} else if (creation_host &&
|
} else if (creation_host &&
|
||||||
!strcmp(creation_host,
|
!strcmp(creation_host,
|
||||||
primary_vginfo->fmt->cmd->hostname)) {
|
primary_vginfo->fmt->cmd->hostname)) {
|
||||||
log_warn("WARNING: Duplicate VG name %s: "
|
log_verbose("Cache: Duplicate VG name %s: "
|
||||||
"%s (created here) takes precedence over %s",
|
"%s (created here) takes precedence over %s",
|
||||||
new_vginfo->vgname, uuid_new,
|
new_vginfo->vgname, uuid_new,
|
||||||
uuid_primary);
|
uuid_primary);
|
||||||
use_new = 1;
|
use_new = 1;
|
||||||
|
} else {
|
||||||
|
log_verbose("Cache: Duplicate VG name %s: "
|
||||||
|
"Prefer existing %s vs new %s",
|
||||||
|
new_vginfo->vgname, uuid_primary, uuid_new);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!use_new) {
|
if (!use_new) {
|
||||||
@@ -1448,7 +1516,8 @@ static int _lvmcache_update_vgname(struct lvmcache_info *info,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int _lvmcache_update_vgstatus(struct lvmcache_info *info, uint32_t vgstatus,
|
static int _lvmcache_update_vgstatus(struct lvmcache_info *info, uint32_t vgstatus,
|
||||||
const char *creation_host, const char *lock_type)
|
const char *creation_host, const char *lock_type,
|
||||||
|
const char *system_id)
|
||||||
{
|
{
|
||||||
if (!info || !info->vginfo)
|
if (!info || !info->vginfo)
|
||||||
return 1;
|
return 1;
|
||||||
@@ -1482,20 +1551,41 @@ static int _lvmcache_update_vgstatus(struct lvmcache_info *info, uint32_t vgstat
|
|||||||
set_lock_type:
|
set_lock_type:
|
||||||
|
|
||||||
if (!lock_type)
|
if (!lock_type)
|
||||||
goto out;
|
goto set_system_id;
|
||||||
|
|
||||||
if (info->vginfo->lock_type && !strcmp(lock_type, info->vginfo->lock_type))
|
if (info->vginfo->lock_type && !strcmp(lock_type, info->vginfo->lock_type))
|
||||||
goto out;
|
goto set_system_id;
|
||||||
|
|
||||||
if (info->vginfo->lock_type)
|
if (info->vginfo->lock_type)
|
||||||
dm_free(info->vginfo->lock_type);
|
dm_free(info->vginfo->lock_type);
|
||||||
|
|
||||||
if (!(info->vginfo->lock_type = dm_strdup(lock_type))) {
|
if (!(info->vginfo->lock_type = dm_strdup(lock_type))) {
|
||||||
log_error("cache creation host alloc failed for %s",
|
log_error("cache lock_type alloc failed for %s", lock_type);
|
||||||
lock_type);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log_debug_cache("lvmcache: %s: VG %s: Set lock_type to %s.",
|
||||||
|
dev_name(info->dev), info->vginfo->vgname, lock_type);
|
||||||
|
|
||||||
|
set_system_id:
|
||||||
|
|
||||||
|
if (!system_id)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (info->vginfo->system_id && !strcmp(system_id, info->vginfo->system_id))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (info->vginfo->system_id)
|
||||||
|
dm_free(info->vginfo->system_id);
|
||||||
|
|
||||||
|
if (!(info->vginfo->system_id = dm_strdup(system_id))) {
|
||||||
|
log_error("cache system_id alloc failed for %s", system_id);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_debug_cache("lvmcache: %s: VG %s: Set system_id to %s.",
|
||||||
|
dev_name(info->dev), info->vginfo->vgname, system_id);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -1542,10 +1632,6 @@ int lvmcache_update_vgname_and_id(struct lvmcache_info *info, struct lvmcache_vg
|
|||||||
vgid = vgname;
|
vgid = vgname;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* When using lvmetad, the PV could not have become orphaned. */
|
|
||||||
if (lvmetad_active() && is_orphan_vg(vgname) && info->vginfo)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
/* If PV without mdas is already in a real VG, don't make it orphan */
|
/* If PV without mdas is already in a real VG, don't make it orphan */
|
||||||
if (is_orphan_vg(vgname) && info->vginfo &&
|
if (is_orphan_vg(vgname) && info->vginfo &&
|
||||||
mdas_empty_or_ignored(&info->mdas) &&
|
mdas_empty_or_ignored(&info->mdas) &&
|
||||||
@@ -1565,7 +1651,7 @@ int lvmcache_update_vgname_and_id(struct lvmcache_info *info, struct lvmcache_vg
|
|||||||
if (!_lvmcache_update_vgname(info, vgname, vgid, vgsummary->vgstatus,
|
if (!_lvmcache_update_vgname(info, vgname, vgid, vgsummary->vgstatus,
|
||||||
vgsummary->creation_host, info->fmt) ||
|
vgsummary->creation_host, info->fmt) ||
|
||||||
!_lvmcache_update_vgid(info, info->vginfo, vgid) ||
|
!_lvmcache_update_vgid(info, info->vginfo, vgid) ||
|
||||||
!_lvmcache_update_vgstatus(info, vgsummary->vgstatus, vgsummary->creation_host, vgsummary->lock_type) ||
|
!_lvmcache_update_vgstatus(info, vgsummary->vgstatus, vgsummary->creation_host, vgsummary->lock_type, vgsummary->system_id) ||
|
||||||
!_lvmcache_update_vg_mda_info(info, vgsummary->mda_checksum, vgsummary->mda_size))
|
!_lvmcache_update_vg_mda_info(info, vgsummary->mda_checksum, vgsummary->mda_size))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
@@ -1581,6 +1667,7 @@ int lvmcache_update_vg(struct volume_group *vg, unsigned precommitted)
|
|||||||
.vgname = vg->name,
|
.vgname = vg->name,
|
||||||
.vgstatus = vg->status,
|
.vgstatus = vg->status,
|
||||||
.vgid = vg->id,
|
.vgid = vg->id,
|
||||||
|
.system_id = vg->system_id,
|
||||||
.lock_type = vg->lock_type
|
.lock_type = vg->lock_type
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1788,7 +1875,7 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
|
|||||||
* been chosen during a previous populating of
|
* been chosen during a previous populating of
|
||||||
* lvmcache, so just use the existing preferences.
|
* lvmcache, so just use the existing preferences.
|
||||||
*/
|
*/
|
||||||
log_verbose("Found duplicate PV %s: using existing dev %s",
|
log_warn("Found duplicate PV %s: using existing dev %s",
|
||||||
pvid_s,
|
pvid_s,
|
||||||
dev_name(existing->dev));
|
dev_name(existing->dev));
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -1871,7 +1958,7 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
|
|||||||
* device already exists? Things don't seem to work
|
* device already exists? Things don't seem to work
|
||||||
* if we do that for some reason.
|
* if we do that for some reason.
|
||||||
*/
|
*/
|
||||||
log_verbose("Found same device %s with same pvid %s",
|
log_debug_cache("Found same device %s with same pvid %s",
|
||||||
dev_name(existing->dev), pvid_s);
|
dev_name(existing->dev), pvid_s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2069,7 +2156,8 @@ int lvmcache_populate_pv_fields(struct lvmcache_info *info,
|
|||||||
|
|
||||||
/* Perform full scan (just the first time) and try again */
|
/* Perform full scan (just the first time) and try again */
|
||||||
if (!scan_label_only && !critical_section() && !full_scan_done()) {
|
if (!scan_label_only && !critical_section() && !full_scan_done()) {
|
||||||
lvmcache_label_scan(info->fmt->cmd, 2);
|
lvmcache_force_next_label_scan();
|
||||||
|
lvmcache_label_scan(info->fmt->cmd);
|
||||||
|
|
||||||
if (_get_pv_if_in_vg(info, pv))
|
if (_get_pv_if_in_vg(info, pv))
|
||||||
return 1;
|
return 1;
|
||||||
@@ -2358,3 +2446,41 @@ int lvmcache_contains_lock_type_sanlock(struct cmd_context *cmd)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lvmcache_get_max_name_lengths(struct cmd_context *cmd,
|
||||||
|
unsigned *pv_max_name_len,
|
||||||
|
unsigned *vg_max_name_len)
|
||||||
|
{
|
||||||
|
struct lvmcache_vginfo *vginfo;
|
||||||
|
struct lvmcache_info *info;
|
||||||
|
unsigned len;
|
||||||
|
|
||||||
|
*vg_max_name_len = 0;
|
||||||
|
*pv_max_name_len = 0;
|
||||||
|
|
||||||
|
dm_list_iterate_items(vginfo, &_vginfos) {
|
||||||
|
len = strlen(vginfo->vgname);
|
||||||
|
if (*vg_max_name_len < len)
|
||||||
|
*vg_max_name_len = len;
|
||||||
|
|
||||||
|
dm_list_iterate_items(info, &vginfo->infos) {
|
||||||
|
len = strlen(dev_name(info->dev));
|
||||||
|
if (*pv_max_name_len < len)
|
||||||
|
*pv_max_name_len = len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int lvmcache_vg_is_foreign(struct cmd_context *cmd, const char *vgname, const char *vgid)
|
||||||
|
{
|
||||||
|
struct lvmcache_vginfo *vginfo;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (lvmetad_active())
|
||||||
|
return lvmetad_vg_is_foreign(cmd, vgname, vgid);
|
||||||
|
|
||||||
|
if ((vginfo = lvmcache_vginfo_from_vgid(vgid)))
|
||||||
|
ret = !is_system_id_allowed(cmd, vginfo->system_id);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
22
lib/cache/lvmcache.h
vendored
22
lib/cache/lvmcache.h
vendored
@@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _LVM_CACHE_H
|
#ifndef _LVM_CACHE_H
|
||||||
@@ -55,6 +55,7 @@ struct lvmcache_vgsummary {
|
|||||||
struct id vgid;
|
struct id vgid;
|
||||||
uint64_t vgstatus;
|
uint64_t vgstatus;
|
||||||
char *creation_host;
|
char *creation_host;
|
||||||
|
const char *system_id;
|
||||||
const char *lock_type;
|
const char *lock_type;
|
||||||
uint32_t mda_checksum;
|
uint32_t mda_checksum;
|
||||||
size_t mda_size;
|
size_t mda_size;
|
||||||
@@ -65,9 +66,14 @@ void lvmcache_allow_reads_with_lvmetad(void);
|
|||||||
|
|
||||||
void lvmcache_destroy(struct cmd_context *cmd, int retain_orphans, int reset);
|
void lvmcache_destroy(struct cmd_context *cmd, int retain_orphans, int reset);
|
||||||
|
|
||||||
/* Set full_scan to 1 to reread every filtered device label or
|
/*
|
||||||
* 2 to rescan /dev for new devices */
|
* lvmcache_label_scan() will scan labels the first time it's
|
||||||
int lvmcache_label_scan(struct cmd_context *cmd, int full_scan);
|
* called, but not on subsequent calls, unless
|
||||||
|
* lvmcache_force_next_label_scan() is called first
|
||||||
|
* to force the next lvmcache_label_scan() to scan again.
|
||||||
|
*/
|
||||||
|
void lvmcache_force_next_label_scan(void);
|
||||||
|
int lvmcache_label_scan(struct cmd_context *cmd);
|
||||||
|
|
||||||
/* Add/delete a device */
|
/* Add/delete a device */
|
||||||
struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
|
struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
|
||||||
@@ -98,6 +104,7 @@ struct lvmcache_vginfo *lvmcache_vginfo_from_vgname(const char *vgname,
|
|||||||
struct lvmcache_vginfo *lvmcache_vginfo_from_vgid(const char *vgid);
|
struct lvmcache_vginfo *lvmcache_vginfo_from_vgid(const char *vgid);
|
||||||
struct lvmcache_info *lvmcache_info_from_pvid(const char *pvid, int valid_only);
|
struct lvmcache_info *lvmcache_info_from_pvid(const char *pvid, int valid_only);
|
||||||
const char *lvmcache_vgname_from_vgid(struct dm_pool *mem, const char *vgid);
|
const char *lvmcache_vgname_from_vgid(struct dm_pool *mem, const char *vgid);
|
||||||
|
const char *lvmcache_vgid_from_vgname(struct cmd_context *cmd, const char *vgname);
|
||||||
struct device *lvmcache_device_from_pvid(struct cmd_context *cmd, const struct id *pvid,
|
struct device *lvmcache_device_from_pvid(struct cmd_context *cmd, const struct id *pvid,
|
||||||
unsigned *scan_done_once, uint64_t *label_sector);
|
unsigned *scan_done_once, uint64_t *label_sector);
|
||||||
const char *lvmcache_pvid_from_devname(struct cmd_context *cmd,
|
const char *lvmcache_pvid_from_devname(struct cmd_context *cmd,
|
||||||
@@ -190,4 +197,11 @@ void lvmcache_set_preferred_duplicates(const char *vgid);
|
|||||||
|
|
||||||
int lvmcache_contains_lock_type_sanlock(struct cmd_context *cmd);
|
int lvmcache_contains_lock_type_sanlock(struct cmd_context *cmd);
|
||||||
|
|
||||||
|
void lvmcache_get_max_name_lengths(struct cmd_context *cmd,
|
||||||
|
unsigned *pv_max_name_len, unsigned *vg_max_name_len);
|
||||||
|
|
||||||
|
int lvmcache_vg_is_foreign(struct cmd_context *cmd, const char *vgname, const char *vgid);
|
||||||
|
|
||||||
|
void lvmcache_lock_ordering(int enable);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
243
lib/cache/lvmetad.c
vendored
243
lib/cache/lvmetad.c
vendored
@@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "lib.h"
|
#include "lib.h"
|
||||||
@@ -37,6 +37,70 @@ static struct cmd_context *_lvmetad_cmd = NULL;
|
|||||||
|
|
||||||
static struct volume_group *lvmetad_pvscan_vg(struct cmd_context *cmd, struct volume_group *vg);
|
static struct volume_group *lvmetad_pvscan_vg(struct cmd_context *cmd, struct volume_group *vg);
|
||||||
|
|
||||||
|
static int _log_debug_inequality(const char *name, struct dm_config_node *a, struct dm_config_node *b)
|
||||||
|
{
|
||||||
|
int result = 0;
|
||||||
|
int final_result = 0;
|
||||||
|
|
||||||
|
if (a->v && b->v) {
|
||||||
|
result = compare_value(a->v, b->v);
|
||||||
|
if (result) {
|
||||||
|
struct dm_config_value *av = a->v;
|
||||||
|
struct dm_config_value *bv = b->v;
|
||||||
|
|
||||||
|
if (!strcmp(a->key, b->key)) {
|
||||||
|
if (a->v->type == DM_CFG_STRING && b->v->type == DM_CFG_STRING)
|
||||||
|
log_debug_lvmetad("VG %s metadata inequality at %s / %s: %s / %s",
|
||||||
|
name, a->key, b->key, av->v.str, bv->v.str);
|
||||||
|
else if (a->v->type == DM_CFG_INT && b->v->type == DM_CFG_INT)
|
||||||
|
log_debug_lvmetad("VG %s metadata inequality at %s / %s: " FMTi64 " / " FMTi64,
|
||||||
|
name, a->key, b->key, av->v.i, bv->v.i);
|
||||||
|
else
|
||||||
|
log_debug_lvmetad("VG %s metadata inequality at %s / %s: type %d / type %d",
|
||||||
|
name, a->key, b->key, av->type, bv->type);
|
||||||
|
} else {
|
||||||
|
log_debug_lvmetad("VG %s metadata inequality at %s / %s", name, a->key, b->key);
|
||||||
|
}
|
||||||
|
final_result = result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a->v && !b->v) {
|
||||||
|
log_debug_lvmetad("VG %s metadata inequality at %s / %s", name, a->key, b->key);
|
||||||
|
final_result = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!a->v && b->v) {
|
||||||
|
log_debug_lvmetad("VG %s metadata inequality at %s / %s", name, a->key, b->key);
|
||||||
|
final_result = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a->child && b->child) {
|
||||||
|
result = _log_debug_inequality(name, a->child, b->child);
|
||||||
|
if (result)
|
||||||
|
final_result = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a->sib && b->sib) {
|
||||||
|
result = _log_debug_inequality(name, a->sib, b->sib);
|
||||||
|
if (result)
|
||||||
|
final_result = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (a->sib && !b->sib) {
|
||||||
|
log_debug_lvmetad("VG %s metadata inequality at %s / %s", name, a->key, b->key);
|
||||||
|
final_result = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!a->sib && b->sib) {
|
||||||
|
log_debug_lvmetad("VG %s metadata inequality at %s / %s", name, a->key, b->key);
|
||||||
|
final_result = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return final_result;
|
||||||
|
}
|
||||||
|
|
||||||
void lvmetad_disconnect(void)
|
void lvmetad_disconnect(void)
|
||||||
{
|
{
|
||||||
if (_lvmetad_connected)
|
if (_lvmetad_connected)
|
||||||
@@ -252,6 +316,15 @@ static int _lvmetad_handle_reply(daemon_reply reply, const char *action, const c
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Multiple VGs with the same name were found. */
|
||||||
|
if (found && !strcmp(daemon_reply_str(reply, "response", ""), "multiple")) {
|
||||||
|
log_very_verbose("Request to %s %s%sin lvmetad found multiple matching objects.",
|
||||||
|
action, object, *object ? " " : "");
|
||||||
|
if (found)
|
||||||
|
*found = 2;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
log_error("Request to %s %s%sin lvmetad gave response %s. Reason: %s",
|
log_error("Request to %s %s%sin lvmetad gave response %s. Reason: %s",
|
||||||
action, object, *object ? " " : "",
|
action, object, *object ? " " : "",
|
||||||
daemon_reply_str(reply, "response", "<missing>"),
|
daemon_reply_str(reply, "response", "<missing>"),
|
||||||
@@ -375,6 +448,14 @@ static int _pv_populate_lvmcache(struct cmd_context *cmd,
|
|||||||
|
|
||||||
while (alt_device) {
|
while (alt_device) {
|
||||||
dev_alternate = dev_cache_get_by_devt(alt_device->v.i, cmd->filter);
|
dev_alternate = dev_cache_get_by_devt(alt_device->v.i, cmd->filter);
|
||||||
|
|
||||||
|
log_verbose("PV on device %s (%d:%d %d) is also on device %s (%d:%d %d) %s",
|
||||||
|
dev_name(dev),
|
||||||
|
(int)MAJOR(devt), (int)MINOR(devt), (int)devt,
|
||||||
|
dev_alternate ? dev_name(dev_alternate) : "unknown",
|
||||||
|
(int)MAJOR(alt_device->v.i), (int)MINOR(alt_device->v.i), (int)alt_device->v.i,
|
||||||
|
pvid_txt);
|
||||||
|
|
||||||
if (dev_alternate) {
|
if (dev_alternate) {
|
||||||
if ((info_alternate = lvmcache_add(fmt->labeller, (const char *)&pvid, dev_alternate,
|
if ((info_alternate = lvmcache_add(fmt->labeller, (const char *)&pvid, dev_alternate,
|
||||||
vgname, (const char *)&vgid, 0))) {
|
vgname, (const char *)&vgid, 0))) {
|
||||||
@@ -382,9 +463,6 @@ static int _pv_populate_lvmcache(struct cmd_context *cmd,
|
|||||||
info = info_alternate;
|
info = info_alternate;
|
||||||
lvmcache_get_label(info)->dev = dev_alternate;
|
lvmcache_get_label(info)->dev = dev_alternate;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
log_warn("Duplicate of PV %s dev %s exists on unknown device %"PRId64 ":%" PRId64,
|
|
||||||
pvid_txt, dev_name(dev), MAJOR(alt_device->v.i), MINOR(alt_device->v.i));
|
|
||||||
}
|
}
|
||||||
alt_device = alt_device->next;
|
alt_device = alt_device->next;
|
||||||
}
|
}
|
||||||
@@ -434,6 +512,7 @@ struct volume_group *lvmetad_vg_lookup(struct cmd_context *cmd, const char *vgna
|
|||||||
struct format_type *fmt;
|
struct format_type *fmt;
|
||||||
struct dm_config_node *pvcn;
|
struct dm_config_node *pvcn;
|
||||||
struct pv_list *pvl;
|
struct pv_list *pvl;
|
||||||
|
int rescan = 0;
|
||||||
|
|
||||||
if (!lvmetad_active())
|
if (!lvmetad_active())
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -441,22 +520,39 @@ struct volume_group *lvmetad_vg_lookup(struct cmd_context *cmd, const char *vgna
|
|||||||
if (vgid) {
|
if (vgid) {
|
||||||
if (!id_write_format((const struct id*)vgid, uuid, sizeof(uuid)))
|
if (!id_write_format((const struct id*)vgid, uuid, sizeof(uuid)))
|
||||||
return_NULL;
|
return_NULL;
|
||||||
log_debug_lvmetad("Asking lvmetad for VG %s (%s)", uuid, vgname ? : "name unknown");
|
}
|
||||||
|
|
||||||
|
if (vgid && vgname) {
|
||||||
|
log_debug_lvmetad("Asking lvmetad for VG %s %s", uuid, vgname);
|
||||||
|
reply = _lvmetad_send("vg_lookup",
|
||||||
|
"uuid = %s", uuid,
|
||||||
|
"name = %s", vgname,
|
||||||
|
NULL);
|
||||||
|
diag_name = uuid;
|
||||||
|
|
||||||
|
} else if (vgid) {
|
||||||
|
log_debug_lvmetad("Asking lvmetad for VG vgid %s", uuid);
|
||||||
reply = _lvmetad_send("vg_lookup", "uuid = %s", uuid, NULL);
|
reply = _lvmetad_send("vg_lookup", "uuid = %s", uuid, NULL);
|
||||||
diag_name = uuid;
|
diag_name = uuid;
|
||||||
} else {
|
|
||||||
if (!vgname) {
|
} else if (vgname) {
|
||||||
log_error(INTERNAL_ERROR "VG name required (VGID not available)");
|
|
||||||
reply = _lvmetad_send("vg_lookup", "name = %s", "MISSING", NULL);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
log_debug_lvmetad("Asking lvmetad for VG %s", vgname);
|
log_debug_lvmetad("Asking lvmetad for VG %s", vgname);
|
||||||
reply = _lvmetad_send("vg_lookup", "name = %s", vgname, NULL);
|
reply = _lvmetad_send("vg_lookup", "name = %s", vgname, NULL);
|
||||||
diag_name = vgname;
|
diag_name = vgname;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
log_error(INTERNAL_ERROR "VG name required (VGID not available)");
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_lvmetad_handle_reply(reply, "lookup VG", diag_name, &found) && found) {
|
if (_lvmetad_handle_reply(reply, "lookup VG", diag_name, &found) && found) {
|
||||||
|
|
||||||
|
if ((found == 2) && vgname) {
|
||||||
|
log_error("Multiple VGs found with the same name: %s.", vgname);
|
||||||
|
log_error("See the --select option with VG UUID (vg_uuid).");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(top = dm_config_find_node(reply.cft->root, "metadata"))) {
|
if (!(top = dm_config_find_node(reply.cft->root, "metadata"))) {
|
||||||
log_error(INTERNAL_ERROR "metadata config node not found.");
|
log_error(INTERNAL_ERROR "metadata config node not found.");
|
||||||
goto out;
|
goto out;
|
||||||
@@ -492,15 +588,55 @@ struct volume_group *lvmetad_vg_lookup(struct cmd_context *cmd, const char *vgna
|
|||||||
if (!(vg = import_vg_from_lvmetad_config_tree(reply.cft, fid)))
|
if (!(vg = import_vg_from_lvmetad_config_tree(reply.cft, fid)))
|
||||||
goto_out;
|
goto_out;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read the VG from disk, ignoring the lvmetad copy in these
|
||||||
|
* cases:
|
||||||
|
*
|
||||||
|
* 1. The host is not using lvmlockd, but is reading lockd VGs
|
||||||
|
* using the --shared option. The shared option is meant to
|
||||||
|
* let hosts not running lvmlockd look at lockd VGs, like the
|
||||||
|
* foreign option allows hosts to look at foreign VGs. When
|
||||||
|
* --foreign is used, the code forces a rescan since the local
|
||||||
|
* lvmetad cache of foreign VGs is likely stale. Similarly,
|
||||||
|
* for --shared, have the code reading the shared VGs below
|
||||||
|
* not use the cached copy from lvmetad but to rescan the VG.
|
||||||
|
*
|
||||||
|
* 2. The host failed to acquire the VG lock from lvmlockd for
|
||||||
|
* the lockd VG. In this case, the usual mechanisms for
|
||||||
|
* updating the lvmetad copy of the VG have been missed. Since
|
||||||
|
* we don't know if the cached copy is valid, assume it's not.
|
||||||
|
*
|
||||||
|
* 3. lvmetad has returned the "vg_invalid" flag, which is the
|
||||||
|
* usual mechanism used by lvmlockd/lvmetad to cause a host to
|
||||||
|
* reread a VG from disk that has been modified from another
|
||||||
|
* host.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (is_lockd_type(vg->lock_type) && cmd->include_shared_vgs) {
|
||||||
|
log_debug_lvmetad("Rescan VG %s because including shared", vgname);
|
||||||
|
rescan = 1;
|
||||||
|
} else if (is_lockd_type(vg->lock_type) && cmd->lockd_vg_rescan) {
|
||||||
|
log_debug_lvmetad("Rescan VG %s because no lvmlockd lock is held", vgname);
|
||||||
|
rescan = 1;
|
||||||
|
} else if (dm_config_find_node(reply.cft->root, "vg_invalid")) {
|
||||||
|
log_debug_lvmetad("Rescan VG %s because lvmetad returned invalid", vgname);
|
||||||
|
rescan = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* locking may have detected a newer vg version and
|
* locking may have detected a newer vg version and
|
||||||
* invalidated the cached vg.
|
* invalidated the cached vg.
|
||||||
*/
|
*/
|
||||||
if (dm_config_find_node(reply.cft->root, "vg_invalid")) {
|
if (rescan) {
|
||||||
log_debug_lvmetad("Update invalid lvmetad cache for VG %s", vgname);
|
log_debug_lvmetad("Update invalid lvmetad cache for VG %s", vgname);
|
||||||
vg2 = lvmetad_pvscan_vg(cmd, vg);
|
vg2 = lvmetad_pvscan_vg(cmd, vg);
|
||||||
release_vg(vg);
|
release_vg(vg);
|
||||||
vg = vg2;
|
vg = vg2;
|
||||||
|
if (!vg) {
|
||||||
|
log_debug_lvmetad("VG %s from lvmetad not found during rescan.", vgname);
|
||||||
|
fid = NULL;
|
||||||
|
goto out;
|
||||||
|
} else
|
||||||
fid = vg->fid;
|
fid = vg->fid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1062,16 +1198,17 @@ struct _lvmetad_pvscan_baton {
|
|||||||
static int _lvmetad_pvscan_single(struct metadata_area *mda, void *baton)
|
static int _lvmetad_pvscan_single(struct metadata_area *mda, void *baton)
|
||||||
{
|
{
|
||||||
struct _lvmetad_pvscan_baton *b = baton;
|
struct _lvmetad_pvscan_baton *b = baton;
|
||||||
struct volume_group *this;
|
struct volume_group *vg;
|
||||||
|
|
||||||
if (!(this = mda_is_ignored(mda) ? NULL : mda->ops->vg_read(b->fid, "", mda, NULL, NULL, 1)))
|
if (mda_is_ignored(mda) ||
|
||||||
|
!(vg = mda->ops->vg_read(b->fid, "", mda, NULL, NULL, 1)))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/* FIXME Also ensure contents match etc. */
|
/* FIXME Also ensure contents match etc. */
|
||||||
if (!b->vg || this->seqno > b->vg->seqno)
|
if (!b->vg || vg->seqno > b->vg->seqno)
|
||||||
b->vg = this;
|
b->vg = vg;
|
||||||
else if (b->vg)
|
else if (b->vg)
|
||||||
release_vg(this);
|
release_vg(vg);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -1081,6 +1218,8 @@ static int _lvmetad_pvscan_single(struct metadata_area *mda, void *baton)
|
|||||||
* due to something like an lvcreate from another host.
|
* due to something like an lvcreate from another host.
|
||||||
* This is limited to changes that only affect the vg (not global state like
|
* This is limited to changes that only affect the vg (not global state like
|
||||||
* orphan PVs), so we only need to reread mdas on the vg's existing pvs.
|
* orphan PVs), so we only need to reread mdas on the vg's existing pvs.
|
||||||
|
* But, a previous PV in the VG may have been removed since we last read
|
||||||
|
* the VG, and that PV may have been reused for another VG.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static struct volume_group *lvmetad_pvscan_vg(struct cmd_context *cmd, struct volume_group *vg)
|
static struct volume_group *lvmetad_pvscan_vg(struct cmd_context *cmd, struct volume_group *vg)
|
||||||
@@ -1093,6 +1232,7 @@ static struct volume_group *lvmetad_pvscan_vg(struct cmd_context *cmd, struct vo
|
|||||||
struct format_instance *fid;
|
struct format_instance *fid;
|
||||||
struct format_instance_ctx fic = { .type = 0 };
|
struct format_instance_ctx fic = { .type = 0 };
|
||||||
struct _lvmetad_pvscan_baton baton;
|
struct _lvmetad_pvscan_baton baton;
|
||||||
|
struct device *save_dev = NULL;
|
||||||
|
|
||||||
dm_list_iterate_items(pvl, &vg->pvs) {
|
dm_list_iterate_items(pvl, &vg->pvs) {
|
||||||
/* missing pv */
|
/* missing pv */
|
||||||
@@ -1119,9 +1259,25 @@ static struct volume_group *lvmetad_pvscan_vg(struct cmd_context *cmd, struct vo
|
|||||||
|
|
||||||
lvmcache_foreach_mda(info, _lvmetad_pvscan_single, &baton);
|
lvmcache_foreach_mda(info, _lvmetad_pvscan_single, &baton);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The PV may have been removed from the VG by another host
|
||||||
|
* since we last read the VG.
|
||||||
|
*/
|
||||||
if (!baton.vg) {
|
if (!baton.vg) {
|
||||||
|
log_debug_lvmetad("Did not find VG %s in scan of PV %s", vg->name, dev_name(pvl->pv->dev));
|
||||||
lvmcache_fmt(info)->ops->destroy_instance(baton.fid);
|
lvmcache_fmt(info)->ops->destroy_instance(baton.fid);
|
||||||
return NULL;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The PV may have been removed from the VG and used for a
|
||||||
|
* different VG since we last read the VG.
|
||||||
|
*/
|
||||||
|
if (strcmp(baton.vg->name, vg->name)) {
|
||||||
|
log_debug_lvmetad("Did not find VG %s in scan of PV %s which is now VG %s",
|
||||||
|
vg->name, dev_name(pvl->pv->dev), baton.vg->name);
|
||||||
|
release_vg(baton.vg);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(vgmeta = export_vg_to_config_tree(baton.vg))) {
|
if (!(vgmeta = export_vg_to_config_tree(baton.vg))) {
|
||||||
@@ -1132,9 +1288,12 @@ static struct volume_group *lvmetad_pvscan_vg(struct cmd_context *cmd, struct vo
|
|||||||
|
|
||||||
if (!vgmeta_ret) {
|
if (!vgmeta_ret) {
|
||||||
vgmeta_ret = vgmeta;
|
vgmeta_ret = vgmeta;
|
||||||
|
save_dev = pvl->pv->dev;
|
||||||
} else {
|
} else {
|
||||||
if (!compare_config(vgmeta_ret->root, vgmeta->root)) {
|
if (compare_config(vgmeta_ret->root, vgmeta->root)) {
|
||||||
log_error("VG metadata comparison failed");
|
log_error("VG %s metadata comparison failed for device %s vs %s",
|
||||||
|
vg->name, dev_name(pvl->pv->dev), save_dev ? dev_name(save_dev) : "none");
|
||||||
|
_log_debug_inequality(vg->name, vgmeta_ret->root, vgmeta->root);
|
||||||
dm_config_destroy(vgmeta);
|
dm_config_destroy(vgmeta);
|
||||||
dm_config_destroy(vgmeta_ret);
|
dm_config_destroy(vgmeta_ret);
|
||||||
release_vg(baton.vg);
|
release_vg(baton.vg);
|
||||||
@@ -1178,6 +1337,7 @@ int lvmetad_pvscan_single(struct cmd_context *cmd, struct device *dev,
|
|||||||
struct _lvmetad_pvscan_baton baton;
|
struct _lvmetad_pvscan_baton baton;
|
||||||
/* Create a dummy instance. */
|
/* Create a dummy instance. */
|
||||||
struct format_instance_ctx fic = { .type = 0 };
|
struct format_instance_ctx fic = { .type = 0 };
|
||||||
|
struct metadata_area *mda;
|
||||||
|
|
||||||
if (!lvmetad_active()) {
|
if (!lvmetad_active()) {
|
||||||
log_error("Cannot proceed since lvmetad is not active.");
|
log_error("Cannot proceed since lvmetad is not active.");
|
||||||
@@ -1204,7 +1364,7 @@ int lvmetad_pvscan_single(struct cmd_context *cmd, struct device *dev,
|
|||||||
log_warn("WARNING: Ignoring obsolete format of metadata (%s) on device %s when using lvmetad",
|
log_warn("WARNING: Ignoring obsolete format of metadata (%s) on device %s when using lvmetad",
|
||||||
baton.fid->fmt->name, dev_name(dev));
|
baton.fid->fmt->name, dev_name(dev));
|
||||||
else
|
else
|
||||||
log_error("WARNING: Ignoring obsolete format of metadata (%s) on device %s when using lvmetad",
|
log_error("Ignoring obsolete format of metadata (%s) on device %s when using lvmetad.",
|
||||||
baton.fid->fmt->name, dev_name(dev));
|
baton.fid->fmt->name, dev_name(dev));
|
||||||
lvmcache_fmt(info)->ops->destroy_instance(baton.fid);
|
lvmcache_fmt(info)->ops->destroy_instance(baton.fid);
|
||||||
|
|
||||||
@@ -1221,8 +1381,12 @@ int lvmetad_pvscan_single(struct cmd_context *cmd, struct device *dev,
|
|||||||
* Note that the single_device parameter also gets ignored and this code
|
* Note that the single_device parameter also gets ignored and this code
|
||||||
* can scan further devices.
|
* can scan further devices.
|
||||||
*/
|
*/
|
||||||
if (!baton.vg && !(baton.fid->fmt->features & FMT_MDAS))
|
if (!baton.vg && !(baton.fid->fmt->features & FMT_MDAS)) {
|
||||||
baton.vg = ((struct metadata_area *) dm_list_first(&baton.fid->metadata_areas_in_use))->ops->vg_read(baton.fid, lvmcache_vgname_from_info(info), NULL, NULL, NULL, 1);
|
/* This code seems to be unreachable */
|
||||||
|
if ((mda = (struct metadata_area *)dm_list_first(&baton.fid->metadata_areas_in_use)))
|
||||||
|
baton.vg = mda->ops->vg_read(baton.fid, lvmcache_vgname_from_info(info),
|
||||||
|
mda, NULL, NULL, 1);
|
||||||
|
}
|
||||||
|
|
||||||
if (!baton.vg)
|
if (!baton.vg)
|
||||||
lvmcache_fmt(info)->ops->destroy_instance(baton.fid);
|
lvmcache_fmt(info)->ops->destroy_instance(baton.fid);
|
||||||
@@ -1556,7 +1720,7 @@ void lvmetad_validate_global_cache(struct cmd_context *cmd, int force)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!lvmetad_used())
|
if (!lvmetad_active())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
log_debug_lvmetad("Validating global lvmetad cache");
|
log_debug_lvmetad("Validating global lvmetad cache");
|
||||||
@@ -1598,7 +1762,8 @@ void lvmetad_validate_global_cache(struct cmd_context *cmd, int force)
|
|||||||
* Update the local lvmetad cache so it correctly reflects any
|
* Update the local lvmetad cache so it correctly reflects any
|
||||||
* changes made on remote hosts.
|
* changes made on remote hosts.
|
||||||
*/
|
*/
|
||||||
lvmetad_pvscan_all_devs(cmd, NULL);
|
if (!lvmetad_pvscan_all_devs(cmd, NULL))
|
||||||
|
stack; /* FIXME: Anything more on this error path ? */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clear the global_invalid flag in lvmetad.
|
* Clear the global_invalid flag in lvmetad.
|
||||||
@@ -1608,7 +1773,7 @@ void lvmetad_validate_global_cache(struct cmd_context *cmd, int force)
|
|||||||
*/
|
*/
|
||||||
reply = daemon_send_simple(_lvmetad, "set_global_info",
|
reply = daemon_send_simple(_lvmetad, "set_global_info",
|
||||||
"token = %s", "skip",
|
"token = %s", "skip",
|
||||||
"global_invalid = %d", 0,
|
"global_invalid = " FMTd64, INT64_C(0),
|
||||||
NULL);
|
NULL);
|
||||||
if (reply.error)
|
if (reply.error)
|
||||||
log_error("lvmetad_validate_global_cache set_global_info error %d", reply.error);
|
log_error("lvmetad_validate_global_cache set_global_info error %d", reply.error);
|
||||||
@@ -1643,3 +1808,29 @@ void lvmetad_validate_global_cache(struct cmd_context *cmd, int force)
|
|||||||
_update_changed_pvs_in_udev(cmd, &pvc_before, &pvc_after);
|
_update_changed_pvs_in_udev(cmd, &pvc_before, &pvc_after);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int lvmetad_vg_is_foreign(struct cmd_context *cmd, const char *vgname, const char *vgid)
|
||||||
|
{
|
||||||
|
daemon_reply reply;
|
||||||
|
struct dm_config_node *top;
|
||||||
|
const char *system_id = NULL;
|
||||||
|
char uuid[64];
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!id_write_format((const struct id*)vgid, uuid, sizeof(uuid)))
|
||||||
|
return_0;
|
||||||
|
|
||||||
|
reply = _lvmetad_send("vg_lookup",
|
||||||
|
"uuid = %s", uuid,
|
||||||
|
"name = %s", vgname,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if ((top = dm_config_find_node(reply.cft->root, "metadata")))
|
||||||
|
system_id = dm_config_find_str(top, "metadata/system_id", NULL);
|
||||||
|
|
||||||
|
ret = !is_system_id_allowed(cmd, system_id);
|
||||||
|
|
||||||
|
daemon_reply_destroy(reply);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
5
lib/cache/lvmetad.h
vendored
5
lib/cache/lvmetad.h
vendored
@@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* 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,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _LVM_METAD_H
|
#ifndef _LVM_METAD_H
|
||||||
@@ -169,6 +169,8 @@ int lvmetad_pvscan_foreign_vgs(struct cmd_context *cmd, activation_handler handl
|
|||||||
int lvmetad_vg_clear_outdated_pvs(struct volume_group *vg);
|
int lvmetad_vg_clear_outdated_pvs(struct volume_group *vg);
|
||||||
void lvmetad_validate_global_cache(struct cmd_context *cmd, int force);
|
void lvmetad_validate_global_cache(struct cmd_context *cmd, int force);
|
||||||
|
|
||||||
|
int lvmetad_vg_is_foreign(struct cmd_context *cmd, const char *vgname, const char *vgid);
|
||||||
|
|
||||||
# else /* LVMETAD_SUPPORT */
|
# else /* LVMETAD_SUPPORT */
|
||||||
|
|
||||||
# define lvmetad_init(cmd) do { } while (0)
|
# define lvmetad_init(cmd) do { } while (0)
|
||||||
@@ -197,6 +199,7 @@ void lvmetad_validate_global_cache(struct cmd_context *cmd, int force);
|
|||||||
# define lvmetad_pvscan_foreign_vgs(cmd, handler) (0)
|
# define lvmetad_pvscan_foreign_vgs(cmd, handler) (0)
|
||||||
# define lvmetad_vg_clear_outdated_pvs(vg) (1)
|
# define lvmetad_vg_clear_outdated_pvs(vg) (1)
|
||||||
# define lvmetad_validate_global_cache(cmd, force) do { } while (0)
|
# define lvmetad_validate_global_cache(cmd, force) do { } while (0)
|
||||||
|
# define lvmetad_vg_is_foreign(cmd, vgname, vgid) (0)
|
||||||
|
|
||||||
# endif /* LVMETAD_SUPPORT */
|
# endif /* LVMETAD_SUPPORT */
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
#
|
#
|
||||||
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
srcdir = @srcdir@
|
srcdir = @srcdir@
|
||||||
top_srcdir = @top_srcdir@
|
top_srcdir = @top_srcdir@
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user