mirror of
git://sourceware.org/git/lvm2.git
synced 2026-02-01 00:32:46 +03:00
Compare commits
524 Commits
dm_v1_02_2
...
v2_02_43
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9fbe96fd7c | ||
|
|
98cd400443 | ||
|
|
873e699f6d | ||
|
|
9a8f6c824f | ||
|
|
a98888ad07 | ||
|
|
db98500b72 | ||
|
|
3feee09cfe | ||
|
|
4a1cd0d391 | ||
|
|
edb5071d3b | ||
|
|
e9509aa5e6 | ||
|
|
5e6ca1b72d | ||
|
|
543bf2ffbd | ||
|
|
15a7a4c38b | ||
|
|
640d07bf35 | ||
|
|
e5ecc2b942 | ||
|
|
cfd8fe40f4 | ||
|
|
abba6e0642 | ||
|
|
ec94fb89a2 | ||
|
|
bb167efa7b | ||
|
|
2a550ef96d | ||
|
|
03ed7d73fc | ||
|
|
446852db3b | ||
|
|
7c90b57e87 | ||
|
|
6339e2588b | ||
|
|
af6687405b | ||
|
|
a2bfad1c29 | ||
|
|
645aa55abc | ||
|
|
05329c885a | ||
|
|
b3fed93a74 | ||
|
|
2c6fad0ea7 | ||
|
|
57854c2231 | ||
|
|
a8cf4293e0 | ||
|
|
ba70dce803 | ||
|
|
5b4c3ace56 | ||
|
|
2ade7a15e2 | ||
|
|
e83f71d678 | ||
|
|
412c91cb6b | ||
|
|
aa44167319 | ||
|
|
dd5700e8b3 | ||
|
|
ef7fc430d7 | ||
|
|
f1bcb6c634 | ||
|
|
4a4eb17d08 | ||
|
|
8afc267c68 | ||
|
|
6457ab31b6 | ||
|
|
306dfa2043 | ||
|
|
424bdade0b | ||
|
|
10857e3321 | ||
|
|
85a4e47879 | ||
|
|
759e49f025 | ||
|
|
43924e31b8 | ||
|
|
3b34fcf59f | ||
|
|
ba7253eaf7 | ||
|
|
be23682a30 | ||
|
|
3a5dce4c92 | ||
|
|
22d7e60d0e | ||
|
|
5752156c9e | ||
|
|
a30215a530 | ||
|
|
f9c8c1b964 | ||
|
|
5650f67ef5 | ||
|
|
5ec25dfb94 | ||
|
|
ef16682725 | ||
|
|
883486cc67 | ||
|
|
f367f9b747 | ||
|
|
a3d987fa73 | ||
|
|
2d48685673 | ||
|
|
9b21ace1e9 | ||
|
|
be2c03fa96 | ||
|
|
f5585e9252 | ||
|
|
4d534dd7e4 | ||
|
|
c8584e1cce | ||
|
|
84a1de464c | ||
|
|
3966f3d319 | ||
|
|
e6166cf711 | ||
|
|
2285712834 | ||
|
|
53cb6128e8 | ||
|
|
8c317baf19 | ||
|
|
8cac933c71 | ||
|
|
03e61a4bf8 | ||
|
|
71446a76b2 | ||
|
|
28db8d6c7c | ||
|
|
786e33d7d5 | ||
|
|
b140d6c50e | ||
|
|
64a95abdee | ||
|
|
57f926be17 | ||
|
|
4933b67959 | ||
|
|
370b4f1b9e | ||
|
|
f3b7baa84e | ||
|
|
eafdb2c807 | ||
|
|
a91fa821ab | ||
|
|
37ef162cda | ||
|
|
770928acfc | ||
|
|
d0f3570219 | ||
|
|
3d07c2605f | ||
|
|
c350798528 | ||
|
|
6bc3cc0bec | ||
|
|
2e3e5fcc81 | ||
|
|
dfdb10f6de | ||
|
|
5cbe5909eb | ||
|
|
04d52b450b | ||
|
|
a586a89547 | ||
|
|
1905eacf15 | ||
|
|
858ec0d740 | ||
|
|
76cfd406ca | ||
|
|
9dbaad859d | ||
|
|
95d43e17b3 | ||
|
|
09a2dff8de | ||
|
|
57208f879a | ||
|
|
149638431d | ||
|
|
30d2940c67 | ||
|
|
5ee86fc5d0 | ||
|
|
a03d0e2c3f | ||
|
|
8bd367d58d | ||
|
|
bc633e03aa | ||
|
|
797d0f1ef1 | ||
|
|
1be3e86aa0 | ||
|
|
e56dd38021 | ||
|
|
410904bef1 | ||
|
|
026cc120e7 | ||
|
|
ef2fda05cf | ||
|
|
92277e3ae2 | ||
|
|
fbc34d70b0 | ||
|
|
91dcddbdf7 | ||
|
|
874f42ad6c | ||
|
|
1989ef4ebc | ||
|
|
4f4c72c065 | ||
|
|
666cc72661 | ||
|
|
4524e8f5c9 | ||
|
|
bd07a29886 | ||
|
|
a0d865492e | ||
|
|
de27790de8 | ||
|
|
9c910b7be2 | ||
|
|
7f23ab94e2 | ||
|
|
77dc036c8f | ||
|
|
aa6e8d82ce | ||
|
|
3010285bb3 | ||
|
|
aaad3252f8 | ||
|
|
9065f534d8 | ||
|
|
52361c94e5 | ||
|
|
798be60fef | ||
|
|
6294154b15 | ||
|
|
6594fe077d | ||
|
|
582706cde6 | ||
|
|
6537cbdc17 | ||
|
|
53959459bb | ||
|
|
22d6121099 | ||
|
|
48d7f6f2f4 | ||
|
|
9fd4ddc490 | ||
|
|
a4d2fddbb2 | ||
|
|
c54a3f2721 | ||
|
|
04c0dba697 | ||
|
|
5406e3b7c5 | ||
|
|
6b624b7d00 | ||
|
|
2d364d4d80 | ||
|
|
1f27bf3774 | ||
|
|
d30a2653b5 | ||
|
|
3086822cd2 | ||
|
|
2c08336490 | ||
|
|
5936ac58c2 | ||
|
|
ded77e3f5c | ||
|
|
8a29df0a6c | ||
|
|
9db22babaf | ||
|
|
c318c5ed61 | ||
|
|
61243c65cd | ||
|
|
4a5d5cb462 | ||
|
|
cbf1447ebd | ||
|
|
30104441bf | ||
|
|
b4a70804f0 | ||
|
|
74f6707bde | ||
|
|
223eb8c84d | ||
|
|
107d000606 | ||
|
|
43e05607af | ||
|
|
55793452d5 | ||
|
|
686ba37255 | ||
|
|
03ed19dad5 | ||
|
|
ad2b6e5de1 | ||
|
|
767676d6ff | ||
|
|
bc7a54c615 | ||
|
|
1bda393678 | ||
|
|
bb5495c6bd | ||
|
|
484f905749 | ||
|
|
e0d61a4336 | ||
|
|
e643a16ba5 | ||
|
|
98fadec2b6 | ||
|
|
14f464ecb0 | ||
|
|
2ecdaf9bd4 | ||
|
|
707c898f66 | ||
|
|
69e4400774 | ||
|
|
695efde68d | ||
|
|
0c4b769011 | ||
|
|
e53eff0634 | ||
|
|
6c75243a06 | ||
|
|
efde37880b | ||
|
|
7d8f6381be | ||
|
|
3c361e3393 | ||
|
|
8440ecef5e | ||
|
|
6401f1b1c9 | ||
|
|
7487a7c988 | ||
|
|
f44584fa10 | ||
|
|
7b32165614 | ||
|
|
b0dc94d187 | ||
|
|
0383c4e1d8 | ||
|
|
a8c5758222 | ||
|
|
a7fabfd8cb | ||
|
|
5d5b575d16 | ||
|
|
ac1373653c | ||
|
|
b097aa787b | ||
|
|
723be0fe69 | ||
|
|
f0597a03de | ||
|
|
65f0656f54 | ||
|
|
507ece15a5 | ||
|
|
30be4d1613 | ||
|
|
366e89bda0 | ||
|
|
f159c3f768 | ||
|
|
8506d1d567 | ||
|
|
111829da46 | ||
|
|
605798073e | ||
|
|
8320f2b094 | ||
|
|
df0d8d809b | ||
|
|
062886df64 | ||
|
|
148ea3aaa8 | ||
|
|
ab5f66c13a | ||
|
|
e65ffb8e68 | ||
|
|
949c1ab517 | ||
|
|
946d8ee046 | ||
|
|
c54a8a2e10 | ||
|
|
31177e4f85 | ||
|
|
750f81b4b5 | ||
|
|
987ff02a45 | ||
|
|
f5adaf813c | ||
|
|
78ff7dc7f0 | ||
|
|
d1fced3324 | ||
|
|
e7df9c289b | ||
|
|
a78d7231a9 | ||
|
|
ba7ae0002e | ||
|
|
a090f7b839 | ||
|
|
34ed15a987 | ||
|
|
cacec4c910 | ||
|
|
3e47d4e65b | ||
|
|
8b42fa150b | ||
|
|
60e660b9c7 | ||
|
|
fe74f013e3 | ||
|
|
24c0c70f90 | ||
|
|
757f91ca89 | ||
|
|
5c34f7847e | ||
|
|
de456f014e | ||
|
|
d29565066d | ||
|
|
4d52c9233b | ||
|
|
6da1ca0cb9 | ||
|
|
2f02f1518a | ||
|
|
e8863707de | ||
|
|
6a336dfc69 | ||
|
|
35dec1b9e4 | ||
|
|
f148280c99 | ||
|
|
599fe39749 | ||
|
|
44f3fcb238 | ||
|
|
af40fdb285 | ||
|
|
9daf8b825c | ||
|
|
ef5d8ce367 | ||
|
|
4a199ab23b | ||
|
|
6f0f5a569d | ||
|
|
3172fbfde6 | ||
|
|
e97a07a505 | ||
|
|
6579ad92da | ||
|
|
ec2fad0cfa | ||
|
|
6196ac7995 | ||
|
|
095a861018 | ||
|
|
2449ed7765 | ||
|
|
117a0408d6 | ||
|
|
a54b0223a3 | ||
|
|
44ee708ba5 | ||
|
|
58a20d0fb6 | ||
|
|
063078a02d | ||
|
|
01402fea50 | ||
|
|
b7fc2d1147 | ||
|
|
43eeb7011c | ||
|
|
d7901a4220 | ||
|
|
0c6271dabc | ||
|
|
2d4cf0c9f5 | ||
|
|
0646d0dd91 | ||
|
|
83e54b45a5 | ||
|
|
5cd87d3d27 | ||
|
|
689d8a80b5 | ||
|
|
b1d82a92e7 | ||
|
|
4d65627a50 | ||
|
|
ce3a68d817 | ||
|
|
409725be24 | ||
|
|
b74f74a0d7 | ||
|
|
719d554430 | ||
|
|
13f54f4521 | ||
|
|
57dfc9cf42 | ||
|
|
57244a6823 | ||
|
|
8bdde01bef | ||
|
|
09bbd5a472 | ||
|
|
9154a74400 | ||
|
|
1399b84b32 | ||
|
|
2ddbb3a8fa | ||
|
|
e46a6d1cc1 | ||
|
|
b698ab9011 | ||
|
|
0a2572a5eb | ||
|
|
77d049cc3d | ||
|
|
7b8f053be2 | ||
|
|
2c850d5293 | ||
|
|
4056bbf10b | ||
|
|
896b04a846 | ||
|
|
93cda8b6ec | ||
|
|
bb5e930684 | ||
|
|
43761fed2a | ||
|
|
a636299680 | ||
|
|
08e5bd5b72 | ||
|
|
2f057bef5e | ||
|
|
5ab4f21444 | ||
|
|
9ec26ed481 | ||
|
|
29c9df1389 | ||
|
|
867e9c51d4 | ||
|
|
0170f7b42a | ||
|
|
74bb6ead95 | ||
|
|
303388e5cb | ||
|
|
8388779937 | ||
|
|
fc7dfca452 | ||
|
|
e5a1db2392 | ||
|
|
6790656af6 | ||
|
|
b7477bdc15 | ||
|
|
ffc61f31de | ||
|
|
e612871ea7 | ||
|
|
7f40f09f10 | ||
|
|
456e42257c | ||
|
|
8618c271cf | ||
|
|
72ca1ccc23 | ||
|
|
075b4bef3f | ||
|
|
b59fce4393 | ||
|
|
8674a25eb8 | ||
|
|
10bf8fd2cd | ||
|
|
57cb22ff3c | ||
|
|
0162abdcae | ||
|
|
5801171518 | ||
|
|
bf1edbd1e2 | ||
|
|
a8484d987d | ||
|
|
9b2147f608 | ||
|
|
32530b378e | ||
|
|
a42905efa6 | ||
|
|
c59745f9dd | ||
|
|
b4ad9a5d08 | ||
|
|
3ead7a38b1 | ||
|
|
bf90435200 | ||
|
|
9c181fa3d3 | ||
|
|
3af0b1eb90 | ||
|
|
7110c318ee | ||
|
|
49a552ccdc | ||
|
|
57685f17a9 | ||
|
|
a1c09a463f | ||
|
|
194121760a | ||
|
|
6a987d46bf | ||
|
|
e3db0b39b9 | ||
|
|
4d4f0ee188 | ||
|
|
ac7334c167 | ||
|
|
e7bdd69af0 | ||
|
|
fefc655969 | ||
|
|
4dceaef60e | ||
|
|
6fc10dd3ae | ||
|
|
1ecd05a584 | ||
|
|
976acaca31 | ||
|
|
b4e5131d59 | ||
|
|
49f7cfefd7 | ||
|
|
fc365092f6 | ||
|
|
7f26240442 | ||
|
|
db559bb20a | ||
|
|
52850faa15 | ||
|
|
57d9a6c836 | ||
|
|
752c880bfc | ||
|
|
d83a354781 | ||
|
|
17dd81336d | ||
|
|
eaa46a2575 | ||
|
|
fc0ec1e71e | ||
|
|
fb2f92df1d | ||
|
|
74adbb77b7 | ||
|
|
788e544e1d | ||
|
|
368a0d4d2d | ||
|
|
962b7222d0 | ||
|
|
17c1f54369 | ||
|
|
33ae38e71b | ||
|
|
ef58af4bf1 | ||
|
|
3fad2db2f8 | ||
|
|
9feaeb28ca | ||
|
|
0075364715 | ||
|
|
99c5da5da5 | ||
|
|
22c957bc20 | ||
|
|
3316d59910 | ||
|
|
a109ce1eca | ||
|
|
e581a78d65 | ||
|
|
3c78f9900c | ||
|
|
bd606943e6 | ||
|
|
6381666df4 | ||
|
|
736f1aa301 | ||
|
|
b1a4eac7a8 | ||
|
|
8226a5276b | ||
|
|
77ad0bb12e | ||
|
|
9412b42206 | ||
|
|
2a91d87074 | ||
|
|
4a23617d79 | ||
|
|
0e2ceed74d | ||
|
|
ed56aed8eb | ||
|
|
8d909cbdc0 | ||
|
|
bf98943cbb | ||
|
|
6ff4552be2 | ||
|
|
1c7eb79370 | ||
|
|
f095a75f1e | ||
|
|
f70af6018c | ||
|
|
71b3b1ff4c | ||
|
|
d9fefa0c6c | ||
|
|
3bfe922381 | ||
|
|
a85cf17bf1 | ||
|
|
dbb5a09918 | ||
|
|
93e5097f20 | ||
|
|
dd53f2dc83 | ||
|
|
2b83c80593 | ||
|
|
6930f60c06 | ||
|
|
376b76e75c | ||
|
|
1ddd4509dc | ||
|
|
6af3f4f4cf | ||
|
|
6726c5f958 | ||
|
|
d5a9c43cb2 | ||
|
|
19a5a6a4eb | ||
|
|
617a599ee9 | ||
|
|
25e2d4da44 | ||
|
|
ad2e7218cb | ||
|
|
917637fa9b | ||
|
|
b595ee1c0b | ||
|
|
c8260a4a56 | ||
|
|
d2eaff3204 | ||
|
|
b65f5a844f | ||
|
|
95a69f99ba | ||
|
|
71d609895a | ||
|
|
9229630447 | ||
|
|
eb18a0b7dc | ||
|
|
05ed5c0d74 | ||
|
|
41330ecc5e | ||
|
|
16fbcc6e36 | ||
|
|
d87da9c7de | ||
|
|
94563b6017 | ||
|
|
34d22f7047 | ||
|
|
e24d996fbe | ||
|
|
9b52617919 | ||
|
|
efc1d46c89 | ||
|
|
9397833ceb | ||
|
|
e9433e83cd | ||
|
|
f3c58100a0 | ||
|
|
8900231d99 | ||
|
|
c7a63b8a2b | ||
|
|
90e90672a4 | ||
|
|
fa51e5c762 | ||
|
|
911f55d005 | ||
|
|
d30eb4e570 | ||
|
|
67bcfb6947 | ||
|
|
3915a61b1e | ||
|
|
c170d321e8 | ||
|
|
2802c476ee | ||
|
|
1050cebf7f | ||
|
|
dad73465fc | ||
|
|
8e2ac98fe2 | ||
|
|
9aaf0c36d5 | ||
|
|
1cb07e9cfd | ||
|
|
f1ccdf25b1 | ||
|
|
6dca497b27 | ||
|
|
42a83262a1 | ||
|
|
63ee9cbee6 | ||
|
|
3862f8ca7c | ||
|
|
4ada7cffd0 | ||
|
|
a664ce4298 | ||
|
|
8d7b6c6905 | ||
|
|
16d22d404a | ||
|
|
ccb24d5779 | ||
|
|
8795b45cb4 | ||
|
|
628d3bff45 | ||
|
|
0336bc9de9 | ||
|
|
033cb21797 | ||
|
|
09b98a45df | ||
|
|
38857ba29e | ||
|
|
1c7520ec8f | ||
|
|
362b9769b2 | ||
|
|
b2d68bd3d2 | ||
|
|
0dc7e635d4 | ||
|
|
80e070a857 | ||
|
|
cc203245e4 | ||
|
|
2f9a65fc93 | ||
|
|
62738e8001 | ||
|
|
5ecacf0c7f | ||
|
|
06b103c8d4 | ||
|
|
d473b7bca8 | ||
|
|
50a1e81ba7 | ||
|
|
d9885b1b64 | ||
|
|
0a9c8cada2 | ||
|
|
60f55f8461 | ||
|
|
7bedaea38f | ||
|
|
9e4b87e798 | ||
|
|
95bf59095c | ||
|
|
e0f34a9720 | ||
|
|
f3797c2a8e | ||
|
|
30cbcccc80 | ||
|
|
f49c0d696f | ||
|
|
71f564ee5b | ||
|
|
4b0950aba5 | ||
|
|
8c3af822ec | ||
|
|
878a207d19 | ||
|
|
0537ad860a | ||
|
|
2cdbbb1aea | ||
|
|
7af977d36b | ||
|
|
9afff4cf30 | ||
|
|
48ba9734aa | ||
|
|
897fc59f72 | ||
|
|
947e44ae67 | ||
|
|
e44843beba | ||
|
|
147482ea69 | ||
|
|
09091c5cf8 | ||
|
|
50827a5f69 | ||
|
|
2d6444c924 | ||
|
|
1d2675d9aa | ||
|
|
ad98990a8e | ||
|
|
8e58c143f2 | ||
|
|
556a4a2395 | ||
|
|
5be987b40f | ||
|
|
066bc35e69 | ||
|
|
403779437c | ||
|
|
fb806f61d4 | ||
|
|
6ce306661c |
34
INSTALL
34
INSTALL
@@ -1,44 +1,30 @@
|
||||
LVM2 installation
|
||||
=================
|
||||
Installation
|
||||
============
|
||||
|
||||
1) Install device-mapper
|
||||
|
||||
Ensure the device-mapper has been installed on the machine.
|
||||
|
||||
The device-mapper should be in the kernel (look for 'device-mapper'
|
||||
messages in the kernel logs) and /usr/include/libdevmapper.h
|
||||
and libdevmapper.so should be present.
|
||||
|
||||
The device-mapper is available from:
|
||||
ftp://ftp.sistina.com/pub/LVM2/device-mapper/
|
||||
|
||||
|
||||
2) Generate custom makefiles.
|
||||
1) Generate custom makefiles.
|
||||
|
||||
Run the 'configure' script from the top directory.
|
||||
|
||||
If you wish to use the built-in LVM2 shell and have GNU readline
|
||||
installed (http://www.gnu.org/directory/readline.html) use:
|
||||
./configure --enable-readline
|
||||
|
||||
If you don't want to include the LVM1 backwards-compatibility code use:
|
||||
./configure --with-lvm1=none
|
||||
|
||||
To separate the LVM1 support into a shared library loaded by lvm.conf use:
|
||||
./configure --with-lvm1=shared
|
||||
|
||||
Use ./configure --help to see other options.
|
||||
|
||||
3) Build and install LVM2.
|
||||
2) Build and install.
|
||||
|
||||
Run 'make install' from the top directory.
|
||||
Run 'make' from the top directory to build everything you configured.
|
||||
Run 'make install' to build and install everything you configured.
|
||||
|
||||
If you only want the device-mapper libraries and tools use
|
||||
'make device-mapper' or 'make install_device-mapper'.
|
||||
|
||||
4) Create a configuration file
|
||||
3) If using LVM2, create a configuration file.
|
||||
|
||||
The tools will work fine without a configuration file being
|
||||
present, but you ought to review the example file in doc/example.conf.
|
||||
For example, specifying the devices that LVM2 is to use can
|
||||
make the tools run more efficiently - and avoid scanning /dev/cdrom!
|
||||
|
||||
Please also refer to the WHATS_NEW file and the manual pages for the
|
||||
individual commands.
|
||||
|
||||
67
Makefile.in
67
Makefile.in
@@ -1,6 +1,6 @@
|
||||
#
|
||||
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
# Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
|
||||
# Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
|
||||
#
|
||||
# This file is part of LVM2.
|
||||
#
|
||||
@@ -22,39 +22,40 @@ ifeq ("@INTL@", "yes")
|
||||
SUBDIRS += po
|
||||
endif
|
||||
|
||||
SUBDIRS += lib tools daemons
|
||||
|
||||
ifeq ("@DMEVENTD@", "yes")
|
||||
SUBDIRS += dmeventd
|
||||
endif
|
||||
SUBDIRS += lib tools daemons libdm
|
||||
|
||||
ifeq ($(MAKECMDGOALS),distclean)
|
||||
SUBDIRS += daemons/clvmd \
|
||||
dmeventd \
|
||||
daemons/dmeventd/plugins \
|
||||
lib/format1 \
|
||||
lib/format_pool \
|
||||
lib/locking \
|
||||
lib/mirror \
|
||||
lib/snapshot \
|
||||
po \
|
||||
test/mm test/device test/format1 test/regex test/filters
|
||||
test \
|
||||
po
|
||||
DISTCLEAN_TARGETS += lib/misc/configure.h
|
||||
DISTCLEAN_DIRS += lcov_reports*
|
||||
endif
|
||||
|
||||
include make.tmpl
|
||||
|
||||
libdm: include
|
||||
lib: libdm
|
||||
daemons: lib
|
||||
lib: include
|
||||
tools: lib
|
||||
dmeventd: tools
|
||||
po: tools daemons dmeventd
|
||||
tools: lib device-mapper
|
||||
po: tools daemons
|
||||
|
||||
libdm.device-mapper: include.device-mapper
|
||||
daemons.device-mapper: libdm.device-mapper
|
||||
tools.device-mapper: libdm.device-mapper
|
||||
device-mapper: tools.device-mapper daemons.device-mapper man.device-mapper
|
||||
|
||||
ifeq ("@INTL@", "yes")
|
||||
lib.pofile: include.pofile
|
||||
tools.pofile: lib.pofile
|
||||
daemons.pofile: lib.pofile
|
||||
dmeventd.pofile: tools.pofile
|
||||
po.pofile: tools.pofile daemons.pofile dmeventd.pofile
|
||||
po.pofile: tools.pofile daemons.pofile
|
||||
pofile: po.pofile
|
||||
endif
|
||||
|
||||
@@ -71,3 +72,39 @@ endif
|
||||
|
||||
check: all
|
||||
$(MAKE) -C test all
|
||||
|
||||
ifneq ("@LCOV@", "")
|
||||
.PHONY: lcov-reset lcov lcov-dated
|
||||
|
||||
ifeq ($(MAKECMDGOALS),lcov-dated)
|
||||
LCOV_REPORTS_DIR=$(top_srcdir)/lcov_reports-$(shell date +%Y%m%d%k%M%S)
|
||||
else
|
||||
LCOV_REPORTS_DIR=$(top_srcdir)/lcov_reports
|
||||
endif
|
||||
|
||||
lcov-reset:
|
||||
$(LCOV) -d $(top_srcdir)/dmeventd --zerocounters
|
||||
$(LCOV) -d $(top_srcdir)/libdm --zerocounters
|
||||
$(LCOV) -d $(top_srcdir)/lib --zerocounters
|
||||
$(LCOV) -d $(top_srcdir)/tools --zerocounters
|
||||
|
||||
lcov: all
|
||||
$(RM) -rf $(LCOV_REPORTS_DIR)
|
||||
$(MKDIR_P) $(LCOV_REPORTS_DIR)
|
||||
$(LCOV) -b ${top_srcdir}/libdm -d $(top_srcdir)/libdm -c -o $(LCOV_REPORTS_DIR)/libdm.info
|
||||
$(LCOV) -b $(top_srcdir)/lib -d $(top_srcdir)/lib -c -o $(LCOV_REPORTS_DIR)/lib.info
|
||||
$(LCOV) -b $(top_srcdir)/tools -d $(top_srcdir)/tools -c -o $(LCOV_REPORTS_DIR)/tools.info
|
||||
DMEVENTD_INFO="$(LCOV_REPORTS_DIR)/dmeventd.info" ;\
|
||||
DMEVENTD_INFO_A="-a $$DMEVENTDINFO" ;\
|
||||
$(LCOV) -b $(top_srcdir)/dmeventd -d $(top_srcdir)/dmeventd -c -o $$DMEVENTD_INFO || DMEVENTD_INFO_A="" ;\
|
||||
$(LCOV) $$DMEVENTD_INFO_A -a $(LCOV_REPORTS_DIR)/lib.info \
|
||||
-a $(LCOV_REPORTS_DIR)/libdm.info \
|
||||
-a $(LCOV_REPORTS_DIR)/tools.info \
|
||||
-o $(LCOV_REPORTS_DIR)/lvm.info
|
||||
ifneq ("@GENHTML@", "")
|
||||
$(GENHTML) -o $(LCOV_REPORTS_DIR) -p $(top_srcdir) $(LCOV_REPORTS_DIR)/lvm.info
|
||||
endif
|
||||
|
||||
lcov-dated: lcov
|
||||
|
||||
endif
|
||||
|
||||
18
README
18
README
@@ -1,23 +1,27 @@
|
||||
This directory contains LVM2, the new version of the userland LVM
|
||||
tools designed for the new device-mapper for the Linux kernel.
|
||||
This tree contains the LVM2 and device-mapper tools and libraries.
|
||||
|
||||
The device-mapper needs to be installed before compiling these LVM2 tools.
|
||||
|
||||
For more information about LVM2 read the WHATS_NEW file.
|
||||
For more information about LVM2 read the changelog in the WHATS_NEW file.
|
||||
Installation instructions are in INSTALL.
|
||||
|
||||
There is no warranty - see COPYING and COPYING.LIB.
|
||||
|
||||
Tarballs are available from:
|
||||
ftp://sources.redhat.com/pub/lvm2/
|
||||
ftp://sources.redhat.com/pub/dm/
|
||||
|
||||
To access the CVS tree use:
|
||||
cvs -d :pserver:cvs@sources.redhat.com:/cvs/lvm2 login
|
||||
CVS password: cvs
|
||||
cvs -d :pserver:cvs@sources.redhat.com:/cvs/lvm2 co LVM2
|
||||
|
||||
Mailing list for discussion/bug reports etc.
|
||||
Mailing list for general discussion related to LVM2:
|
||||
linux-lvm@redhat.com
|
||||
Subscribe from https://www.redhat.com/mailman/listinfo/linux-lvm
|
||||
|
||||
Mailing list for LVM2 development, patches and commits:
|
||||
lvm-devel@redhat.com
|
||||
Subscribe from https://www.redhat.com/mailman/listinfo/linux-lvm
|
||||
|
||||
Mailing list for device-mapper development, including kernel patches
|
||||
and multipath-tools:
|
||||
dm-devel@redhat.com
|
||||
Subscribe from https://www.redhat.com/mailman/listinfo/dm-devel
|
||||
|
||||
1
VERSION_DM
Normal file
1
VERSION_DM
Normal file
@@ -0,0 +1 @@
|
||||
1.02.29-cvs (2008-11-10)
|
||||
295
WHATS_NEW
295
WHATS_NEW
@@ -1,5 +1,288 @@
|
||||
Version 2.02.29 -
|
||||
==================================
|
||||
Version 2.02.43 - 10th November 2008
|
||||
====================================
|
||||
Merge device-mapper into the lvm2 tree.
|
||||
Correct prototype for --permission on lvchange and lvcreate man pages.
|
||||
Exit with non-zero status from vgdisplay if couldn't show any requested VG.
|
||||
Move list.c into libdevmapper and rename functions.
|
||||
Rename a couple of variables that matched function names.
|
||||
Use simplified x.y.z version number in libdevmapper.pc.
|
||||
Remove ancient debian directory.
|
||||
Split out lvm-logging.h from log.h and lvm-globals.[ch] from log.[ch].
|
||||
|
||||
Version 2.02.42 - 26th October 2008
|
||||
===================================
|
||||
Accept locking fallback_to_* options in the global section as documented.
|
||||
Fix temp table activation in mirror conversions not to happen in other cmds.
|
||||
Fix temp table in mirror conversions to use always-present error not zero.
|
||||
|
||||
Version 2.02.41 - 17th October 2008
|
||||
===================================
|
||||
Use temp table to set device size when converting mirrors.
|
||||
In resume_mirror_images replace activate_lv with resume_lv as workaround.
|
||||
Avoid overwriting in-use on-disk text metadata by forgetting MDA_HEADER_SIZE.
|
||||
Fix snapshot monitoring library to not cancel monitoring invalid snapshot.
|
||||
Generate man pages from templates and include version.
|
||||
Add usrlibdir and usrsbindir to configure.
|
||||
Fix conversion of md chunk size into sectors.
|
||||
Free text metadata buffer after a failure writing it.
|
||||
Fix misleading error message when there are no allocatable extents in VG.
|
||||
Fix handling of PVs which reappeared with old metadata version.
|
||||
Fix mirror DSO to call vgreduce with proper parameters.
|
||||
Fix validation of --minor and --major in lvcreate to require -My always.
|
||||
Fix release: clvmd build, vgreduce consolidate & tests, /dev/ioerror warning.
|
||||
|
||||
Version 2.02.40 - 19th September 2008
|
||||
=====================================
|
||||
Allow lvremove to remove LVs from VGs with missing PVs.
|
||||
In VG with PVs missing, by default allow activation of LVs that are complete.
|
||||
Track PARTIAL_LV and MISSING_PV flags internally.
|
||||
Require --force with --removemissing in vgreduce to remove partial LVs.
|
||||
No longer write out PARTIAL flag into metadata backups.
|
||||
Treat new default activation/missing_stripe_filler "error" as an error target.
|
||||
Remove internal partial_mode.
|
||||
Add devices/md_chunk_alignment to lvm.conf.
|
||||
Pass struct physical_volume to pe_align and adjust for md chunk size.
|
||||
Store sysfs location in struct cmd_context.
|
||||
Avoid shuffling remaining mirror images when removing one, retaining primary.
|
||||
Add missing LV error target activation in _remove_mirror_images.
|
||||
Prevent resizing an LV while lvconvert is using it.
|
||||
Avoid repeatedly wiping cache while VG_GLOBAL is held in vgscan & pvscan.
|
||||
Fix pvresize to not allow resize if PV has two metadata areas.
|
||||
Fix setting of volume limit count if converting to lvm1 format.
|
||||
Fix vgconvert logical volume id metadata validation.
|
||||
Fix lvmdump metadata gather option (-m) to work correctly.
|
||||
Fix allocation bug in text metadata format write error path.
|
||||
Fix vgcfgbackup to properly check filename if template is used.
|
||||
configure aborts if lcov or genhtml are missing with --enable-profiling
|
||||
vgremove tries to remove lv snapshot first.
|
||||
Added function lv_remove_with_dependencies().
|
||||
Improve file descriptor leak detection to display likely culprit and filename.
|
||||
Change clustered mirror kernel module name from cmirror to dm-log-clustered.
|
||||
Avoid looping forever in _pv_analyze_mda_raw used by pvck.
|
||||
Change lvchange exit status to indicate if any part of the operation failed.
|
||||
Fix pvchange and pvremove to handle PVs without mdas.
|
||||
Refactor _text_pv_read and always return mda list if requested.
|
||||
Fix configure to work w/o readline unless --enable-readline used. (2.02.39)
|
||||
Remove is_lvm_partition template which has not yet been coded.
|
||||
Refactor pvcreate to separate parameter parsing from validation logic.
|
||||
Check for label_write() failure in _text_pv_write().
|
||||
Add pvcreate tests and update vgsplit tests to handle lvm1 and lvm2 metadata.
|
||||
Fix pvchange -M1 -u to preserve existing extent locations when there's a VG.
|
||||
Cease recognising snapshot-in-use percentages returned by early devt kernels.
|
||||
Add backward-compatible flags field to on-disk format_text metadata.
|
||||
Fix dmeventd monitoring libraries to link against liblvm2cmd again. (2.02.39)
|
||||
|
||||
Version 2.02.39 - 27th June 2008
|
||||
================================
|
||||
Enable readline by default if available.
|
||||
Update autoconf to 2008-01-16.
|
||||
Add $DISTCLEAN_DIRS to make.tmpl.in.
|
||||
Create coverage reports with --enable-profiling and make lcov or lcov-dated.
|
||||
Fix up cache for PVs without mdas after consistent VG metadata is processed.
|
||||
Update validation of safe mirror log type conversions in lvconvert.
|
||||
Fix lvconvert to disallow snapshot and mirror combinations.
|
||||
Fix reporting of LV fields alongside unallocated PV segments.
|
||||
Add --unquoted and --rows to reporting tools.
|
||||
Add and use uninitialized_var() macro to suppress invalid compiler warnings.
|
||||
Introduce enum for md minor sb version to suppress compiler warning.
|
||||
Avoid undefined return value after _memlock manipulation in lvm2_run.
|
||||
Avoid link failure if configured without --enable-cmdlib or --enable-readline.
|
||||
Make clvmd return at once if other nodes down in a gulm or openais cluster.
|
||||
Fix and improve readahead 'auto' calculation for stripe_size.
|
||||
Fix lvchange output for -r auto setting if auto is already set.
|
||||
Add test case for readahead.
|
||||
Avoid ambiguous use of identifier error_message_produced.
|
||||
Begin syncing configure.in for merge/unification with device-mapper.
|
||||
Fix add_mirror_images not to dereference uninitialized log_lv upon failure.
|
||||
Don't call openlog for every debug line output by clvmd.
|
||||
Add --force to lvextend and lvresize.
|
||||
Fix vgchange not to activate component mirror volumes directly.
|
||||
Fix test directory clean up in make distclean.
|
||||
|
||||
Version 2.02.38 - 11th June 2008
|
||||
================================
|
||||
Fix tracking of validity of PVs with no mdas in lvmcache.
|
||||
Fix return values for reporting commands when run with no PVs, LVs, or VGs.
|
||||
Add omitted unlock_vg() call when sigint_caught() during vg processing.
|
||||
Fix free_count when reading pool metadata.
|
||||
Fix segfault when using pvcreate on a device containing pool metadata.
|
||||
Fix segfault after _free_vginfo by remembering to remove vginfo from list.
|
||||
Tweak detection of invalid fid after changes to PVs in VG in _vg_read.
|
||||
Revert assuming precommitted metadata is live when activating (unnecessary).
|
||||
Drop cached metadata for disappearing VG in vgmerge.
|
||||
In script-processing mode, stop if any command fails.
|
||||
Warn if command exits with non-zero status code without a prior log_error.
|
||||
Check lv_count in vg_validate.
|
||||
Add --nameprefixes to reporting tools for field name prefix output format.
|
||||
|
||||
Version 2.02.37 - 6th June 2008
|
||||
===============================
|
||||
Make clvmd-cman use a hash rather than an array for node updown info.
|
||||
Correct config file line numbers in messages when parsing comments.
|
||||
Drop cached metadata when renaming a VG.
|
||||
Allow for vginfo changing during _vg_read.
|
||||
Decode numbers in clvmd debugging output.
|
||||
Add missing deactivation after activation failure in lvcreate -Zy.
|
||||
When activating, if precommitted metadata is still cached, assume it's live.
|
||||
When removing LV symlinks, skip any where the VG name is not determined.
|
||||
Drop metadata cache if update fails in vg_revert or vg_commit.
|
||||
Avoid spurious duplicate VG messages referring to VGs that are gone.
|
||||
Drop dev_name_confirmed error message to debug level.
|
||||
Fix setpriority error message to signed int.
|
||||
Temporarily disable dmeventd mirror monitoring during lvchange --resync.
|
||||
Refactor some vginfo manipulation code.
|
||||
Add assertions to trap deprecated P_ and V_ lock usage.
|
||||
Add missing mutex around clvmd lvmcache_drop_metadata library call.
|
||||
Fix uninitialised mutex in clvmd if all daemons are not running at startup.
|
||||
Avoid using DLM locks with LCK_CACHE type P_ lock requests.
|
||||
When asked to drop cached committed VG metadata, invalidate cached PV labels.
|
||||
Drop metadata cache before writing precommitted metadata instead of after.
|
||||
Don't touch /dev in vgrename if activation is disabled.
|
||||
|
||||
Version 2.02.36 - 29th April 2008
|
||||
=================================
|
||||
Fix fsadm.sh to work with older blockdev, blkid & readlink binaries.
|
||||
Fix lvresize to pass new size to fsadm when extending device.
|
||||
Remove unused struct in clvmd-openais, and use correct node count.
|
||||
Fix nodes list in clvmd-openais, and allow for broadcast messages.
|
||||
Exclude VG_GLOBAL from internal concurrent VG lock counter.
|
||||
Fix vgsplit internal counting of snapshot LVs.
|
||||
Fix vgmerge snapshot_count when source VG contains snapshots.
|
||||
Simplify clvmd-openais by using non-async saLckResourceLock.
|
||||
Fix internal LV counter when a snapshot is removed.
|
||||
Fix metadata corruption writing lvm1-formatted metadata with snapshots.
|
||||
Fix lvconvert -m0 allocatable space check.
|
||||
|
||||
Version 2.02.35 - 15th April 2008
|
||||
=================================
|
||||
Drop cached VG metadata before and after committing changes to it.
|
||||
Rename P_global to P_#global.
|
||||
Don't attempt remote metadata backups of non-clustered VGs. (2.02.29)
|
||||
Don't store fid in VG metadata cache to avoid clvmd segfault. (2.02.34)
|
||||
Update vgsplit tests to verify loosening of active LV restriction.
|
||||
Update vgsplit to only restrict split with active LVs involved in split.
|
||||
Add lv_is_active() to determine whether an lv is active.
|
||||
|
||||
Version 2.02.34 - 10th April 2008
|
||||
=================================
|
||||
Improve preferred_names lvm.conf example.
|
||||
Fix vgdisplay 'Cur LV' field to match lvdisplay output.
|
||||
Fix lv_count report field to exclude hidden LVs.
|
||||
Add vg_is_clustered() helper function.
|
||||
Fix vgsplit to only move hidden 'snapshotN' LVs when necessary.
|
||||
Update vgsplit tests for lvnames on the cmdline.
|
||||
Update vgsplit man page to reflect lvnames on the cmdline.
|
||||
Update vgsplit to take "-n LogicalVolumeName" on the cmdline.
|
||||
Use clustered mirror log with pvmove in clustered VGs, if available.
|
||||
Fix some pvmove error status codes.
|
||||
Fix vgsplit error paths to release vg_to lock.
|
||||
Indicate whether or not VG is clustered in vgcreate log message.
|
||||
Mention default --clustered setting in vgcreate man page.
|
||||
Add config file overrides to clvmd when it reads the active LVs list.
|
||||
Fix vgreduce to use vg_split_mdas to check sufficient mdas remain.
|
||||
Add (empty) orphan VGs to lvmcache during initialisation.
|
||||
Fix orphan VG name used for format_pool.
|
||||
Create a fid for internal orphan VGs.
|
||||
Update lvmcache VG lock state for all locking types now.
|
||||
Fix output if overriding command_names on cmdline.
|
||||
Add detection of clustered mirror log capability.
|
||||
Add check to vg_commit() ensuring VG lock held before writing new VG metadata.
|
||||
Add validation of LV name to pvmove -n.
|
||||
Make clvmd refresh the context correctly when lvm.conf is updated.
|
||||
Add some basic internal VG lock validation.
|
||||
Add per-command flags to control which commands use the VG metadata cache.
|
||||
Fix vgsplit locking of new VG (2.02.30).
|
||||
Avoid erroneous vgsplit error message for new VG. (2.02.29)
|
||||
Suppress duplicate message when lvresize fails because of invalid vgname.
|
||||
Cache VG metadata internally while VG lock is held.
|
||||
Fix redundant lvresize message if vg doesn't exist.
|
||||
Fix another allocation bug with clvmd and large node IDs.
|
||||
Add find_lv_in_lv_list() and find_pv_in_pv_list().
|
||||
Fix uninitialised variable in clvmd that could cause odd hangs.
|
||||
Add vgmerge tests.
|
||||
Add pvseg_is_allocated() for identifying a PV segment allocated to a LV.
|
||||
Add list_move() for moving elements from one list to another.
|
||||
Add 'is_reserved_lvname()' for identifying hidden LVs.
|
||||
Correct command name in lvmdiskscan man page.
|
||||
clvmd no longer crashes if it sees nodeids over 50.
|
||||
Fix potential deadlock in clvmd thread handling.
|
||||
Refactor text format initialisation into _init_text_import.
|
||||
Escape double quotes and backslashes in external metadata and config data.
|
||||
Add functions for escaping double quotes in strings.
|
||||
Rename count_chars_len to count_chars.
|
||||
Use return_0 in a couple more places.
|
||||
Correct a function name typo in _line_append error message.
|
||||
Include limits.h in clvmd so it compiles with newer headers.
|
||||
Add VirtIO disks (virtblk) to filters.
|
||||
Fix resetting of MIRROR_IMAGE and VISIBLE_LV after removal of LV. (2.02.30)
|
||||
Fix remove_layer_from_lv to empty the LV before removing it. (2.02.30)
|
||||
Add missing no-longer-used segs_using_this_lv test to check_lv_segments.
|
||||
Remove redundant non-NULL tests before calling free in clvmd.c.
|
||||
Avoid a compiler warning: make is_orphan's parameter const.
|
||||
Fix lvconvert detection of mirror conversion in progress. (2.02.30)
|
||||
Avoid automatic lvconvert polldaemon invocation when -R specified. (2.02.30)
|
||||
Fix 'pvs -a' to detect VGs of PVs without metadata areas.
|
||||
Divide up internal orphan volume group by format type.
|
||||
Update usage message for clvmd.
|
||||
Fix clvmd man page not to print <br> and clarified debug options.
|
||||
Fix lvresize to support /dev/mapper prefix in the LV name.
|
||||
Fix unfilled parameter passed to fsadm from lvresize.
|
||||
Update fsadm to call lvresize if the partition size differs (with option -l).
|
||||
Fix fsadm to support VG/LV names.
|
||||
|
||||
Version 2.02.33 - 31st January 2008
|
||||
===================================
|
||||
Fix mirror log name construction during lvconvert. (2.02.30)
|
||||
Make monitor_dev_for_events recurse through the stack of LVs.
|
||||
Clean up some more compiler warnings.
|
||||
Some whitespace tidy-ups.
|
||||
Use stack return macros throughout.
|
||||
Rely upon internally-cached PV labels while corresponding VG lock is held.
|
||||
|
||||
Version 2.02.32 - 29th January 2008
|
||||
===================================
|
||||
Fix two check_lv_segments error messages to show whole segment.
|
||||
Refactor mirror log attachment code.
|
||||
Fix internal metadata corruption in lvchange --resync. (2.02.30)
|
||||
Fix new parameter validation in vgsplit and test mode. (2.02.30)
|
||||
Remove redundant cnxman-socket.h file from clvmd directory.
|
||||
Fix pvs, vgs, lvs error exit status on some error paths.
|
||||
|
||||
Version 2.02.31 - 19th January 2008
|
||||
===================================
|
||||
Fix lvcreate --nosync not to wait for non-happening sync. (2.02.30)
|
||||
Add very_verbose lvconvert messages.
|
||||
Avoid readahead error message with default setting of lvcreate -M1. (2.02.29)
|
||||
|
||||
Version 2.02.30 - 17th January 2008
|
||||
===================================
|
||||
Set default readahead to twice maximium stripe size.
|
||||
Reinstate VG extent size and stripe size defaults (halved). (2.02.29)
|
||||
Add lists of stacked LV segments using each LV to the internal metadata.
|
||||
Change vgsplit -l (for unimplemented --list) into --maxlogicalvolumes.
|
||||
Fix process_all_pvs to detect non-orphans with no MDAs correctly.
|
||||
Don't use block_on_error with mirror targets version 1.12 and above.
|
||||
Update vgsplit to accept vgcreate options when new VG is destination.
|
||||
Update vgsplit to accept existing VG as destination.
|
||||
lvconvert waits for completion of initial sync by default.
|
||||
Refactor vgcreate for parameter validation and add tests.
|
||||
Add new convert_lv field to lvs output.
|
||||
Print warning when lvm tools are running as non-root.
|
||||
Add snapshot dmeventd library (enables dmeventd snapshot monitoring).
|
||||
Prevent pvcreate from overwriting MDA-less PVs belonging to active VGs.
|
||||
Fix a segfault if using pvs with --all argument. (2.02.29)
|
||||
Update --uuid argument description in man pages.
|
||||
Fix vgreduce PV list processing not to process every PV in the VG. (2.02.29)
|
||||
Extend lvconvert to use polldaemon.
|
||||
Add support for stacked mirrors.
|
||||
Major restructuring of pvmove and lvconvert layer manipulation code.
|
||||
Replace tools/fsadm with scripts/fsadm.sh.
|
||||
Append fields to report/pvsegs_cols_verbose.
|
||||
Permit LV segment fields with PV segment reports.
|
||||
Add seg_start_pe and seg_pe_ranges to reports.
|
||||
|
||||
Version 2.02.29 - 5th December 2007
|
||||
===================================
|
||||
Make clvmd backup vg metadata on remote nodes.
|
||||
Refactor pvmove allocation code.
|
||||
Decode cluster locking state in log message.
|
||||
@@ -36,14 +319,16 @@ Version 2.02.29 -
|
||||
Add const attributes to pv accessor functions.
|
||||
Refactor vg_add_snapshot() and lv_create_empty().
|
||||
Handle new sysfs subsystem/block/devices directory structure.
|
||||
Tests are run with LVM_SYSTEM_DIR pointing to private root and /dev dirs.
|
||||
Run test with LVM_SYSTEM_DIR pointing to private root and /dev dirs.
|
||||
Fix a bug in lvm_dump.sh checks for lvm/dmsetup binaries.
|
||||
Fix underquotations in lvm_dump.sh.
|
||||
Refactor lvcreate stripe and mirror parameter validation.
|
||||
All tools: print --help output to stdout, not stderr.
|
||||
After a diagnostic, suggest --help, rather than printing all --help output.
|
||||
Print --help output to stdout, not stderr.
|
||||
After a cmdline processing error, don't print help text but suggest --help.
|
||||
Add %PVS extents option to lvresize, lvextend, and lvcreate.
|
||||
Add 'make check' to run tests in new subdirectory 'test'.
|
||||
Moved the obsolete test subdirectory to old-tests.
|
||||
Cope with relative paths in configure --with-dmdir.
|
||||
Remove no-longer-correct restrictions on PV arg count with stripes/mirrors.
|
||||
Fix strdup memory leak in str_list_dup().
|
||||
Link with -lpthread when static SELinux libraries require that.
|
||||
|
||||
53
WHATS_NEW_DM
53
WHATS_NEW_DM
@@ -1,10 +1,58 @@
|
||||
Version 1.02.29 - 10th November 2008
|
||||
====================================
|
||||
Merge device-mapper into the LVM2 tree.
|
||||
Split out dm-logging.h from log.h.
|
||||
Use lvm-types.h.
|
||||
Add usrsbindir to configure.
|
||||
|
||||
Version 1.02.28 - 18th September 2008
|
||||
=====================================
|
||||
Only resume devices in dm_tree_preload_children if size changes.
|
||||
Extend deptree buffers so the largest possible device numbers fit.
|
||||
Generate versioned libdevmapper-event.so.
|
||||
Underline longer report help text headings.
|
||||
|
||||
Version 1.02.27 - 25th June 2008
|
||||
================================
|
||||
Align struct memblock in dbg_malloc for sparc.
|
||||
Add --unquoted and --rows to dmsetup.
|
||||
Avoid compiler warning about cast in dmsetup.c's OFFSET_OF macro.
|
||||
Fix inverted no_flush debug message.
|
||||
Remove --enable-jobs from configure. (Set at runtime instead.)
|
||||
Bring configure.in and list.h into line with the lvm2 versions.
|
||||
|
||||
Version 1.02.26 - 6th June 2008
|
||||
===============================
|
||||
Initialise params buffer to empty string in _emit_segment.
|
||||
Skip add_dev_node when ioctls disabled.
|
||||
Make dm_hash_iter safe against deletion.
|
||||
Accept a NULL pointer to dm_free silently.
|
||||
Add tables_loaded, readonly and suspended columns to reports.
|
||||
Add --nameprefixes to dmsetup.
|
||||
Add field name prefix option to reporting functions.
|
||||
Calculate string size within dm_pool_grow_object.
|
||||
|
||||
Version 1.02.25 - 10th April 2008
|
||||
=================================
|
||||
Remove redundant if-before-free tests.
|
||||
Use log_warn for reporting field help text instead of log_print.
|
||||
Change cluster mirror log type name (s/clustered_/clustered-/)
|
||||
|
||||
Version 1.02.24 - 20th December 2007
|
||||
====================================
|
||||
Fix deptree to pass new name to _resume_node after a rename.
|
||||
Suppress other node operations if node is deleted.
|
||||
Add node operation stack debug messages.
|
||||
Report error when empty device name passed to readahead functions.
|
||||
Fix minimum readahead debug message.
|
||||
|
||||
Version 1.02.23 - 5th December 2007
|
||||
===================================
|
||||
Update dm-ioctl.h after removal of compat code.
|
||||
Add readahead support to libdevmapper and dmsetup.
|
||||
Fix double free in a libdevmapper-event error path.
|
||||
Fix configure --with-dmeventd-path substitution.
|
||||
Allow a DM_DEV_DIR environment variable to override /dev.
|
||||
Allow a DM_DEV_DIR environment variable to override /dev in dmsetup.
|
||||
Create a libdevmapper.so.$LIB_VERSION symlink within the build tree.
|
||||
Avoid static link failure with some SELinux libraries that require libpthread.
|
||||
Remove obsolete dmfs code from tree and update INSTALL.
|
||||
@@ -22,7 +70,7 @@ Version 1.02.22 - 21st August 2007
|
||||
Version 1.02.21 - 13th July 2007
|
||||
================================
|
||||
Introduce _LOG_STDERR to send log_warn() messages to stderr not stdout.
|
||||
Fix dmsetup -o devno string termination. (1.02.20)
|
||||
Fix dmsetup -o devno string termination. (1.02.20)
|
||||
|
||||
Version 1.02.20 - 15th June 2007
|
||||
================================
|
||||
@@ -310,4 +358,3 @@ Version 1.00.08 - 27 Feb 2004
|
||||
Fixed DESTDIR for make install/install_static_lib.
|
||||
Updated README/INSTALL to reflect move to sources.redhat.com.
|
||||
Updated autoconf files to 2003-06-17.
|
||||
|
||||
|
||||
60
autoconf/config.guess
vendored
60
autoconf/config.guess
vendored
@@ -1,10 +1,10 @@
|
||||
#! /bin/sh
|
||||
# Attempt to guess a canonical system name.
|
||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||
# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
|
||||
# Inc.
|
||||
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
|
||||
# Free Software Foundation, Inc.
|
||||
|
||||
timestamp='2006-07-02'
|
||||
timestamp='2008-01-23'
|
||||
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
@@ -56,8 +56,8 @@ version="\
|
||||
GNU config.guess ($timestamp)
|
||||
|
||||
Originally written by Per Bothner.
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||
Free Software Foundation, Inc.
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
|
||||
2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
@@ -161,6 +161,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
arm*) machine=arm-unknown ;;
|
||||
sh3el) machine=shl-unknown ;;
|
||||
sh3eb) machine=sh-unknown ;;
|
||||
sh5el) machine=sh5le-unknown ;;
|
||||
*) machine=${UNAME_MACHINE_ARCH}-unknown ;;
|
||||
esac
|
||||
# The Operating System including object format, if it has switched
|
||||
@@ -329,7 +330,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
|
||||
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
exit ;;
|
||||
i86pc:SunOS:5.*:*)
|
||||
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
|
||||
echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
exit ;;
|
||||
sun4*:SunOS:6*:*)
|
||||
@@ -531,7 +532,7 @@ EOF
|
||||
echo rs6000-ibm-aix3.2
|
||||
fi
|
||||
exit ;;
|
||||
*:AIX:*:[45])
|
||||
*:AIX:*:[456])
|
||||
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
|
||||
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
|
||||
IBM_ARCH=rs6000
|
||||
@@ -780,7 +781,7 @@ EOF
|
||||
i*:CYGWIN*:*)
|
||||
echo ${UNAME_MACHINE}-pc-cygwin
|
||||
exit ;;
|
||||
i*:MINGW*:*)
|
||||
*:MINGW*:*)
|
||||
echo ${UNAME_MACHINE}-pc-mingw32
|
||||
exit ;;
|
||||
i*:windows32*:*)
|
||||
@@ -790,12 +791,18 @@ EOF
|
||||
i*:PW*:*)
|
||||
echo ${UNAME_MACHINE}-pc-pw32
|
||||
exit ;;
|
||||
x86:Interix*:[3456]*)
|
||||
echo i586-pc-interix${UNAME_RELEASE}
|
||||
exit ;;
|
||||
EM64T:Interix*:[3456]*)
|
||||
echo x86_64-unknown-interix${UNAME_RELEASE}
|
||||
exit ;;
|
||||
*:Interix*:[3456]*)
|
||||
case ${UNAME_MACHINE} in
|
||||
x86)
|
||||
echo i586-pc-interix${UNAME_RELEASE}
|
||||
exit ;;
|
||||
EM64T | authenticamd)
|
||||
echo x86_64-unknown-interix${UNAME_RELEASE}
|
||||
exit ;;
|
||||
IA64)
|
||||
echo ia64-unknown-interix${UNAME_RELEASE}
|
||||
exit ;;
|
||||
esac ;;
|
||||
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
|
||||
echo i${UNAME_MACHINE}-pc-mks
|
||||
exit ;;
|
||||
@@ -829,7 +836,14 @@ EOF
|
||||
echo ${UNAME_MACHINE}-pc-minix
|
||||
exit ;;
|
||||
arm*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
eval $set_cc_for_build
|
||||
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
|
||||
| grep -q __ARM_EABI__
|
||||
then
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
else
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnueabi
|
||||
fi
|
||||
exit ;;
|
||||
avr32*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
@@ -950,6 +964,9 @@ EOF
|
||||
x86_64:Linux:*:*)
|
||||
echo x86_64-unknown-linux-gnu
|
||||
exit ;;
|
||||
xtensa*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
i*86:Linux:*:*)
|
||||
# The BFD linker knows what the default object file format is, so
|
||||
# first see if it will tell us. cd to the root directory to prevent
|
||||
@@ -1208,6 +1225,15 @@ EOF
|
||||
SX-6:SUPER-UX:*:*)
|
||||
echo sx6-nec-superux${UNAME_RELEASE}
|
||||
exit ;;
|
||||
SX-7:SUPER-UX:*:*)
|
||||
echo sx7-nec-superux${UNAME_RELEASE}
|
||||
exit ;;
|
||||
SX-8:SUPER-UX:*:*)
|
||||
echo sx8-nec-superux${UNAME_RELEASE}
|
||||
exit ;;
|
||||
SX-8R:SUPER-UX:*:*)
|
||||
echo sx8r-nec-superux${UNAME_RELEASE}
|
||||
exit ;;
|
||||
Power*:Rhapsody:*:*)
|
||||
echo powerpc-apple-rhapsody${UNAME_RELEASE}
|
||||
exit ;;
|
||||
@@ -1458,9 +1484,9 @@ This script, last modified $timestamp, has failed to recognize
|
||||
the operating system you are using. It is advised that you
|
||||
download the most up to date version of the config scripts from
|
||||
|
||||
http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
|
||||
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
|
||||
and
|
||||
http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
|
||||
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
|
||||
|
||||
If the version you run ($0) is already up to date, please
|
||||
send the following data and any information you think might be
|
||||
|
||||
66
autoconf/config.sub
vendored
66
autoconf/config.sub
vendored
@@ -1,10 +1,10 @@
|
||||
#! /bin/sh
|
||||
# Configuration validation subroutine script.
|
||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||
# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
|
||||
# Inc.
|
||||
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
|
||||
# Free Software Foundation, Inc.
|
||||
|
||||
timestamp='2006-09-20'
|
||||
timestamp='2008-01-16'
|
||||
|
||||
# This file is (in principle) common to ALL GNU software.
|
||||
# The presence of a machine in this file suggests that SOME GNU software
|
||||
@@ -72,8 +72,8 @@ Report bugs and patches to <config-patches@gnu.org>."
|
||||
version="\
|
||||
GNU config.sub ($timestamp)
|
||||
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||
Free Software Foundation, Inc.
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
|
||||
2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
@@ -245,12 +245,12 @@ case $basic_machine in
|
||||
| bfin \
|
||||
| c4x | clipper \
|
||||
| d10v | d30v | dlx | dsp16xx \
|
||||
| fr30 | frv \
|
||||
| fido | fr30 | frv \
|
||||
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
|
||||
| i370 | i860 | i960 | ia64 \
|
||||
| ip2k | iq2000 \
|
||||
| m32c | m32r | m32rle | m68000 | m68k | m88k \
|
||||
| maxq | mb | microblaze | mcore \
|
||||
| maxq | mb | microblaze | mcore | mep \
|
||||
| mips | mipsbe | mipseb | mipsel | mipsle \
|
||||
| mips16 \
|
||||
| mips64 | mips64el \
|
||||
@@ -324,7 +324,7 @@ case $basic_machine in
|
||||
| clipper-* | craynv-* | cydra-* \
|
||||
| d10v-* | d30v-* | dlx-* \
|
||||
| elxsi-* \
|
||||
| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
|
||||
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
|
||||
| h8300-* | h8500-* \
|
||||
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
|
||||
| i*86-* | i860-* | i960-* | ia64-* \
|
||||
@@ -369,10 +369,14 @@ case $basic_machine in
|
||||
| v850-* | v850e-* | vax-* \
|
||||
| we32k-* \
|
||||
| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
|
||||
| xstormy16-* | xtensa-* \
|
||||
| xstormy16-* | xtensa*-* \
|
||||
| ymp-* \
|
||||
| z8k-*)
|
||||
;;
|
||||
# Recognize the basic CPU types without company name, with glob match.
|
||||
xtensa*)
|
||||
basic_machine=$basic_machine-unknown
|
||||
;;
|
||||
# Recognize the various machine names and aliases which stand
|
||||
# for a CPU type and a company and sometimes even an OS.
|
||||
386bsd)
|
||||
@@ -443,6 +447,14 @@ case $basic_machine in
|
||||
basic_machine=ns32k-sequent
|
||||
os=-dynix
|
||||
;;
|
||||
blackfin)
|
||||
basic_machine=bfin-unknown
|
||||
os=-linux
|
||||
;;
|
||||
blackfin-*)
|
||||
basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
os=-linux
|
||||
;;
|
||||
c90)
|
||||
basic_machine=c90-cray
|
||||
os=-unicos
|
||||
@@ -475,8 +487,8 @@ case $basic_machine in
|
||||
basic_machine=craynv-cray
|
||||
os=-unicosmp
|
||||
;;
|
||||
cr16c)
|
||||
basic_machine=cr16c-unknown
|
||||
cr16)
|
||||
basic_machine=cr16-unknown
|
||||
os=-elf
|
||||
;;
|
||||
crds | unos)
|
||||
@@ -668,6 +680,14 @@ case $basic_machine in
|
||||
basic_machine=m68k-isi
|
||||
os=-sysv
|
||||
;;
|
||||
m68knommu)
|
||||
basic_machine=m68k-unknown
|
||||
os=-linux
|
||||
;;
|
||||
m68knommu-*)
|
||||
basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
os=-linux
|
||||
;;
|
||||
m88k-omron*)
|
||||
basic_machine=m88k-omron
|
||||
;;
|
||||
@@ -683,6 +703,10 @@ case $basic_machine in
|
||||
basic_machine=i386-pc
|
||||
os=-mingw32
|
||||
;;
|
||||
mingw32ce)
|
||||
basic_machine=arm-unknown
|
||||
os=-mingw32ce
|
||||
;;
|
||||
miniframe)
|
||||
basic_machine=m68000-convergent
|
||||
;;
|
||||
@@ -809,6 +833,14 @@ case $basic_machine in
|
||||
basic_machine=i860-intel
|
||||
os=-osf
|
||||
;;
|
||||
parisc)
|
||||
basic_machine=hppa-unknown
|
||||
os=-linux
|
||||
;;
|
||||
parisc-*)
|
||||
basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
os=-linux
|
||||
;;
|
||||
pbd)
|
||||
basic_machine=sparc-tti
|
||||
;;
|
||||
@@ -925,6 +957,9 @@ case $basic_machine in
|
||||
basic_machine=sh-hitachi
|
||||
os=-hms
|
||||
;;
|
||||
sh5el)
|
||||
basic_machine=sh5le-unknown
|
||||
;;
|
||||
sh64)
|
||||
basic_machine=sh64-unknown
|
||||
;;
|
||||
@@ -1014,6 +1049,10 @@ case $basic_machine in
|
||||
basic_machine=tic6x-unknown
|
||||
os=-coff
|
||||
;;
|
||||
tile*)
|
||||
basic_machine=tile-unknown
|
||||
os=-linux-gnu
|
||||
;;
|
||||
tx39)
|
||||
basic_machine=mipstx39-unknown
|
||||
;;
|
||||
@@ -1219,7 +1258,7 @@ case $os in
|
||||
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
|
||||
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
|
||||
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
|
||||
| -skyos* | -haiku* | -rdos* | -toppers*)
|
||||
| -skyos* | -haiku* | -rdos* | -toppers* | -drops*)
|
||||
# Remember, each alternative MUST END IN *, to match a version number.
|
||||
;;
|
||||
-qnx*)
|
||||
@@ -1414,6 +1453,9 @@ case $basic_machine in
|
||||
m68*-cisco)
|
||||
os=-aout
|
||||
;;
|
||||
mep-*)
|
||||
os=-elf
|
||||
;;
|
||||
mips*-cisco)
|
||||
os=-elf
|
||||
;;
|
||||
|
||||
427
configure.in
427
configure.in
@@ -1,8 +1,6 @@
|
||||
##
|
||||
###############################################################################
|
||||
## Copyright (C) 2000-2004 Sistina Software, Inc. All rights reserved.
|
||||
## Copyright (C) 2004, 2007 Red Hat, Inc. All rights reserved.
|
||||
##
|
||||
## This file is part of LVM2.
|
||||
## Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
|
||||
##
|
||||
## This copyrighted material is made available to anyone wishing to use,
|
||||
## modify, copy, or redistribute it subject to the terms and conditions
|
||||
@@ -18,9 +16,7 @@ AC_PREREQ(2.57)
|
||||
dnl -- Process this file with autoconf to produce a configure script.
|
||||
AC_INIT
|
||||
AC_CONFIG_SRCDIR([lib/device/dev-cache.h])
|
||||
|
||||
################################################################################
|
||||
AC_CONFIG_HEADERS(lib/misc/configure.h)
|
||||
AC_CONFIG_HEADERS([lib/misc/configure.h])
|
||||
|
||||
################################################################################
|
||||
dnl -- Setup the directory where autoconf has auxilary files
|
||||
@@ -32,57 +28,64 @@ AC_CANONICAL_TARGET([])
|
||||
|
||||
case "$host_os" in
|
||||
linux*)
|
||||
CFLAGS="$CFLAGS"
|
||||
COPTIMISE_FLAG="-O2"
|
||||
CLDFLAGS="$CLDFLAGS -Wl,--version-script,.export.sym"
|
||||
CLDWHOLEARCHIVE="-Wl,-whole-archive"
|
||||
CLDNOWHOLEARCHIVE="-Wl,-no-whole-archive"
|
||||
LDDEPS="$LDDEPS .export.sym"
|
||||
LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
|
||||
LIB_SUFFIX="so"
|
||||
LIB_SUFFIX=so
|
||||
DEVMAPPER=yes
|
||||
ODIRECT=yes
|
||||
DM_IOCTLS=yes
|
||||
SELINUX=yes
|
||||
REALTIME=yes
|
||||
CLUSTER=internal
|
||||
FSADM=no ;;
|
||||
FSADM=yes
|
||||
;;
|
||||
darwin*)
|
||||
CFLAGS="$CFLAGS -no-cpp-precomp -fno-common"
|
||||
COPTIMISE_FLAG="-O2"
|
||||
CLDFLAGS="$CLDFLAGS"
|
||||
CLDWHOLEARCHIVE="-all_load"
|
||||
CLDNOWHOLEARCHIVE=
|
||||
LDDEPS="$LDDEPS"
|
||||
LDFLAGS="$LDFLAGS"
|
||||
LIB_SUFFIX="dylib"
|
||||
LIB_SUFFIX=dylib
|
||||
DEVMAPPER=yes
|
||||
ODIRECT=no
|
||||
DM_IOCTLS=no
|
||||
SELINUX=no
|
||||
REALTIME=no
|
||||
CLUSTER=none
|
||||
FSADM=no ;;
|
||||
FSADM=no
|
||||
;;
|
||||
esac
|
||||
|
||||
################################################################################
|
||||
dnl -- Checks for programs.
|
||||
AC_PROG_SED
|
||||
AC_PROG_AWK
|
||||
AC_PROG_CC
|
||||
|
||||
dnl probably no longer needed in 2008, but...
|
||||
AC_PROG_GCC_TRADITIONAL
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_LN_S
|
||||
AC_PROG_MAKE_SET
|
||||
AC_PROG_MKDIR_P
|
||||
AC_PROG_RANLIB
|
||||
AC_PATH_PROG(CFLOW_CMD, cflow)
|
||||
AC_PATH_PROG(CSCOPE_CMD, cscope)
|
||||
|
||||
################################################################################
|
||||
dnl -- Checks for header files.
|
||||
dnl -- Check for header files.
|
||||
AC_HEADER_DIRENT
|
||||
AC_HEADER_STDC
|
||||
AC_HEADER_SYS_WAIT
|
||||
AC_HEADER_TIME
|
||||
|
||||
AC_CHECK_HEADERS(fcntl.h limits.h locale.h stddef.h syslog.h sys/file.h sys/ioctl.h sys/param.h sys/time.h,,AC_MSG_ERROR(bailing out))
|
||||
AC_CHECK_HEADERS(assert.h ctype.h libgen.h signal.h stdio.h sys/mman.h sys/resource.h sys/stat.h sys/types.h sys/utsname.h sys/wait.h time.h,,AC_MSG_ERROR(bailing out))
|
||||
AC_CHECK_HEADERS([locale.h stddef.h syslog.h sys/file.h sys/time.h assert.h \
|
||||
libgen.h signal.h sys/mman.h sys/resource.h sys/utsname.h sys/wait.h time.h], ,
|
||||
[AC_MSG_ERROR(bailing out)])
|
||||
|
||||
case "$host_os" in
|
||||
linux*)
|
||||
@@ -91,12 +94,19 @@ case "$host_os" in
|
||||
AC_CHECK_HEADERS(machine/endian.h sys/disk.h,,AC_MSG_ERROR(bailing out)) ;;
|
||||
esac
|
||||
|
||||
AC_CHECK_HEADERS([ctype.h dirent.h errno.h fcntl.h getopt.h inttypes.h limits.h \
|
||||
stdarg.h stdio.h stdlib.h string.h sys/ioctl.h sys/param.h sys/stat.h \
|
||||
sys/types.h unistd.h], , [AC_MSG_ERROR(bailing out)])
|
||||
AC_CHECK_HEADERS(termios.h sys/statvfs.h)
|
||||
|
||||
################################################################################
|
||||
dnl -- Checks for typedefs, structures, and compiler characteristics.
|
||||
dnl -- Check for typedefs, structures, and compiler characteristics.
|
||||
AC_C_CONST
|
||||
AC_C_INLINE
|
||||
AC_CHECK_MEMBERS([struct stat.st_rdev])
|
||||
AC_TYPE_OFF_T
|
||||
AC_TYPE_PID_T
|
||||
AC_TYPE_SIGNAL
|
||||
AC_TYPE_SIZE_T
|
||||
AC_TYPE_MODE_T
|
||||
AC_CHECK_MEMBERS([struct stat.st_rdev])
|
||||
@@ -104,7 +114,9 @@ AC_STRUCT_TM
|
||||
|
||||
################################################################################
|
||||
dnl -- Check for functions
|
||||
AC_CHECK_FUNCS(gethostname getpagesize memset munmap setlocale strcasecmp strchr strdup strncasecmp strerror strrchr strstr strtol strtoul,,AC_MSG_ERROR(bailing out))
|
||||
AC_CHECK_FUNCS([gethostname getpagesize memset mkdir rmdir munmap setlocale \
|
||||
strcasecmp strchr strdup strncasecmp strerror strrchr strstr strtol strtoul \
|
||||
uname], , [AC_MSG_ERROR(bailing out)])
|
||||
AC_FUNC_ALLOCA
|
||||
AC_FUNC_CLOSEDIR_VOID
|
||||
AC_FUNC_FORK
|
||||
@@ -114,22 +126,19 @@ AC_FUNC_MEMCMP
|
||||
AC_FUNC_MMAP
|
||||
AC_FUNC_STAT
|
||||
AC_FUNC_STRTOD
|
||||
AC_FUNC_VPRINTF
|
||||
|
||||
################################################################################
|
||||
dnl -- Prefix is /usr by default, the exec_prefix default is setup later
|
||||
AC_PREFIX_DEFAULT(/usr)
|
||||
|
||||
################################################################################
|
||||
dnl -- Parallel make jobs?
|
||||
AC_ARG_ENABLE(jobs, [ --enable-jobs=NUM Number of jobs to run simultaneously], JOBS=-j$enableval, JOBS=-j2)
|
||||
|
||||
################################################################################
|
||||
dnl -- Setup the ownership of the files
|
||||
AC_MSG_CHECKING(file owner)
|
||||
OWNER="root"
|
||||
|
||||
AC_ARG_WITH(user,
|
||||
[ --with-user=USER Set the owner of installed files ],
|
||||
[ --with-user=USER Set the owner of installed files [[USER=root]] ],
|
||||
[ OWNER="$withval" ])
|
||||
AC_MSG_RESULT($OWNER)
|
||||
|
||||
@@ -142,7 +151,7 @@ dnl -- Setup the group ownership of the files
|
||||
AC_MSG_CHECKING(group owner)
|
||||
GROUP="root"
|
||||
AC_ARG_WITH(group,
|
||||
[ --with-group=GROUP Set the group owner of installed files ],
|
||||
[ --with-group=GROUP Set the group owner of installed files [[GROUP=root]] ],
|
||||
[ GROUP="$withval" ])
|
||||
AC_MSG_RESULT($GROUP)
|
||||
|
||||
@@ -150,6 +159,33 @@ if test x$GROUP != x; then
|
||||
GROUP="-g $GROUP"
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
dnl -- Setup device node ownership
|
||||
AC_MSG_CHECKING(device node uid)
|
||||
|
||||
AC_ARG_WITH(device-uid,
|
||||
[ --with-device-uid=UID Set the owner used for new device nodes [[UID=0]] ],
|
||||
[ DM_DEVICE_UID="$withval" ], [ DM_DEVICE_UID="0" ] )
|
||||
AC_MSG_RESULT($DM_DEVICE_UID)
|
||||
|
||||
################################################################################
|
||||
dnl -- Setup device group ownership
|
||||
AC_MSG_CHECKING(device node gid)
|
||||
|
||||
AC_ARG_WITH(device-gid,
|
||||
[ --with-device-gid=UID Set the group used for new device nodes [[GID=0]] ],
|
||||
[ DM_DEVICE_GID="$withval" ], [ DM_DEVICE_GID="0" ] )
|
||||
AC_MSG_RESULT($DM_DEVICE_GID)
|
||||
|
||||
################################################################################
|
||||
dnl -- Setup device mode
|
||||
AC_MSG_CHECKING(device node mode)
|
||||
|
||||
AC_ARG_WITH(device-mode,
|
||||
[ --with-device-mode=MODE Set the mode used for new device nodes [[MODE=0600]] ],
|
||||
[ DM_DEVICE_MODE="$withval" ], [ DM_DEVICE_MODE="0600" ] )
|
||||
AC_MSG_RESULT($DM_DEVICE_MODE)
|
||||
|
||||
################################################################################
|
||||
dnl -- LVM1 tool fallback option
|
||||
AC_MSG_CHECKING(whether to enable lvm1 fallback)
|
||||
@@ -261,30 +297,13 @@ if test x$MIRRORS = xinternal; then
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
dnl -- Enables staticly-linked tools
|
||||
AC_MSG_CHECKING(whether to use static linking)
|
||||
AC_ARG_ENABLE(static_link, [ --enable-static_link Use this to link the tools to their libraries
|
||||
statically. Default is dynamic linking], STATIC_LINK=$enableval, STATIC_LINK=no)
|
||||
AC_MSG_RESULT($STATIC_LINK)
|
||||
|
||||
################################################################################
|
||||
dnl -- Enable readline
|
||||
dnl -- Disable readline
|
||||
AC_MSG_CHECKING(whether to enable readline)
|
||||
AC_ARG_ENABLE(readline, [ --enable-readline Enable readline support],
|
||||
READLINE=$enableval, READLINE=no)
|
||||
AC_ARG_ENABLE([readline],
|
||||
[ --disable-readline Disable readline support],
|
||||
[READLINE=$enableval], [READLINE=maybe])
|
||||
AC_MSG_RESULT($READLINE)
|
||||
|
||||
if test x$READLINE = xyes; then
|
||||
AC_DEFINE([READLINE_SUPPORT], 1, [Define to 1 to include the LVM readline shell.])
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
dnl -- Disable selinux
|
||||
AC_MSG_CHECKING(whether to enable selinux support)
|
||||
AC_ARG_ENABLE(selinux, [ --disable-selinux Disable selinux support],
|
||||
SELINUX=$enableval)
|
||||
AC_MSG_RESULT($SELINUX)
|
||||
|
||||
################################################################################
|
||||
dnl -- Disable realtime clock support
|
||||
AC_MSG_CHECKING(whether to enable realtime support)
|
||||
@@ -314,7 +333,7 @@ fi
|
||||
dnl -- Enable debugging
|
||||
AC_MSG_CHECKING(whether to enable debugging)
|
||||
AC_ARG_ENABLE(debug, [ --enable-debug Enable debugging],
|
||||
DEBUG=$enableval, DEBUG=no)
|
||||
DEBUG=$enableval, DEBUG=no)
|
||||
AC_MSG_RESULT($DEBUG)
|
||||
|
||||
dnl -- Normally turn off optimisation for debug builds
|
||||
@@ -328,21 +347,48 @@ fi
|
||||
dnl -- Override optimisation
|
||||
AC_MSG_CHECKING(for C optimisation flag)
|
||||
AC_ARG_WITH(optimisation,
|
||||
[ --with-optimisation=OPT C optimisation flag [OPT=-O2] ],
|
||||
[ --with-optimisation=OPT C optimisation flag [[OPT=-O2]] ],
|
||||
[ COPTIMISE_FLAG="$withval" ])
|
||||
AC_MSG_RESULT($COPTIMISE_FLAG)
|
||||
|
||||
################################################################################
|
||||
dnl -- Enable profiling
|
||||
AC_MSG_CHECKING(whether to gather gcov profiling data)
|
||||
AC_ARG_ENABLE(profiling,
|
||||
AC_HELP_STRING(--enable-profiling, [Gather gcov profiling data]),
|
||||
PROFILING=$enableval, PROFILING=no)
|
||||
AC_MSG_RESULT($PROFILING)
|
||||
|
||||
if test "x$PROFILING" = xyes; then
|
||||
COPTIMISE_FLAG="$COPTIMISE_FLAG -fprofile-arcs -ftest-coverage"
|
||||
AC_PATH_PROG(LCOV, lcov, no)
|
||||
AC_PATH_PROG(GENHTML, genhtml, no)
|
||||
if test "$LCOV" = no -o "$GENHTML" = no ; then
|
||||
AC_MSG_ERROR([lcov and genhtml are required for profiling])
|
||||
fi
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
dnl -- Disable devmapper
|
||||
AC_MSG_CHECKING(whether to use device-mapper)
|
||||
AC_ARG_ENABLE(devmapper, [ --disable-devmapper Disable device-mapper interaction],
|
||||
AC_ARG_ENABLE(devmapper, [ --disable-devmapper Disable LVM2 device-mapper interaction],
|
||||
DEVMAPPER=$enableval)
|
||||
AC_MSG_RESULT($DEVMAPPER)
|
||||
|
||||
if test x$DEVMAPPER = xyes; then
|
||||
AC_DEFINE([DEVMAPPER_SUPPORT], 1, [Define to 1 to enable device-mapper interaction.])
|
||||
AC_DEFINE([DEVMAPPER_SUPPORT], 1, [Define to 1 to enable LVM2 device-mapper interaction.])
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
dnl -- Compatibility mode
|
||||
AC_ARG_ENABLE(compat, [ --enable-compat Enable support for old device-mapper versions],
|
||||
DM_COMPAT=$enableval, DM_COMPAT=no)
|
||||
|
||||
################################################################################
|
||||
dnl -- Disable ioctl
|
||||
AC_ARG_ENABLE(ioctl, [ --disable-driver Disable calls to device-mapper in the kernel],
|
||||
DM_IOCTLS=$enableval)
|
||||
|
||||
################################################################################
|
||||
dnl -- Disable O_DIRECT
|
||||
AC_MSG_CHECKING(whether to enable O_DIRECT)
|
||||
@@ -360,10 +406,19 @@ AC_MSG_CHECKING(whether to compile liblvm2cmd.so)
|
||||
AC_ARG_ENABLE(cmdlib, [ --enable-cmdlib Build shared command library],
|
||||
CMDLIB=$enableval, CMDLIB=no)
|
||||
AC_MSG_RESULT($CMDLIB)
|
||||
AC_SUBST([LVM2CMD_LIB])
|
||||
test x$CMDLIB = xyes \
|
||||
&& LVM2CMD_LIB=-llvm2cmd \
|
||||
|| LVM2CMD_LIB=
|
||||
|
||||
################################################################################
|
||||
dnl -- Enable pkg-config
|
||||
AC_ARG_ENABLE(pkgconfig, [ --enable-pkgconfig Install pkgconfig support],
|
||||
PKGCONFIG=$enableval, PKGCONFIG=no)
|
||||
|
||||
################################################################################
|
||||
dnl -- Enable fsadm
|
||||
AC_MSG_CHECKING(whether to build fsadm)
|
||||
AC_MSG_CHECKING(whether to install fsadm)
|
||||
AC_ARG_ENABLE(fsadm, [ --enable-fsadm Enable fsadm],
|
||||
FSADM=$enableval)
|
||||
AC_MSG_RESULT($FSADM)
|
||||
@@ -375,34 +430,52 @@ AC_ARG_ENABLE(dmeventd, [ --enable-dmeventd Enable the device-mapper even
|
||||
DMEVENTD=$enableval)
|
||||
AC_MSG_RESULT($DMEVENTD)
|
||||
|
||||
BUILD_DMEVENTD=$DMEVENTD
|
||||
|
||||
dnl -- dmeventd currently requires internal mirror support
|
||||
if test x$DMEVENTD = xyes && test x$MIRRORS != xinternal; then
|
||||
AC_MSG_ERROR(
|
||||
--enable-dmeventd currently requires --with-mirrors=internal
|
||||
)
|
||||
if test x$DMEVENTD = xyes; then
|
||||
if test x$MIRRORS != xinternal; then
|
||||
AC_MSG_ERROR(
|
||||
--enable-dmeventd currently requires --with-mirrors=internal
|
||||
)
|
||||
fi
|
||||
if test x$CMDLIB = xno; then
|
||||
AC_MSG_ERROR(
|
||||
--enable-dmeventd requires --enable-cmdlib to be used as well
|
||||
)
|
||||
fi
|
||||
fi
|
||||
|
||||
if test x$DMEVENTD = xyes; then
|
||||
AC_DEFINE([DMEVENTD], 1, [Define to 1 to enable the device-mapper event daemon.])
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
dnl -- Mess with default exec_prefix
|
||||
dnl -- getline included in recent libc
|
||||
|
||||
AC_CHECK_LIB(c, getline, AC_DEFINE([HAVE_GETLINE], 1,
|
||||
[Define to 1 if getline is available.]))
|
||||
|
||||
################################################################################
|
||||
dnl -- canonicalize_file_name included in recent libc
|
||||
|
||||
AC_CHECK_LIB(c, canonicalize_file_name,
|
||||
AC_DEFINE([HAVE_CANONICALIZE_FILE_NAME], 1,
|
||||
[Define to 1 if canonicalize_file_name is available.]))
|
||||
|
||||
################################################################################
|
||||
dnl -- Clear default exec_prefix - install into /sbin rather than /usr/sbin
|
||||
if [[ "x$exec_prefix" = xNONE -a "x$prefix" = xNONE ]];
|
||||
then exec_prefix="";
|
||||
fi;
|
||||
|
||||
################################################################################
|
||||
dnl -- Checks for library functions.
|
||||
AC_PROG_GCC_TRADITIONAL
|
||||
AC_TYPE_SIGNAL
|
||||
AC_FUNC_VPRINTF
|
||||
AC_CHECK_FUNCS(mkdir rmdir uname,,AC_MSG_ERROR(bailing out))
|
||||
|
||||
################################################################################
|
||||
dnl -- Check for termcap (Shamelessly copied from parted 1.4.17)
|
||||
if test x$READLINE = xyes; then
|
||||
AC_SEARCH_LIBS(tgetent, ncurses curses termcap termlib, ,
|
||||
AC_MSG_ERROR(
|
||||
if test x$READLINE != xno; then
|
||||
AC_SEARCH_LIBS([tgetent], [ncurses curses termcap termlib],
|
||||
[tg_found=yes], [tg_found=no])
|
||||
test x$READLINE:$tg_found = xyes:no &&
|
||||
AC_MSG_ERROR(
|
||||
termcap could not be found which is required for the
|
||||
--enable-readline option (which is enabled by default). Either disable readline
|
||||
support with --disable-readline or download and install termcap from:
|
||||
@@ -412,7 +485,6 @@ Note: if you are using precompiled packages you will also need the development
|
||||
Note: (n)curses also seems to work as a substitute for termcap. This was
|
||||
not found either - but you could try installing that as well.
|
||||
)
|
||||
)
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
@@ -436,12 +508,30 @@ Features cannot be 'shared' when building statically
|
||||
)
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
dnl -- Enables statically-linked tools
|
||||
AC_MSG_CHECKING(whether to use static linking)
|
||||
AC_ARG_ENABLE(static_link,
|
||||
[ --enable-static_link Use this to link the tools to their libraries
|
||||
statically. Default is dynamic linking],
|
||||
STATIC_LINK=$enableval, STATIC_LINK=no)
|
||||
AC_MSG_RESULT($STATIC_LINK)
|
||||
|
||||
################################################################################
|
||||
dnl -- Disable selinux
|
||||
AC_MSG_CHECKING(whether to enable selinux support)
|
||||
AC_ARG_ENABLE(selinux, [ --disable-selinux Disable selinux support],
|
||||
SELINUX=$enableval)
|
||||
AC_MSG_RESULT($SELINUX)
|
||||
|
||||
################################################################################
|
||||
dnl -- Check for selinux
|
||||
if test x$SELINUX = xyes; then
|
||||
AC_CHECK_LIB(sepol, sepol_check_context, HAVE_SEPOL=yes, HAVE_SEPOL=no)
|
||||
|
||||
if test x$HAVE_SEPOL = xyes; then
|
||||
AC_DEFINE([HAVE_SEPOL], 1,
|
||||
[Define to 1 if sepol_check_context is available.])
|
||||
LIBS="-lsepol $LIBS"
|
||||
fi
|
||||
|
||||
@@ -454,7 +544,7 @@ if test x$SELINUX = xyes; then
|
||||
AC_MSG_WARN(Disabling selinux)
|
||||
fi
|
||||
|
||||
# With --enable-static_link and selinux enabled, linking lvm.static
|
||||
# With --enable-static_link and selinux enabled, linking
|
||||
# fails on at least Debian unstable due to unsatisfied references
|
||||
# to pthread_mutex_lock and _unlock. See if we need -lpthread.
|
||||
if test "$STATIC_LINK-$HAVE_SELINUX" = yes-yes; then
|
||||
@@ -482,13 +572,15 @@ fi
|
||||
|
||||
################################################################################
|
||||
dnl -- Check for getopt
|
||||
AC_CHECK_HEADERS(getopt.h, AC_DEFINE([HAVE_GETOPTLONG], 1, [Define to 1 to if getopt_long is available.]))
|
||||
AC_CHECK_HEADERS(getopt.h, AC_DEFINE([HAVE_GETOPTLONG], 1, [Define to 1 if getopt_long is available.]))
|
||||
|
||||
################################################################################
|
||||
dnl -- Check for readline (Shamelessly copied from parted 1.4.17)
|
||||
if test x$READLINE = xyes; then
|
||||
AC_CHECK_LIB(readline, readline, ,
|
||||
AC_MSG_ERROR(
|
||||
if test x$READLINE != xno; then
|
||||
rl_found=yes
|
||||
AC_CHECK_LIB([readline], [readline], , [rl_found=no])
|
||||
test x$READLINE:$rl_found = xyes:no &&
|
||||
AC_MSG_ERROR(
|
||||
GNU Readline could not be found which is required for the
|
||||
--enable-readline option (which is enabled by default). Either disable readline
|
||||
support with --disable-readline or download and install readline from:
|
||||
@@ -496,8 +588,11 @@ support with --disable-readline or download and install readline from:
|
||||
Note: if you are using precompiled packages you will also need the development
|
||||
package as well (which may be called readline-devel or something similar).
|
||||
)
|
||||
)
|
||||
AC_CHECK_FUNC(rl_completion_matches, AC_DEFINE([HAVE_RL_COMPLETION_MATCHES], 1, [Define to 1 if rl_completion_matches() is available.]))
|
||||
if test $rl_found = yes; then
|
||||
AC_CHECK_FUNCS([rl_completion_matches])
|
||||
AC_DEFINE([READLINE_SUPPORT], 1,
|
||||
[Define to 1 to include the LVM readline shell.])
|
||||
fi
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
@@ -508,6 +603,7 @@ AC_ARG_ENABLE(nls, [ --enable-nls Enable Native Language Support],
|
||||
AC_MSG_RESULT($INTL)
|
||||
|
||||
if test x$INTL = xyes; then
|
||||
# FIXME - Move this - can be device-mapper too
|
||||
INTL_PACKAGE="lvm2"
|
||||
AC_PATH_PROG(MSGFMT, msgfmt)
|
||||
if [[ "x$MSGFMT" == x ]];
|
||||
@@ -517,32 +613,31 @@ if test x$INTL = xyes; then
|
||||
fi;
|
||||
|
||||
AC_ARG_WITH(localedir,
|
||||
[ --with-localedir=DIR Translation files in DIR [PREFIX/share/locale]],
|
||||
[ LOCALEDIR="$withval" ],
|
||||
[ LOCALEDIR='${prefix}/share/locale' ])
|
||||
[ --with-localedir=DIR Translation files in DIR [[PREFIX/share/locale]] ],
|
||||
[ LOCALEDIR="$withval" ],
|
||||
[ LOCALEDIR='${prefix}/share/locale' ])
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
AC_ARG_WITH(confdir,
|
||||
[ --with-confdir=DIR Configuration files in DIR [/etc]],
|
||||
[ CONFDIR="$withval" ],
|
||||
[ CONFDIR='/etc' ])
|
||||
[ CONFDIR="$withval" ],
|
||||
[ CONFDIR='/etc' ])
|
||||
|
||||
AC_ARG_WITH(staticdir,
|
||||
[ --with-staticdir=DIR Static binary in DIR [EXEC_PREFIX/sbin]],
|
||||
[ STATICDIR="$withval" ],
|
||||
[ STATICDIR='${exec_prefix}/sbin' ])
|
||||
[ STATICDIR="$withval" ],
|
||||
[ STATICDIR='${exec_prefix}/sbin' ])
|
||||
|
||||
AC_ARG_WITH(dmdir,
|
||||
[ --with-dmdir=DIR Build against device-mapper source tree in DIR],
|
||||
[ DMDIR="$withval" CPPFLAGS="$CPPFLAGS -I$DMDIR/include"],
|
||||
[ DMDIR= ])
|
||||
AC_ARG_WITH(usrlibdir,
|
||||
[ --with-usrlibdir=DIR],
|
||||
[ usrlibdir="$withval"],
|
||||
[ usrlibdir='${prefix}/lib' ])
|
||||
|
||||
# Convert a relative dir name to absolute.
|
||||
case $DMDIR in
|
||||
/*) ;;
|
||||
*) DMDIR="`pwd`/$DMDIR" ;;
|
||||
esac
|
||||
AC_ARG_WITH(usrsbindir,
|
||||
[ --with-usrsbindir=DIR],
|
||||
[ usrsbindir="$withval"],
|
||||
[ usrsbindir='${prefix}/sbin' ])
|
||||
|
||||
################################################################################
|
||||
dnl -- Ensure additional headers required
|
||||
@@ -558,11 +653,6 @@ if test x$CLVMD != xnone; then
|
||||
AC_FUNC_SELECT_ARGTYPES
|
||||
fi
|
||||
|
||||
if test x$FSADM = xyes; then
|
||||
AC_CHECK_HEADERS(fstab.h sys/mount.h sys/vfs.h,,AC_MSG_ERROR(bailing out))
|
||||
AC_CHECK_FUNCS(memmove,,AC_MSG_ERROR(bailing out))
|
||||
fi
|
||||
|
||||
if test x$CLUSTER != xnone; then
|
||||
AC_CHECK_HEADERS(sys/socket.h sys/un.h,,AC_MSG_ERROR(bailing out))
|
||||
AC_CHECK_FUNCS(socket,,AC_MSG_ERROR(bailing out))
|
||||
@@ -576,8 +666,6 @@ if test x$INTL = xyes; then
|
||||
AC_CHECK_HEADERS(libintl.h,,AC_MSG_ERROR(bailing out))
|
||||
fi
|
||||
|
||||
AC_CHECK_HEADERS(libdevmapper.h,,AC_MSG_ERROR(bailing out))
|
||||
|
||||
if test x$HAVE_SELINUX = xyes; then
|
||||
AC_CHECK_HEADERS(selinux/selinux.h,,AC_MSG_ERROR(bailing out))
|
||||
fi
|
||||
@@ -590,52 +678,105 @@ if test x$MODPROBE_CMD != x; then
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
if test "-f VERSION"; then
|
||||
LVM_VERSION="\"`cat VERSION`\""
|
||||
else
|
||||
LVM_VERSION="Unknown"
|
||||
dnl -- dmeventd pidfile and executable path
|
||||
AH_TEMPLATE(DMEVENTD_PIDFILE, [Path to dmeventd pidfile.])
|
||||
if test "$BUILD_DMEVENTD" = yes; then
|
||||
AC_ARG_WITH(dmeventd-pidfile,
|
||||
[ --with-dmeventd-pidfile=PATH dmeventd pidfile [[/var/run/dmeventd.pid]] ],
|
||||
[ AC_DEFINE_UNQUOTED(DMEVENTD_PIDFILE,"$withval") ],
|
||||
[ AC_DEFINE_UNQUOTED(DMEVENTD_PIDFILE,"/var/run/dmeventd.pid") ])
|
||||
fi
|
||||
|
||||
AH_TEMPLATE(DMEVENTD_PATH, [Path to dmeventd binary.])
|
||||
if test "$BUILD_DMEVENTD" = yes; then
|
||||
dmeventd_prefix="$exec_prefix"
|
||||
if test "x$dmeventd_prefix" = "xNONE"; then
|
||||
dmeventd_prefix="$prefix"
|
||||
fi
|
||||
if test "x$dmeventd_prefix" = "xNONE"; then
|
||||
dmeventd_prefix=""
|
||||
fi
|
||||
AC_ARG_WITH(dmeventd-path,
|
||||
[ --with-dmeventd-path=PATH dmeventd path [[${exec_prefix}/sbin/dmeventd]] ],
|
||||
[ AC_DEFINE_UNQUOTED(DMEVENTD_PATH,"$withval") ],
|
||||
[ AC_DEFINE_UNQUOTED(DMEVENTD_PATH,"$dmeventd_prefix/sbin/dmeventd") ])
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
AC_SUBST(JOBS)
|
||||
AC_SUBST(STATIC_LINK)
|
||||
AC_SUBST(LVM1)
|
||||
AC_SUBST(POOL)
|
||||
AC_SUBST(SNAPSHOTS)
|
||||
AC_SUBST(MIRRORS)
|
||||
AC_SUBST(OWNER)
|
||||
AC_SUBST(GROUP)
|
||||
dnl -- which kernel interface to use (ioctl only)
|
||||
AC_MSG_CHECKING(for kernel interface choice)
|
||||
AC_ARG_WITH(interface,
|
||||
[ --with-interface=IFACE Choose kernel interface (ioctl) [[ioctl]] ],
|
||||
[ interface="$withval" ],
|
||||
[ interface=ioctl ])
|
||||
if [[ "x$interface" != xioctl ]];
|
||||
then
|
||||
AC_MSG_ERROR(--with-interface=ioctl required. fs no longer supported.)
|
||||
fi
|
||||
AC_MSG_RESULT($interface)
|
||||
|
||||
################################################################################
|
||||
DM_LIB_VERSION="\"`cat VERSION_DM 2>/dev/null || echo Unknown`\""
|
||||
AC_DEFINE_UNQUOTED(DM_LIB_VERSION, $DM_LIB_VERSION, [Library version])
|
||||
|
||||
DM_LIB_PATCHLEVEL=`cat VERSION_DM | awk -F '[[-. ]]' '{printf "%s.%s.%s",$1,$2,$3}'`
|
||||
|
||||
LVM_VERSION="\"`cat VERSION 2>/dev/null || echo Unknown`\""
|
||||
|
||||
################################################################################
|
||||
AC_SUBST(BUILD_DMEVENTD)
|
||||
AC_SUBST(CFLAGS)
|
||||
AC_SUBST(COPTIMISE_FLAG)
|
||||
AC_SUBST(CFLOW_CMD)
|
||||
AC_SUBST(CLDFLAGS)
|
||||
AC_SUBST(CLDWHOLEARCHIVE)
|
||||
AC_SUBST(CLDNOWHOLEARCHIVE)
|
||||
AC_SUBST(LDDEPS)
|
||||
AC_SUBST(LDFLAGS)
|
||||
AC_SUBST(LIB_SUFFIX)
|
||||
AC_SUBST(LIBS)
|
||||
AC_SUBST(LVM_VERSION)
|
||||
AC_SUBST(LVM1_FALLBACK)
|
||||
AC_SUBST(CLDWHOLEARCHIVE)
|
||||
AC_SUBST(CLUSTER)
|
||||
AC_SUBST(CLVMD)
|
||||
AC_SUBST(CMDLIB)
|
||||
AC_SUBST(COPTIMISE_FLAG)
|
||||
AC_SUBST(CSCOPE_CMD)
|
||||
AC_SUBST(DEBUG)
|
||||
AC_SUBST(DEVMAPPER)
|
||||
AC_SUBST(HAVE_LIBDL)
|
||||
AC_SUBST(HAVE_SELINUX)
|
||||
AC_SUBST(HAVE_REALTIME)
|
||||
AC_SUBST(CMDLIB)
|
||||
AC_SUBST(MSGFMT)
|
||||
AC_SUBST(LOCALEDIR)
|
||||
AC_SUBST(CONFDIR)
|
||||
AC_SUBST(STATICDIR)
|
||||
AC_SUBST(DMDIR)
|
||||
AC_SUBST(INTL_PACKAGE)
|
||||
AC_SUBST(INTL)
|
||||
AC_SUBST(CLVMD)
|
||||
AC_SUBST(CLUSTER)
|
||||
AC_SUBST(FSADM)
|
||||
AC_SUBST(DMEVENTD)
|
||||
AC_SUBST(CFLOW_CMD)
|
||||
AC_SUBST(CSCOPE_CMD)
|
||||
AC_SUBST(DM_COMPAT)
|
||||
AC_SUBST(DM_DEVICE_GID)
|
||||
AC_SUBST(DM_DEVICE_MODE)
|
||||
AC_SUBST(DM_DEVICE_UID)
|
||||
AC_SUBST(DM_IOCTLS)
|
||||
AC_SUBST(DM_LIB_VERSION)
|
||||
AC_SUBST(DM_LIB_PATCHLEVEL)
|
||||
AC_SUBST(FSADM)
|
||||
AC_SUBST(GROUP)
|
||||
AC_SUBST(HAVE_LIBDL)
|
||||
AC_SUBST(HAVE_REALTIME)
|
||||
AC_SUBST(HAVE_SELINUX)
|
||||
AC_SUBST(INTL)
|
||||
AC_SUBST(INTL_PACKAGE)
|
||||
AC_SUBST(JOBS)
|
||||
AC_SUBST(LDDEPS)
|
||||
AC_SUBST(LIBS)
|
||||
AC_SUBST(LIB_SUFFIX)
|
||||
AC_SUBST(LOCALEDIR)
|
||||
AC_SUBST(LVM1)
|
||||
AC_SUBST(LVM1_FALLBACK)
|
||||
AC_SUBST(CONFDIR)
|
||||
AC_SUBST(LVM_VERSION)
|
||||
AC_SUBST(MIRRORS)
|
||||
AC_SUBST(MSGFMT)
|
||||
AC_SUBST(OWNER)
|
||||
AC_SUBST(PKGCONFIG)
|
||||
AC_SUBST(POOL)
|
||||
AC_SUBST(SNAPSHOTS)
|
||||
AC_SUBST(STATICDIR)
|
||||
AC_SUBST(STATIC_LINK)
|
||||
AC_SUBST([LIB_PTHREAD])
|
||||
AC_SUBST(interface)
|
||||
AC_SUBST(kerneldir)
|
||||
AC_SUBST(missingkernel)
|
||||
AC_SUBST(kernelvsn)
|
||||
AC_SUBST(tmpdir)
|
||||
AC_SUBST(usrlibdir)
|
||||
AC_SUBST(usrsbindir)
|
||||
|
||||
################################################################################
|
||||
dnl -- First and last lines should not contain files to generate in order to
|
||||
@@ -645,8 +786,11 @@ Makefile
|
||||
make.tmpl
|
||||
daemons/Makefile
|
||||
daemons/clvmd/Makefile
|
||||
dmeventd/Makefile
|
||||
dmeventd/mirror/Makefile
|
||||
daemons/dmeventd/Makefile
|
||||
daemons/dmeventd/libdevmapper-event.pc
|
||||
daemons/dmeventd/plugins/Makefile
|
||||
daemons/dmeventd/plugins/mirror/Makefile
|
||||
daemons/dmeventd/plugins/snapshot/Makefile
|
||||
doc/Makefile
|
||||
include/Makefile
|
||||
lib/Makefile
|
||||
@@ -655,24 +799,17 @@ lib/format_pool/Makefile
|
||||
lib/locking/Makefile
|
||||
lib/mirror/Makefile
|
||||
lib/snapshot/Makefile
|
||||
test/Makefile
|
||||
libdm/Makefile
|
||||
libdm/libdevmapper.pc
|
||||
man/Makefile
|
||||
po/Makefile
|
||||
scripts/Makefile
|
||||
test/Makefile
|
||||
tools/Makefile
|
||||
tools/version.h
|
||||
tools/fsadm/Makefile
|
||||
])
|
||||
AC_OUTPUT
|
||||
|
||||
if test x$ODIRECT != xyes; then
|
||||
AC_MSG_WARN(Warning: O_DIRECT disabled: low-memory pvmove may lock up)
|
||||
fi
|
||||
|
||||
if test x$FSADM == xyes; then
|
||||
AC_MSG_WARN(fsadm support is untested)
|
||||
fi
|
||||
|
||||
if test x$DMEVENTD == xyes; then
|
||||
AC_MSG_WARN(dmeventd support is untested)
|
||||
fi
|
||||
|
||||
@@ -15,9 +15,18 @@ srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
.PHONY: dmeventd clvmd
|
||||
|
||||
ifneq ("@CLVMD@", "none")
|
||||
SUBDIRS = clvmd
|
||||
endif
|
||||
|
||||
ifeq ("@DMEVENTD@", "yes")
|
||||
SUBDIRS += dmeventd
|
||||
endif
|
||||
|
||||
include $(top_srcdir)/make.tmpl
|
||||
|
||||
ifeq ("@DMEVENTD@", "yes")
|
||||
device-mapper: dmeventd.device-mapper
|
||||
endif
|
||||
|
||||
@@ -90,7 +90,7 @@ clvmd: $(OBJECTS) $(top_srcdir)/lib/liblvm.a
|
||||
|
||||
install_clvmd: $(TARGETS)
|
||||
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) clvmd \
|
||||
$(sbindir)/clvmd
|
||||
$(usrsbindir)/clvmd
|
||||
|
||||
install: $(INSTALL_TARGETS)
|
||||
|
||||
|
||||
@@ -17,6 +17,10 @@
|
||||
* CMAN communication layer for clvmd.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
|
||||
#include <configure.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -36,23 +40,28 @@
|
||||
#include <fcntl.h>
|
||||
#include <getopt.h>
|
||||
#include <errno.h>
|
||||
#include <libdevmapper.h>
|
||||
#include <libdlm.h>
|
||||
|
||||
#include "clvmd-comms.h"
|
||||
#include "clvm.h"
|
||||
#include "log.h"
|
||||
#include "lvm-logging.h"
|
||||
#include "clvmd.h"
|
||||
#include "lvm-functions.h"
|
||||
|
||||
#define LOCKSPACE_NAME "clvmd"
|
||||
|
||||
struct clvmd_node
|
||||
{
|
||||
struct cman_node *node;
|
||||
int clvmd_up;
|
||||
};
|
||||
|
||||
static int num_nodes;
|
||||
static struct cman_node *nodes = NULL;
|
||||
static struct cman_node this_node;
|
||||
static int count_nodes; /* size of allocated nodes array */
|
||||
static int max_updown_nodes = 50; /* Current size of the allocated array */
|
||||
/* Node up/down status, indexed by nodeid */
|
||||
static int *node_updown = NULL;
|
||||
static struct dm_hash_table *node_updown_hash;
|
||||
static dlm_lshandle_t *lockspace;
|
||||
static cman_handle_t c_handle;
|
||||
|
||||
@@ -72,6 +81,8 @@ struct lock_wait {
|
||||
|
||||
static int _init_cluster(void)
|
||||
{
|
||||
node_updown_hash = dm_hash_create(100);
|
||||
|
||||
/* Open the cluster communication socket */
|
||||
c_handle = cman_init(NULL);
|
||||
if (!c_handle) {
|
||||
@@ -165,8 +176,10 @@ static int _cluster_do_node_callback(struct local_client *client,
|
||||
|
||||
for (i = 0; i < _get_num_nodes(); i++) {
|
||||
if (nodes[i].cn_member && nodes[i].cn_nodeid) {
|
||||
callback(client, (char *)&nodes[i].cn_nodeid, node_updown[nodes[i].cn_nodeid]);
|
||||
if (!node_updown[nodes[i].cn_nodeid])
|
||||
int up = (int)(long)dm_hash_lookup_binary(node_updown_hash, (char *)&nodes[i].cn_nodeid, sizeof(int));
|
||||
|
||||
callback(client, (char *)&nodes[i].cn_nodeid, up);
|
||||
if (!up)
|
||||
somedown = -1;
|
||||
}
|
||||
}
|
||||
@@ -184,7 +197,7 @@ static void event_callback(cman_handle_t handle, void *private, int reason, int
|
||||
log_notice("clvmd on node %s has died\n", namebuf);
|
||||
DEBUGLOG("Got port closed message, removing node %s\n", namebuf);
|
||||
|
||||
node_updown[arg] = 0;
|
||||
dm_hash_insert_binary(node_updown_hash, (char *)&arg, sizeof(int), (void *)0);
|
||||
break;
|
||||
|
||||
case CMAN_REASON_STATECHANGE:
|
||||
@@ -239,22 +252,7 @@ static void _add_up_node(const char *csid)
|
||||
/* It's up ! */
|
||||
int nodeid = nodeid_from_csid(csid);
|
||||
|
||||
if (nodeid >= max_updown_nodes) {
|
||||
int new_size = nodeid + 10;
|
||||
int *new_updown = realloc(node_updown, new_size);
|
||||
|
||||
if (new_updown) {
|
||||
node_updown = new_updown;
|
||||
max_updown_nodes = new_size;
|
||||
DEBUGLOG("realloced more space for nodes. now %d\n",
|
||||
max_updown_nodes);
|
||||
} else {
|
||||
log_error
|
||||
("Realloc failed. Node status for clvmd will be wrong. quitting\n");
|
||||
exit(999);
|
||||
}
|
||||
}
|
||||
node_updown[nodeid] = 1;
|
||||
dm_hash_insert_binary(node_updown_hash, (char *)&nodeid, sizeof(int), (void *)1);
|
||||
DEBUGLOG("Added new node %d to updown list\n", nodeid);
|
||||
}
|
||||
|
||||
@@ -288,7 +286,12 @@ static void count_clvmds_running(void)
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num_nodes; i++) {
|
||||
node_updown[nodes[i].cn_nodeid] = is_listening(nodes[i].cn_nodeid);
|
||||
int nodeid = nodes[i].cn_nodeid;
|
||||
|
||||
if (is_listening(nodeid) == 1)
|
||||
dm_hash_insert_binary(node_updown_hash, (void *)&nodeid, sizeof(int), (void*)1);
|
||||
else
|
||||
dm_hash_insert_binary(node_updown_hash, (void *)&nodeid, sizeof(int), (void*)0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,6 +300,8 @@ static void get_members()
|
||||
{
|
||||
int retnodes;
|
||||
int status;
|
||||
int i;
|
||||
int high_nodeid = 0;
|
||||
|
||||
num_nodes = cman_get_node_count(c_handle);
|
||||
if (num_nodes == -1) {
|
||||
@@ -325,11 +330,10 @@ static void get_members()
|
||||
exit(6);
|
||||
}
|
||||
|
||||
if (node_updown == NULL) {
|
||||
size_t buf_len = sizeof(int) * max(num_nodes, max_updown_nodes);
|
||||
node_updown = malloc(buf_len);
|
||||
if (node_updown)
|
||||
memset(node_updown, 0, buf_len);
|
||||
/* Get the highest nodeid */
|
||||
for (i=0; i<retnodes; i++) {
|
||||
if (nodes[i].cn_nodeid > high_nodeid)
|
||||
high_nodeid = nodes[i].cn_nodeid;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -50,6 +50,10 @@
|
||||
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
|
||||
#include <configure.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/utsname.h>
|
||||
@@ -67,9 +71,8 @@
|
||||
#include <libdevmapper.h>
|
||||
#include <libdlm.h>
|
||||
|
||||
#include "list.h"
|
||||
#include "locking.h"
|
||||
#include "log.h"
|
||||
#include "lvm-logging.h"
|
||||
#include "lvm-functions.h"
|
||||
#include "clvmd-comms.h"
|
||||
#include "clvm.h"
|
||||
@@ -118,9 +121,11 @@ int do_command(struct local_client *client, struct clvm_header *msg, int msglen,
|
||||
lockname = &args[2];
|
||||
/* Check to see if the VG is in use by LVM1 */
|
||||
status = do_check_lvm1(lockname);
|
||||
/* P_global causes a cache refresh */
|
||||
if (strcmp(lockname, "P_global") == 0)
|
||||
do_refresh_cache();
|
||||
/* P_#global causes a full cache refresh */
|
||||
if (!strcmp(lockname, "P_" VG_GLOBAL))
|
||||
do_refresh_cache();
|
||||
else
|
||||
drop_metadata(lockname + 2);
|
||||
|
||||
break;
|
||||
|
||||
@@ -251,7 +256,11 @@ int do_pre_command(struct local_client *client)
|
||||
break;
|
||||
|
||||
case CLVMD_CMD_LOCK_VG:
|
||||
status = lock_vg(client);
|
||||
lockname = &args[2];
|
||||
/* We take out a real lock unless LCK_CACHE was set */
|
||||
if (!strncmp(lockname, "V_", 2) ||
|
||||
!strncmp(lockname, "P_#", 3))
|
||||
status = lock_vg(client);
|
||||
break;
|
||||
|
||||
case CLVMD_CMD_LOCK_LV:
|
||||
|
||||
@@ -44,9 +44,8 @@
|
||||
#include <ccs.h>
|
||||
#include <libgulm.h>
|
||||
|
||||
#include "list.h"
|
||||
#include "locking.h"
|
||||
#include "log.h"
|
||||
#include "lvm-logging.h"
|
||||
#include "clvm.h"
|
||||
#include "clvmd-comms.h"
|
||||
#include "lvm-functions.h"
|
||||
@@ -665,6 +664,7 @@ static int _cluster_do_node_callback(struct local_client *master_client,
|
||||
{
|
||||
struct dm_hash_node *hn;
|
||||
struct node_info *ninfo;
|
||||
int somedown = 0;
|
||||
|
||||
dm_hash_iterate(hn, node_hash)
|
||||
{
|
||||
@@ -686,12 +686,14 @@ static int _cluster_do_node_callback(struct local_client *master_client,
|
||||
client = dm_hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
|
||||
|
||||
}
|
||||
DEBUGLOG("down_callback2. node %s, state = %d\n", ninfo->name, ninfo->state);
|
||||
if (ninfo->state != NODE_DOWN)
|
||||
callback(master_client, csid, ninfo->state == NODE_CLVMD);
|
||||
|
||||
|
||||
if (ninfo->state != NODE_CLVMD)
|
||||
somedown = -1;
|
||||
}
|
||||
return 0;
|
||||
return somedown;
|
||||
}
|
||||
|
||||
/* Convert gulm error codes to unix errno numbers */
|
||||
|
||||
@@ -11,6 +11,10 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
|
||||
#include <configure.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/utsname.h>
|
||||
@@ -39,9 +43,8 @@
|
||||
#include <openais/saLck.h>
|
||||
#include <openais/cpg.h>
|
||||
|
||||
#include "list.h"
|
||||
#include "locking.h"
|
||||
#include "log.h"
|
||||
#include "lvm-logging.h"
|
||||
#include "clvm.h"
|
||||
#include "clvmd-comms.h"
|
||||
#include "lvm-functions.h"
|
||||
@@ -50,11 +53,6 @@
|
||||
/* Timeout value for several openais calls */
|
||||
#define TIMEOUT 10
|
||||
|
||||
static void lck_lock_callback(SaInvocationT invocation,
|
||||
SaLckLockStatusT lockStatus,
|
||||
SaAisErrorT error);
|
||||
static void lck_unlock_callback(SaInvocationT invocation,
|
||||
SaAisErrorT error);
|
||||
static void cpg_deliver_callback (cpg_handle_t handle,
|
||||
struct cpg_name *groupName,
|
||||
uint32_t nodeid,
|
||||
@@ -92,11 +90,6 @@ cpg_callbacks_t cpg_callbacks = {
|
||||
.cpg_confchg_fn = cpg_confchg_callback,
|
||||
};
|
||||
|
||||
SaLckCallbacksT lck_callbacks = {
|
||||
.saLckLockGrantCallback = lck_lock_callback,
|
||||
.saLckResourceUnlockCallback = lck_unlock_callback
|
||||
};
|
||||
|
||||
struct node_info
|
||||
{
|
||||
enum {NODE_UNKNOWN, NODE_DOWN, NODE_UP, NODE_CLVMD} state;
|
||||
@@ -110,13 +103,6 @@ struct lock_info
|
||||
SaNameT lock_name;
|
||||
};
|
||||
|
||||
struct lock_wait
|
||||
{
|
||||
pthread_cond_t cond;
|
||||
pthread_mutex_t mutex;
|
||||
int status;
|
||||
};
|
||||
|
||||
/* Set errno to something approximating the right value and return 0 or -1 */
|
||||
static int ais_to_errno(SaAisErrorT err)
|
||||
{
|
||||
@@ -255,12 +241,13 @@ static void cpg_deliver_callback (cpg_handle_t handle,
|
||||
|
||||
memcpy(&target_nodeid, msg, OPENAIS_CSID_LEN);
|
||||
|
||||
DEBUGLOG("Got message from nodeid %d for %d. len %d\n",
|
||||
nodeid, target_nodeid, msg_len-4);
|
||||
DEBUGLOG("%u got message from nodeid %d for %d. len %d\n",
|
||||
our_nodeid, nodeid, target_nodeid, msg_len-4);
|
||||
|
||||
if (target_nodeid == our_nodeid)
|
||||
process_message(cluster_client, (char *)msg+OPENAIS_CSID_LEN,
|
||||
msg_len-OPENAIS_CSID_LEN, (char*)&nodeid);
|
||||
if (nodeid != our_nodeid)
|
||||
if (target_nodeid == our_nodeid || target_nodeid == 0)
|
||||
process_message(cluster_client, (char *)msg+OPENAIS_CSID_LEN,
|
||||
msg_len-OPENAIS_CSID_LEN, (char*)&nodeid);
|
||||
}
|
||||
|
||||
static void cpg_confchg_callback(cpg_handle_t handle,
|
||||
@@ -302,34 +289,27 @@ static void cpg_confchg_callback(cpg_handle_t handle,
|
||||
ninfo->state = NODE_DOWN;
|
||||
}
|
||||
|
||||
num_nodes = joined_list_entries;
|
||||
}
|
||||
for (i=0; i<member_list_entries; i++) {
|
||||
if (member_list[i].nodeid == 0) continue;
|
||||
ninfo = dm_hash_lookup_binary(node_hash,
|
||||
(char *)&member_list[i].nodeid,
|
||||
OPENAIS_CSID_LEN);
|
||||
if (!ninfo) {
|
||||
ninfo = malloc(sizeof(struct node_info));
|
||||
if (!ninfo) {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
ninfo->nodeid = member_list[i].nodeid;
|
||||
dm_hash_insert_binary(node_hash,
|
||||
(char *)&ninfo->nodeid,
|
||||
OPENAIS_CSID_LEN, ninfo);
|
||||
}
|
||||
}
|
||||
ninfo->state = NODE_CLVMD;
|
||||
}
|
||||
|
||||
static void lck_lock_callback(SaInvocationT invocation,
|
||||
SaLckLockStatusT lockStatus,
|
||||
SaAisErrorT error)
|
||||
{
|
||||
struct lock_wait *lwait = (struct lock_wait *)(long)invocation;
|
||||
|
||||
DEBUGLOG("lck_lock_callback, error = %d\n", error);
|
||||
|
||||
lwait->status = error;
|
||||
pthread_mutex_lock(&lwait->mutex);
|
||||
pthread_cond_signal(&lwait->cond);
|
||||
pthread_mutex_unlock(&lwait->mutex);
|
||||
}
|
||||
|
||||
static void lck_unlock_callback(SaInvocationT invocation,
|
||||
SaAisErrorT error)
|
||||
{
|
||||
struct lock_wait *lwait = (struct lock_wait *)(long)invocation;
|
||||
|
||||
DEBUGLOG("lck_unlock_callback\n");
|
||||
|
||||
lwait->status = SA_AIS_OK;
|
||||
pthread_mutex_lock(&lwait->mutex);
|
||||
pthread_cond_signal(&lwait->cond);
|
||||
pthread_mutex_unlock(&lwait->mutex);
|
||||
num_nodes = member_list_entries;
|
||||
}
|
||||
|
||||
static int lck_dispatch(struct local_client *client, char *buf, int len,
|
||||
@@ -359,7 +339,7 @@ static int _init_cluster(void)
|
||||
}
|
||||
|
||||
err = saLckInitialize(&lck_handle,
|
||||
&lck_callbacks,
|
||||
NULL,
|
||||
&ver);
|
||||
if (err != SA_AIS_OK) {
|
||||
cpg_initialize(&cpg_handle, &cpg_callbacks);
|
||||
@@ -475,6 +455,7 @@ static int _cluster_do_node_callback(struct local_client *master_client,
|
||||
{
|
||||
struct dm_hash_node *hn;
|
||||
struct node_info *ninfo;
|
||||
int somedown = 0;
|
||||
|
||||
dm_hash_iterate(hn, node_hash)
|
||||
{
|
||||
@@ -488,22 +469,20 @@ static int _cluster_do_node_callback(struct local_client *master_client,
|
||||
|
||||
if (ninfo->state != NODE_DOWN)
|
||||
callback(master_client, csid, ninfo->state == NODE_CLVMD);
|
||||
if (ninfo->state != NODE_CLVMD)
|
||||
somedown = -1;
|
||||
}
|
||||
return 0;
|
||||
return somedown;
|
||||
}
|
||||
|
||||
/* Real locking */
|
||||
static int _lock_resource(char *resource, int mode, int flags, int *lockid)
|
||||
{
|
||||
struct lock_wait lwait;
|
||||
struct lock_info *linfo;
|
||||
SaLckResourceHandleT res_handle;
|
||||
SaAisErrorT err;
|
||||
SaLckLockIdT lock_id;
|
||||
|
||||
pthread_cond_init(&lwait.cond, NULL);
|
||||
pthread_mutex_init(&lwait.mutex, NULL);
|
||||
pthread_mutex_lock(&lwait.mutex);
|
||||
SaLckLockStatusT lockStatus;
|
||||
|
||||
/* This needs to be converted from DLM/LVM2 value for OpenAIS LCK */
|
||||
if (flags & LCK_NONBLOCK) flags = SA_LCK_LOCK_NO_QUEUE;
|
||||
@@ -526,24 +505,24 @@ static int _lock_resource(char *resource, int mode, int flags, int *lockid)
|
||||
return ais_to_errno(err);
|
||||
}
|
||||
|
||||
err = saLckResourceLockAsync(res_handle,
|
||||
(SaInvocationT)(long)&lwait,
|
||||
&lock_id,
|
||||
mode,
|
||||
flags,
|
||||
0);
|
||||
if (err != SA_AIS_OK)
|
||||
err = saLckResourceLock(
|
||||
res_handle,
|
||||
&lock_id,
|
||||
mode,
|
||||
flags,
|
||||
0,
|
||||
SA_TIME_END,
|
||||
&lockStatus);
|
||||
if (err != SA_AIS_OK && lockStatus != SA_LCK_LOCK_GRANTED)
|
||||
{
|
||||
free(linfo);
|
||||
saLckResourceClose(res_handle);
|
||||
return ais_to_errno(err);
|
||||
}
|
||||
|
||||
|
||||
/* Wait for it to complete */
|
||||
pthread_cond_wait(&lwait.cond, &lwait.mutex);
|
||||
pthread_mutex_unlock(&lwait.mutex);
|
||||
|
||||
DEBUGLOG("lock_resource returning %d, lock_id=%llx\n", lwait.status,
|
||||
DEBUGLOG("lock_resource returning %d, lock_id=%llx\n", err,
|
||||
lock_id);
|
||||
|
||||
linfo->lock_id = lock_id;
|
||||
@@ -551,43 +530,34 @@ static int _lock_resource(char *resource, int mode, int flags, int *lockid)
|
||||
|
||||
dm_hash_insert(lock_hash, resource, linfo);
|
||||
|
||||
return ais_to_errno(lwait.status);
|
||||
return ais_to_errno(err);
|
||||
}
|
||||
|
||||
|
||||
static int _unlock_resource(char *resource, int lockid)
|
||||
{
|
||||
struct lock_wait lwait;
|
||||
SaAisErrorT err;
|
||||
struct lock_info *linfo;
|
||||
|
||||
pthread_cond_init(&lwait.cond, NULL);
|
||||
pthread_mutex_init(&lwait.mutex, NULL);
|
||||
pthread_mutex_lock(&lwait.mutex);
|
||||
|
||||
DEBUGLOG("unlock_resource %s\n", resource);
|
||||
linfo = dm_hash_lookup(lock_hash, resource);
|
||||
if (!linfo)
|
||||
return 0;
|
||||
|
||||
DEBUGLOG("unlock_resource: lockid: %llx\n", linfo->lock_id);
|
||||
err = saLckResourceUnlockAsync((SaInvocationT)(long)&lwait, linfo->lock_id);
|
||||
err = saLckResourceUnlock(linfo->lock_id, SA_TIME_END);
|
||||
if (err != SA_AIS_OK)
|
||||
{
|
||||
DEBUGLOG("Unlock returned %d\n", err);
|
||||
return ais_to_errno(err);
|
||||
}
|
||||
|
||||
/* Wait for it to complete */
|
||||
pthread_cond_wait(&lwait.cond, &lwait.mutex);
|
||||
pthread_mutex_unlock(&lwait.mutex);
|
||||
|
||||
/* Release the resource */
|
||||
dm_hash_remove(lock_hash, resource);
|
||||
saLckResourceClose(linfo->res_handle);
|
||||
free(linfo);
|
||||
|
||||
return ais_to_errno(lwait.status);
|
||||
return ais_to_errno(err);
|
||||
}
|
||||
|
||||
static int _sync_lock(const char *resource, int mode, int flags, int *lockid)
|
||||
|
||||
@@ -17,6 +17,12 @@
|
||||
* CLVMD: Cluster LVM daemon
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
|
||||
#include <configure.h>
|
||||
#include <libdevmapper.h>
|
||||
|
||||
#include <pthread.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -37,6 +43,7 @@
|
||||
#include <getopt.h>
|
||||
#include <syslog.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <libdlm.h>
|
||||
|
||||
#include "clvmd-comms.h"
|
||||
@@ -45,8 +52,7 @@
|
||||
#include "version.h"
|
||||
#include "clvmd.h"
|
||||
#include "refresh_clvmd.h"
|
||||
#include "list.h"
|
||||
#include "log.h"
|
||||
#include "lvm-logging.h"
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
@@ -74,7 +80,7 @@ static unsigned max_cluster_member_name_len;
|
||||
|
||||
/* Structure of items on the LVM thread list */
|
||||
struct lvm_thread_cmd {
|
||||
struct list list;
|
||||
struct dm_list list;
|
||||
|
||||
struct local_client *client;
|
||||
struct clvm_header *msg;
|
||||
@@ -89,7 +95,7 @@ static pthread_t lvm_thread;
|
||||
static pthread_mutex_t lvm_thread_mutex;
|
||||
static pthread_cond_t lvm_thread_cond;
|
||||
static pthread_mutex_t lvm_start_mutex;
|
||||
static struct list lvm_cmd_head;
|
||||
static struct dm_list lvm_cmd_head;
|
||||
static volatile sig_atomic_t quit = 0;
|
||||
static volatile sig_atomic_t reread_config = 0;
|
||||
static int child_pipe[2];
|
||||
@@ -146,8 +152,10 @@ static void usage(char *prog, FILE *file)
|
||||
fprintf(file, "\n");
|
||||
fprintf(file, " -V Show version of clvmd\n");
|
||||
fprintf(file, " -h Show this help information\n");
|
||||
fprintf(file, " -d Don't fork, run in the foreground\n");
|
||||
fprintf(file, " -d Set debug level\n");
|
||||
fprintf(file, " If starting clvmd then don't fork, run in the foreground\n");
|
||||
fprintf(file, " -R Tell all running clvmds in the cluster to reload their device cache\n");
|
||||
fprintf(file, " -C Sets debug level (from -d) on all clvmd instances clusterwide\n");
|
||||
fprintf(file, " -t<secs> Command timeout (default 60 seconds)\n");
|
||||
fprintf(file, " -T<secs> Startup timeout (default none)\n");
|
||||
fprintf(file, "\n");
|
||||
@@ -179,8 +187,10 @@ void debuglog(const char *fmt, ...)
|
||||
va_end(ap);
|
||||
}
|
||||
if (debug == DEBUG_SYSLOG) {
|
||||
if (!syslog_init)
|
||||
if (!syslog_init) {
|
||||
openlog("clvmd", LOG_PID, LOG_DAEMON);
|
||||
syslog_init = 1;
|
||||
}
|
||||
|
||||
va_start(ap,fmt);
|
||||
vsyslog(LOG_DEBUG, fmt, ap);
|
||||
@@ -188,6 +198,58 @@ void debuglog(const char *fmt, ...)
|
||||
}
|
||||
}
|
||||
|
||||
static const char *decode_cmd(unsigned char cmdl)
|
||||
{
|
||||
static char buf[128];
|
||||
const char *command;
|
||||
|
||||
switch (cmdl) {
|
||||
case CLVMD_CMD_TEST:
|
||||
command = "TEST";
|
||||
break;
|
||||
case CLVMD_CMD_LOCK_VG:
|
||||
command = "LOCK_VG";
|
||||
break;
|
||||
case CLVMD_CMD_LOCK_LV:
|
||||
command = "LOCK_LV";
|
||||
break;
|
||||
case CLVMD_CMD_REFRESH:
|
||||
command = "REFRESH";
|
||||
break;
|
||||
case CLVMD_CMD_SET_DEBUG:
|
||||
command = "SET_DEBUG";
|
||||
break;
|
||||
case CLVMD_CMD_GET_CLUSTERNAME:
|
||||
command = "GET_CLUSTERNAME";
|
||||
break;
|
||||
case CLVMD_CMD_VG_BACKUP:
|
||||
command = "VG_BACKUP";
|
||||
break;
|
||||
case CLVMD_CMD_REPLY:
|
||||
command = "REPLY";
|
||||
break;
|
||||
case CLVMD_CMD_VERSION:
|
||||
command = "VERSION";
|
||||
break;
|
||||
case CLVMD_CMD_GOAWAY:
|
||||
command = "GOAWAY";
|
||||
break;
|
||||
case CLVMD_CMD_LOCK:
|
||||
command = "LOCK";
|
||||
break;
|
||||
case CLVMD_CMD_UNLOCK:
|
||||
command = "UNLOCK";
|
||||
break;
|
||||
default:
|
||||
command = "unknown";
|
||||
break;
|
||||
}
|
||||
|
||||
sprintf(buf, "%s (0x%x)", command, cmdl);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int local_sock;
|
||||
@@ -295,7 +357,7 @@ int main(int argc, char *argv[])
|
||||
sigprocmask(SIG_BLOCK, &ss, NULL);
|
||||
|
||||
/* Initialise the LVM thread variables */
|
||||
list_init(&lvm_cmd_head);
|
||||
dm_list_init(&lvm_cmd_head);
|
||||
pthread_mutex_init(&lvm_thread_mutex, NULL);
|
||||
pthread_cond_init(&lvm_thread_cond, NULL);
|
||||
pthread_mutex_init(&lvm_start_mutex, NULL);
|
||||
@@ -527,7 +589,7 @@ static void timedout_callback(struct local_client *client, const char *csid,
|
||||
char nodename[max_cluster_member_name_len];
|
||||
|
||||
clops->name_from_csid(csid, nodename);
|
||||
DEBUGLOG("PJC: checking for a reply from %s\n", nodename);
|
||||
DEBUGLOG("Checking for a reply from %s\n", nodename);
|
||||
pthread_mutex_lock(&client->bits.localsock.reply_mutex);
|
||||
|
||||
reply = client->bits.localsock.replies;
|
||||
@@ -538,7 +600,7 @@ static void timedout_callback(struct local_client *client, const char *csid,
|
||||
pthread_mutex_unlock(&client->bits.localsock.reply_mutex);
|
||||
|
||||
if (!reply) {
|
||||
DEBUGLOG("PJC: node %s timed-out\n", nodename);
|
||||
DEBUGLOG("Node %s timed-out\n", nodename);
|
||||
add_reply_to_list(client, ETIMEDOUT, csid,
|
||||
"Command timed out", 18);
|
||||
}
|
||||
@@ -630,7 +692,7 @@ static void main_loop(int local_sock, int cmd_timeout)
|
||||
}
|
||||
|
||||
if (FD_ISSET(thisfd->fd, &in)) {
|
||||
struct local_client *newfd;
|
||||
struct local_client *newfd = NULL;
|
||||
int ret;
|
||||
|
||||
/* Do callback */
|
||||
@@ -901,8 +963,7 @@ static int read_from_local_sock(struct local_client *thisfd)
|
||||
}
|
||||
|
||||
/* Free the command buffer */
|
||||
if (thisfd->bits.localsock.cmd)
|
||||
free(thisfd->bits.localsock.cmd);
|
||||
free(thisfd->bits.localsock.cmd);
|
||||
|
||||
/* Clear out the cross-link */
|
||||
if (thisfd->bits.localsock.pipe_client != NULL)
|
||||
@@ -937,8 +998,7 @@ static int read_from_local_sock(struct local_client *thisfd)
|
||||
}
|
||||
|
||||
/* Free any old buffer space */
|
||||
if (thisfd->bits.localsock.cmd)
|
||||
free(thisfd->bits.localsock.cmd);
|
||||
free(thisfd->bits.localsock.cmd);
|
||||
|
||||
/* See if we have the whole message */
|
||||
argslen =
|
||||
@@ -984,6 +1044,14 @@ static int read_from_local_sock(struct local_client *thisfd)
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialise and lock the mutex so the subthread will wait after
|
||||
finishing the PRE routine */
|
||||
if (!thisfd->bits.localsock.threadid) {
|
||||
pthread_mutex_init(&thisfd->bits.localsock.mutex, NULL);
|
||||
pthread_cond_init(&thisfd->bits.localsock.cond, NULL);
|
||||
pthread_mutex_init(&thisfd->bits.localsock.reply_mutex, NULL);
|
||||
}
|
||||
|
||||
/* Only run the command if all the cluster nodes are running CLVMD */
|
||||
if (((inheader->flags & CLVMD_FLAG_LOCAL) == 0) &&
|
||||
(check_all_clvmds_running(thisfd) == -1)) {
|
||||
@@ -1055,12 +1123,6 @@ static int read_from_local_sock(struct local_client *thisfd)
|
||||
|
||||
thisfd->bits.localsock.pipe = comms_pipe[1];
|
||||
|
||||
/* Initialise and lock the mutex so the subthread will wait after
|
||||
finishing the PRE routine */
|
||||
pthread_mutex_init(&thisfd->bits.localsock.mutex, NULL);
|
||||
pthread_cond_init(&thisfd->bits.localsock.cond, NULL);
|
||||
pthread_mutex_init(&thisfd->bits.localsock.reply_mutex, NULL);
|
||||
|
||||
/* Make sure the thread has a copy of it's own ID */
|
||||
newfd->bits.pipe.threadid = thisfd->bits.localsock.threadid;
|
||||
|
||||
@@ -1166,8 +1228,8 @@ static void process_remote_command(struct clvm_header *msg, int msglen, int fd,
|
||||
/* Get the node name as we /may/ need it later */
|
||||
clops->name_from_csid(csid, nodename);
|
||||
|
||||
DEBUGLOG("process_remote_command %d for clientid 0x%x XID %d on node %s\n",
|
||||
msg->cmd, msg->clientid, msg->xid, nodename);
|
||||
DEBUGLOG("process_remote_command %s for clientid 0x%x XID %d on node %s\n",
|
||||
decode_cmd(msg->cmd), msg->clientid, msg->xid, nodename);
|
||||
|
||||
/* Check for GOAWAY and sulk */
|
||||
if (msg->cmd == CLVMD_CMD_GOAWAY) {
|
||||
@@ -1415,7 +1477,8 @@ next_pre:
|
||||
DEBUGLOG("Waiting for next pre command\n");
|
||||
|
||||
pthread_mutex_lock(&client->bits.localsock.mutex);
|
||||
if (client->bits.localsock.state != PRE_COMMAND) {
|
||||
if (client->bits.localsock.state != PRE_COMMAND &&
|
||||
!client->bits.localsock.finished) {
|
||||
pthread_cond_wait(&client->bits.localsock.cond,
|
||||
&client->bits.localsock.mutex);
|
||||
}
|
||||
@@ -1437,8 +1500,9 @@ static int process_local_command(struct clvm_header *msg, int msglen,
|
||||
int replylen = 0;
|
||||
int status;
|
||||
|
||||
DEBUGLOG("process_local_command: msg=%p, msglen =%d, client=%p\n", msg,
|
||||
msglen, client);
|
||||
DEBUGLOG("process_local_command: %s msg=%p, msglen =%d, client=%p\n",
|
||||
decode_cmd(msg->cmd), msg, msglen, client);
|
||||
|
||||
if (replybuf == NULL)
|
||||
return -1;
|
||||
|
||||
@@ -1545,8 +1609,7 @@ static void send_local_reply(struct local_client *client, int status, int fd)
|
||||
}
|
||||
thisreply = thisreply->next;
|
||||
|
||||
if (tempreply->replymsg)
|
||||
free(tempreply->replymsg);
|
||||
free(tempreply->replymsg);
|
||||
free(tempreply);
|
||||
}
|
||||
|
||||
@@ -1577,8 +1640,7 @@ static void free_reply(struct local_client *client)
|
||||
|
||||
thisreply = thisreply->next;
|
||||
|
||||
if (tempreply->replymsg)
|
||||
free(tempreply->replymsg);
|
||||
free(tempreply->replymsg);
|
||||
free(tempreply);
|
||||
}
|
||||
client->bits.localsock.replies = NULL;
|
||||
@@ -1613,7 +1675,7 @@ static void send_version_message()
|
||||
static int send_message(void *buf, int msglen, const char *csid, int fd,
|
||||
const char *errtext)
|
||||
{
|
||||
int len;
|
||||
int len = 0;
|
||||
int saved_errno = 0;
|
||||
struct timespec delay;
|
||||
struct timespec remtime;
|
||||
@@ -1692,7 +1754,7 @@ static int process_work_item(struct lvm_thread_cmd *cmd)
|
||||
*/
|
||||
static __attribute__ ((noreturn)) void *lvm_thread_fn(void *arg)
|
||||
{
|
||||
struct list *cmdl, *tmp;
|
||||
struct dm_list *cmdl, *tmp;
|
||||
sigset_t ss;
|
||||
int using_gulm = (int)(long)arg;
|
||||
|
||||
@@ -1718,20 +1780,19 @@ static __attribute__ ((noreturn)) void *lvm_thread_fn(void *arg)
|
||||
DEBUGLOG("LVM thread waiting for work\n");
|
||||
|
||||
pthread_mutex_lock(&lvm_thread_mutex);
|
||||
if (list_empty(&lvm_cmd_head))
|
||||
if (dm_list_empty(&lvm_cmd_head))
|
||||
pthread_cond_wait(&lvm_thread_cond, &lvm_thread_mutex);
|
||||
|
||||
list_iterate_safe(cmdl, tmp, &lvm_cmd_head) {
|
||||
dm_list_iterate_safe(cmdl, tmp, &lvm_cmd_head) {
|
||||
struct lvm_thread_cmd *cmd;
|
||||
|
||||
cmd =
|
||||
list_struct_base(cmdl, struct lvm_thread_cmd, list);
|
||||
list_del(&cmd->list);
|
||||
dm_list_struct_base(cmdl, struct lvm_thread_cmd, list);
|
||||
dm_list_del(&cmd->list);
|
||||
pthread_mutex_unlock(&lvm_thread_mutex);
|
||||
|
||||
process_work_item(cmd);
|
||||
if (cmd->msg)
|
||||
free(cmd->msg);
|
||||
free(cmd->msg);
|
||||
free(cmd);
|
||||
|
||||
pthread_mutex_lock(&lvm_thread_mutex);
|
||||
@@ -1777,7 +1838,7 @@ static int add_to_lvmqueue(struct local_client *client, struct clvm_header *msg,
|
||||
("add_to_lvmqueue: cmd=%p. client=%p, msg=%p, len=%d, csid=%p, xid=%d\n",
|
||||
cmd, client, msg, msglen, csid, cmd->xid);
|
||||
pthread_mutex_lock(&lvm_thread_mutex);
|
||||
list_add(&lvm_cmd_head, &cmd->list);
|
||||
dm_list_add(&lvm_cmd_head, &cmd->list);
|
||||
pthread_cond_signal(&lvm_thread_cond);
|
||||
pthread_mutex_unlock(&lvm_thread_mutex);
|
||||
|
||||
@@ -1824,8 +1885,9 @@ static int open_local_sock()
|
||||
log_error("Can't create local socket: %m");
|
||||
return -1;
|
||||
}
|
||||
/* Set Close-on-exec */
|
||||
/* Set Close-on-exec & non-blocking */
|
||||
fcntl(local_socket, F_SETFD, 1);
|
||||
fcntl(local_socket, F_SETFL, fcntl(local_socket, F_GETFL, 0) | O_NONBLOCK);
|
||||
|
||||
memset(&sockaddr, 0, sizeof(sockaddr));
|
||||
memcpy(sockaddr.sun_path, CLVMD_SOCKNAME, sizeof(CLVMD_SOCKNAME));
|
||||
|
||||
@@ -1,226 +0,0 @@
|
||||
/******************************************************************************
|
||||
*******************************************************************************
|
||||
**
|
||||
** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
|
||||
** Copyright (C) 2004 Red Hat, Inc. All rights reserved.
|
||||
**
|
||||
** This copyrighted material is made available to anyone wishing to use,
|
||||
** modify, copy, or redistribute it subject to the terms and conditions
|
||||
** of the GNU General Public License v.2.
|
||||
**
|
||||
*******************************************************************************
|
||||
******************************************************************************/
|
||||
|
||||
/* CMAN socket interface header,
|
||||
may be include by user or kernel code */
|
||||
|
||||
#ifndef __CNXMAN_SOCKET_H
|
||||
#define __CNXMAN_SOCKET_H
|
||||
|
||||
/* A currently unused number. TIPC also uses this number and you're unlikely
|
||||
to be using both.
|
||||
*/
|
||||
#define AF_CLUSTER 30
|
||||
#define PF_CLUSTER AF_CLUSTER
|
||||
|
||||
/* Protocol(socket) types */
|
||||
#define CLPROTO_MASTER 2
|
||||
#define CLPROTO_CLIENT 3
|
||||
|
||||
/* ioctls -- should register these properly */
|
||||
#define SIOCCLUSTER_NOTIFY _IOW('x', 0x01, int)
|
||||
#define SIOCCLUSTER_REMOVENOTIFY _IO( 'x', 0x02)
|
||||
#define SIOCCLUSTER_GETMEMBERS _IOR('x', 0x03, struct cl_cluster_nodelist)
|
||||
#define SIOCCLUSTER_SETEXPECTED_VOTES _IOW('x', 0x04, int)
|
||||
#define SIOCCLUSTER_ISQUORATE _IO( 'x', 0x05)
|
||||
#define SIOCCLUSTER_ISLISTENING _IOW('x', 0x06, struct cl_listen_request)
|
||||
#define SIOCCLUSTER_GETALLMEMBERS _IOR('x', 0x07, struct cl_cluster_nodelist)
|
||||
#define SIOCCLUSTER_SET_VOTES _IOW('x', 0x08, int)
|
||||
#define SIOCCLUSTER_GET_VERSION _IOR('x', 0x09, struct cl_version)
|
||||
#define SIOCCLUSTER_SET_VERSION _IOW('x', 0x0a, struct cl_version)
|
||||
#define SIOCCLUSTER_ISACTIVE _IO( 'x', 0x0b)
|
||||
#define SIOCCLUSTER_KILLNODE _IOW('x', 0x0c, int)
|
||||
#define SIOCCLUSTER_GET_JOINCOUNT _IO( 'x', 0x0d)
|
||||
#define SIOCCLUSTER_SERVICE_REGISTER _IOW('x', 0x0e, char)
|
||||
#define SIOCCLUSTER_SERVICE_UNREGISTER _IO('x', 0x0f)
|
||||
#define SIOCCLUSTER_SERVICE_JOIN _IO( 'x', 0x10)
|
||||
#define SIOCCLUSTER_SERVICE_LEAVE _IO( 'x', 0x20)
|
||||
#define SIOCCLUSTER_SERVICE_SETSIGNAL _IOW('x', 0x30, int)
|
||||
#define SIOCCLUSTER_SERVICE_STARTDONE _IOW('x', 0x40, unsigned int)
|
||||
#define SIOCCLUSTER_SERVICE_GETEVENT _IOR('x', 0x50, struct cl_service_event)
|
||||
#define SIOCCLUSTER_SERVICE_GETMEMBERS _IOR('x', 0x60, struct cl_cluster_nodelist)
|
||||
#define SIOCCLUSTER_SERVICE_GLOBALID _IOR('x', 0x70, uint32_t)
|
||||
#define SIOCCLUSTER_SERVICE_SETLEVEL _IOR('x', 0x80, int)
|
||||
#define SIOCCLUSTER_GETNODE _IOWR('x', 0x90, struct cl_cluster_node)
|
||||
#define SIOCCLUSTER_BARRIER _IOW('x', 0x0a0, struct cl_barrier_info)
|
||||
|
||||
/* These were setsockopts */
|
||||
#define SIOCCLUSTER_PASS_SOCKET _IOW('x', 0x0b0, struct cl_passed_sock)
|
||||
#define SIOCCLUSTER_SET_NODENAME _IOW('x', 0x0b1, char *)
|
||||
#define SIOCCLUSTER_SET_NODEID _IOW('x', 0x0b2, int)
|
||||
#define SIOCCLUSTER_JOIN_CLUSTER _IOW('x', 0x0b3, struct cl_join_cluster_info)
|
||||
#define SIOCCLUSTER_LEAVE_CLUSTER _IOW('x', 0x0b4, int)
|
||||
|
||||
|
||||
/* Maximum size of a cluster message */
|
||||
#define CMAN_MAX_CLUSTER_MESSAGE 1500
|
||||
#define CMAN_MAX_CLUSTER_MEMBER_NAME_LEN 255
|
||||
#define MAX_BARRIER_NAME_LEN 33
|
||||
#define MAX_SA_ADDR_LEN 12
|
||||
#define MAX_CLUSTER_NAME_LEN 16
|
||||
|
||||
/* Well-known cluster port numbers */
|
||||
#define CLUSTER_PORT_MEMBERSHIP 1 /* Mustn't block during cluster
|
||||
* transitions! */
|
||||
#define CLUSTER_PORT_SERVICES 2
|
||||
#define CLUSTER_PORT_SYSMAN 10 /* Remote execution daemon */
|
||||
#define CLUSTER_PORT_CLVMD 11 /* Cluster LVM daemon */
|
||||
#define CLUSTER_PORT_SLM 12 /* LVM SLM (simple lock manager) */
|
||||
|
||||
/* Port numbers above this will be blocked when the cluster is inquorate or in
|
||||
* transition */
|
||||
#define HIGH_PROTECTED_PORT 9
|
||||
|
||||
/* Reasons for leaving the cluster */
|
||||
#define CLUSTER_LEAVEFLAG_DOWN 0 /* Normal shutdown */
|
||||
#define CLUSTER_LEAVEFLAG_KILLED 1
|
||||
#define CLUSTER_LEAVEFLAG_PANIC 2
|
||||
#define CLUSTER_LEAVEFLAG_REMOVED 3 /* This one can reduce quorum */
|
||||
#define CLUSTER_LEAVEFLAG_REJECTED 4 /* Not allowed into the cluster in the
|
||||
* first place */
|
||||
#define CLUSTER_LEAVEFLAG_INCONSISTENT 5 /* Our view of the cluster is
|
||||
* in a minority */
|
||||
#define CLUSTER_LEAVEFLAG_DEAD 6 /* Discovered to be dead */
|
||||
#define CLUSTER_LEAVEFLAG_FORCE 0x10 /* Forced by command-line */
|
||||
|
||||
/* OOB messages sent to a local socket */
|
||||
#define CLUSTER_OOB_MSG_PORTCLOSED 1
|
||||
#define CLUSTER_OOB_MSG_STATECHANGE 2
|
||||
#define CLUSTER_OOB_MSG_SERVICEEVENT 3
|
||||
|
||||
/* Sendmsg flags, these are above the normal sendmsg flags so they don't
|
||||
* interfere */
|
||||
#define MSG_NOACK 0x010000 /* Don't need an ACK for this message */
|
||||
#define MSG_QUEUE 0x020000 /* Queue the message for sending later */
|
||||
#define MSG_MULTICAST 0x080000 /* Message was sent to all nodes in the cluster
|
||||
*/
|
||||
#define MSG_ALLINT 0x100000 /* Send out of all interfaces */
|
||||
#define MSG_REPLYEXP 0x200000 /* Reply is expected */
|
||||
|
||||
typedef enum { NODESTATE_REMOTEMEMBER, NODESTATE_JOINING, NODESTATE_MEMBER,
|
||||
NODESTATE_DEAD } nodestate_t;
|
||||
|
||||
|
||||
struct sockaddr_cl {
|
||||
unsigned short scl_family;
|
||||
unsigned char scl_flags;
|
||||
unsigned char scl_port;
|
||||
int scl_nodeid;
|
||||
};
|
||||
|
||||
/*
|
||||
* This is how we pass the multicast & receive sockets into kernel space.
|
||||
*/
|
||||
struct cl_passed_sock {
|
||||
int fd; /* FD of master socket to do multicast on */
|
||||
int number; /* Socket number, to match up recvonly & bcast
|
||||
* sockets */
|
||||
int multicast; /* Is it multicast or receive ? */
|
||||
};
|
||||
|
||||
/* Cluster configuration info passed when we join the cluster */
|
||||
struct cl_join_cluster_info {
|
||||
unsigned char votes;
|
||||
unsigned int expected_votes;
|
||||
unsigned int two_node;
|
||||
unsigned int config_version;
|
||||
|
||||
char cluster_name[17];
|
||||
};
|
||||
|
||||
|
||||
/* This is the structure, per node, returned from the membership ioctl */
|
||||
struct cl_cluster_node {
|
||||
unsigned int size;
|
||||
unsigned int node_id;
|
||||
unsigned int us;
|
||||
unsigned int leave_reason;
|
||||
unsigned int incarnation;
|
||||
nodestate_t state;
|
||||
char name[CMAN_MAX_CLUSTER_MEMBER_NAME_LEN];
|
||||
unsigned char votes;
|
||||
};
|
||||
|
||||
/* The struct passed to the membership ioctls */
|
||||
struct cl_cluster_nodelist {
|
||||
uint32_t max_members;
|
||||
struct cl_cluster_node *nodes;
|
||||
};
|
||||
|
||||
/* Structure passed to SIOCCLUSTER_ISLISTENING */
|
||||
struct cl_listen_request {
|
||||
unsigned char port;
|
||||
int nodeid;
|
||||
};
|
||||
|
||||
/* A Cluster PORTCLOSED message - received by a local user as an OOB message */
|
||||
struct cl_portclosed_oob {
|
||||
unsigned char cmd; /* CLUSTER_OOB_MSG_PORTCLOSED */
|
||||
unsigned char port;
|
||||
};
|
||||
|
||||
/* Get all version numbers or set the config version */
|
||||
struct cl_version {
|
||||
unsigned int major;
|
||||
unsigned int minor;
|
||||
unsigned int patch;
|
||||
unsigned int config;
|
||||
};
|
||||
|
||||
/* structure passed to barrier ioctls */
|
||||
struct cl_barrier_info {
|
||||
char cmd;
|
||||
char name[MAX_BARRIER_NAME_LEN];
|
||||
unsigned int flags;
|
||||
unsigned long arg;
|
||||
};
|
||||
|
||||
typedef enum { SERVICE_EVENT_STOP, SERVICE_EVENT_START, SERVICE_EVENT_FINISH,
|
||||
SERVICE_EVENT_LEAVEDONE } service_event_t;
|
||||
|
||||
typedef enum { SERVICE_START_FAILED, SERVICE_START_JOIN, SERVICE_START_LEAVE }
|
||||
service_start_t;
|
||||
|
||||
struct cl_service_event {
|
||||
service_event_t type;
|
||||
service_start_t start_type;
|
||||
unsigned int event_id;
|
||||
unsigned int last_stop;
|
||||
unsigned int last_start;
|
||||
unsigned int last_finish;
|
||||
unsigned int node_count;
|
||||
};
|
||||
|
||||
|
||||
/* Commands to the barrier ioctl */
|
||||
#define BARRIER_IOCTL_REGISTER 1
|
||||
#define BARRIER_IOCTL_CHANGE 2
|
||||
#define BARRIER_IOCTL_DELETE 3
|
||||
#define BARRIER_IOCTL_WAIT 4
|
||||
|
||||
/* Attributes of a barrier - bitmask */
|
||||
#define BARRIER_ATTR_AUTODELETE 1
|
||||
#define BARRIER_ATTR_MULTISTEP 2
|
||||
#define BARRIER_ATTR_MANUAL 4
|
||||
#define BARRIER_ATTR_ENABLED 8
|
||||
#define BARRIER_ATTR_CALLBACK 16
|
||||
|
||||
/* Attribute setting commands */
|
||||
#define BARRIER_SETATTR_AUTODELETE 1
|
||||
#define BARRIER_SETATTR_MULTISTEP 2
|
||||
#define BARRIER_SETATTR_ENABLED 3
|
||||
#define BARRIER_SETATTR_NODES 4
|
||||
#define BARRIER_SETATTR_CALLBACK 5
|
||||
#define BARRIER_SETATTR_TIMEOUT 6
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
*
|
||||
@@ -13,6 +13,10 @@
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
|
||||
#include <configure.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/utsname.h>
|
||||
@@ -33,7 +37,6 @@
|
||||
#include <libdevmapper.h>
|
||||
#include <libdlm.h>
|
||||
|
||||
#include "list.h"
|
||||
#include "lvm-types.h"
|
||||
#include "clvm.h"
|
||||
#include "clvmd-comms.h"
|
||||
@@ -43,7 +46,8 @@
|
||||
/* LVM2 headers */
|
||||
#include "toolcontext.h"
|
||||
#include "lvmcache.h"
|
||||
#include "log.h"
|
||||
#include "lvm-logging.h"
|
||||
#include "lvm-globals.h"
|
||||
#include "activate.h"
|
||||
#include "locking.h"
|
||||
#include "archiver.h"
|
||||
@@ -61,6 +65,93 @@ struct lv_info {
|
||||
int lock_mode;
|
||||
};
|
||||
|
||||
#define LCK_MASK (LCK_TYPE_MASK | LCK_SCOPE_MASK)
|
||||
|
||||
static const char *decode_locking_cmd(unsigned char cmdl)
|
||||
{
|
||||
static char buf[128];
|
||||
const char *type;
|
||||
const char *scope;
|
||||
const char *command;
|
||||
|
||||
switch (cmdl & LCK_TYPE_MASK) {
|
||||
case LCK_NULL:
|
||||
type = "NULL";
|
||||
break;
|
||||
case LCK_READ:
|
||||
type = "READ";
|
||||
break;
|
||||
case LCK_PREAD:
|
||||
type = "PREAD";
|
||||
break;
|
||||
case LCK_WRITE:
|
||||
type = "WRITE";
|
||||
break;
|
||||
case LCK_EXCL:
|
||||
type = "EXCL";
|
||||
break;
|
||||
case LCK_UNLOCK:
|
||||
type = "UNLOCK";
|
||||
break;
|
||||
default:
|
||||
type = "unknown";
|
||||
break;
|
||||
}
|
||||
|
||||
switch (cmdl & LCK_SCOPE_MASK) {
|
||||
case LCK_VG:
|
||||
scope = "VG";
|
||||
break;
|
||||
case LCK_LV:
|
||||
scope = "LV";
|
||||
break;
|
||||
default:
|
||||
scope = "unknown";
|
||||
break;
|
||||
}
|
||||
|
||||
switch (cmdl & LCK_MASK) {
|
||||
case LCK_LV_EXCLUSIVE & LCK_MASK:
|
||||
command = "LCK_LV_EXCLUSIVE";
|
||||
break;
|
||||
case LCK_LV_SUSPEND & LCK_MASK:
|
||||
command = "LCK_LV_SUSPEND";
|
||||
break;
|
||||
case LCK_LV_RESUME & LCK_MASK:
|
||||
command = "LCK_LV_RESUME";
|
||||
break;
|
||||
case LCK_LV_ACTIVATE & LCK_MASK:
|
||||
command = "LCK_LV_ACTIVATE";
|
||||
break;
|
||||
case LCK_LV_DEACTIVATE & LCK_MASK:
|
||||
command = "LCK_LV_DEACTIVATE";
|
||||
break;
|
||||
default:
|
||||
command = "unknown";
|
||||
break;
|
||||
}
|
||||
|
||||
sprintf(buf, "0x%x %s (%s|%s%s%s%s%s%s)", cmdl, command, type, scope,
|
||||
cmdl & LCK_NONBLOCK ? "|NONBLOCK" : "",
|
||||
cmdl & LCK_HOLD ? "|HOLD" : "",
|
||||
cmdl & LCK_LOCAL ? "|LOCAL" : "",
|
||||
cmdl & LCK_CLUSTER_VG ? "|CLUSTER_VG" : "",
|
||||
cmdl & LCK_CACHE ? "|CACHE" : "");
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static const char *decode_flags(unsigned char flags)
|
||||
{
|
||||
static char buf[128];
|
||||
|
||||
sprintf(buf, "0x%x (%s%s)", flags,
|
||||
flags & LCK_MIRROR_NOSYNC_MODE ? "MIRROR_NOSYNC " : "",
|
||||
flags & LCK_DMEVENTD_MONITOR_MODE ? "DMEVENTD_MONITOR " : "");
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
char *get_last_lvm_error()
|
||||
{
|
||||
return last_error;
|
||||
@@ -312,22 +403,19 @@ int do_lock_lv(unsigned char command, unsigned char lock_flags, char *resource)
|
||||
{
|
||||
int status = 0;
|
||||
|
||||
DEBUGLOG("do_lock_lv: resource '%s', cmd = 0x%x, flags = %x\n",
|
||||
resource, command, lock_flags);
|
||||
DEBUGLOG("do_lock_lv: resource '%s', cmd = %s, flags = %s\n",
|
||||
resource, decode_locking_cmd(command), decode_flags(lock_flags));
|
||||
|
||||
pthread_mutex_lock(&lvm_lock);
|
||||
if (!cmd->config_valid || config_files_changed(cmd)) {
|
||||
/* Reinitialise various settings inc. logging, filters */
|
||||
if (!refresh_toolcontext(cmd)) {
|
||||
if (do_refresh_cache()) {
|
||||
log_error("Updated config file invalid. Aborting.");
|
||||
pthread_mutex_unlock(&lvm_lock);
|
||||
return EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (lock_flags & LCK_PARTIAL_MODE)
|
||||
init_partial(1);
|
||||
|
||||
if (lock_flags & LCK_MIRROR_NOSYNC_MODE)
|
||||
init_mirror_in_sync(1);
|
||||
|
||||
@@ -366,9 +454,6 @@ int do_lock_lv(unsigned char command, unsigned char lock_flags, char *resource)
|
||||
break;
|
||||
}
|
||||
|
||||
if (lock_flags & LCK_PARTIAL_MODE)
|
||||
init_partial(0);
|
||||
|
||||
if (lock_flags & LCK_MIRROR_NOSYNC_MODE)
|
||||
init_mirror_in_sync(0);
|
||||
|
||||
@@ -391,8 +476,8 @@ int pre_lock_lv(unsigned char command, unsigned char lock_flags, char *resource)
|
||||
before suspending cluster-wide.
|
||||
*/
|
||||
if (command == LCK_LV_SUSPEND) {
|
||||
DEBUGLOG("pre_lock_lv: resource '%s', cmd = 0x%x, flags = %d\n",
|
||||
resource, command, lock_flags);
|
||||
DEBUGLOG("pre_lock_lv: resource '%s', cmd = %s, flags = %s\n",
|
||||
resource, decode_locking_cmd(command), decode_flags(lock_flags));
|
||||
|
||||
if (hold_lock(resource, LKM_PWMODE, LKF_NOQUEUE))
|
||||
return errno;
|
||||
@@ -411,8 +496,8 @@ int post_lock_lv(unsigned char command, unsigned char lock_flags,
|
||||
int oldmode;
|
||||
|
||||
DEBUGLOG
|
||||
("post_lock_lv: resource '%s', cmd = 0x%x, flags = %d\n",
|
||||
resource, command, lock_flags);
|
||||
("post_lock_lv: resource '%s', cmd = %s, flags = %s\n",
|
||||
resource, decode_locking_cmd(command), decode_flags(lock_flags));
|
||||
|
||||
/* If the lock state is PW then restore it to what it was */
|
||||
oldmode = get_current_lock(resource);
|
||||
@@ -437,7 +522,7 @@ int post_lock_lv(unsigned char command, unsigned char lock_flags,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check if a VG is un use by LVM1 so we don't stomp on it */
|
||||
/* Check if a VG is in use by LVM1 so we don't stomp on it */
|
||||
int do_check_lvm1(const char *vgname)
|
||||
{
|
||||
int status;
|
||||
@@ -470,9 +555,10 @@ static void drop_vg_locks()
|
||||
char line[255];
|
||||
FILE *vgs =
|
||||
popen
|
||||
("lvm pvs --nolocking --noheadings -o vg_name", "r");
|
||||
("lvm pvs --config 'log{command_names=0 prefix=\"\"}' --nolocking --noheadings -o vg_name", "r");
|
||||
|
||||
sync_unlock("P_orphans", LCK_EXCL);
|
||||
sync_unlock("P_" VG_ORPHANS, LCK_EXCL);
|
||||
sync_unlock("P_" VG_GLOBAL, LCK_EXCL);
|
||||
|
||||
if (!vgs)
|
||||
return;
|
||||
@@ -499,6 +585,17 @@ static void drop_vg_locks()
|
||||
DEBUGLOG("vgs fclose failed: %s\n", strerror(errno));
|
||||
}
|
||||
|
||||
/*
|
||||
* Drop lvmcache metadata
|
||||
*/
|
||||
void drop_metadata(const char *vgname)
|
||||
{
|
||||
DEBUGLOG("Dropping metadata for VG %s\n", vgname);
|
||||
pthread_mutex_lock(&lvm_lock);
|
||||
lvmcache_drop_metadata(vgname);
|
||||
pthread_mutex_unlock(&lvm_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ideally, clvmd should be started before any LVs are active
|
||||
* but this may not be the case...
|
||||
@@ -511,7 +608,7 @@ static void *get_initial_state()
|
||||
char line[255];
|
||||
FILE *lvs =
|
||||
popen
|
||||
("lvm lvs --nolocking --noheadings -o vg_uuid,lv_uuid,lv_attr,vg_attr",
|
||||
("lvm lvs --config 'log{command_names=0 prefix=\"\"}' --nolocking --noheadings -o vg_uuid,lv_uuid,lv_attr,vg_attr",
|
||||
"r");
|
||||
|
||||
if (!lvs)
|
||||
|
||||
@@ -33,5 +33,6 @@ extern int hold_unlock(char *resource);
|
||||
extern int hold_lock(char *resource, int mode, int flags);
|
||||
extern void unlock_all(void);
|
||||
extern char *get_last_lvm_error(void);
|
||||
extern void drop_metadata(const char *vgname);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
|
||||
#include <configure.h>
|
||||
#include <stddef.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
@@ -26,6 +30,7 @@
|
||||
#include <libdevmapper.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "clvm.h"
|
||||
#include "refresh_clvmd.h"
|
||||
|
||||
@@ -13,7 +13,10 @@
|
||||
It can also make outgoing connnections to the other clvmd nodes.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
|
||||
#include <configure.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/utsname.h>
|
||||
|
||||
@@ -18,22 +18,31 @@ VPATH = @srcdir@
|
||||
SOURCES = libdevmapper-event.c
|
||||
|
||||
LIB_STATIC = libdevmapper-event.a
|
||||
LIB_VERSION = $(LIB_VERSION_DM)
|
||||
|
||||
ifeq ("@LIB_SUFFIX@","dylib")
|
||||
LIB_SHARED = libdevmapper-event.dylib
|
||||
else
|
||||
LIB_SHARED = libdevmapper-event.so
|
||||
VERSIONED_SHLIB = $(LIB_SHARED).$(LIB_VERSION)
|
||||
endif
|
||||
|
||||
TARGETS = dmeventd
|
||||
CLEAN_TARGETS = dmeventd.o
|
||||
|
||||
include ../make.tmpl
|
||||
ifneq ($(MAKECMDGOALS),device-mapper)
|
||||
SUBDIRS+=plugins
|
||||
endif
|
||||
|
||||
include $(top_srcdir)/make.tmpl
|
||||
|
||||
all: dmeventd
|
||||
device-mapper: dmeventd
|
||||
|
||||
LDFLAGS += -ldl -ldevmapper -lpthread
|
||||
CLDFLAGS += -ldl -ldevmapper -lpthread
|
||||
|
||||
dmeventd: $(LIB_SHARED) dmeventd.o
|
||||
dmeventd: $(LIB_SHARED) $(VERSIONED_SHLIB) dmeventd.o
|
||||
$(CC) -o $@ dmeventd.o $(CFLAGS) $(LDFLAGS) \
|
||||
-L. -ldevmapper-event $(LIBS) -rdynamic
|
||||
|
||||
@@ -52,6 +61,8 @@ endif
|
||||
|
||||
install: $(INSTALL_TYPE) install_include install_dmeventd
|
||||
|
||||
install_device-mapper: install
|
||||
|
||||
install_include:
|
||||
$(INSTALL) -D $(OWNER) $(GROUP) -m 444 libdevmapper-event.h \
|
||||
$(includedir)/libdevmapper-event.h
|
||||
@@ -74,6 +85,10 @@ install_static: libdevmapper-event.a
|
||||
$(libdir)/libdevmapper-event.a.$(LIB_VERSION)
|
||||
$(LN_S) -f libdevmapper-event.a.$(LIB_VERSION) $(libdir)/libdevmapper-event.a
|
||||
|
||||
$(VERSIONED_SHLIB): $(LIB_SHARED)
|
||||
$(RM) -f $@
|
||||
$(LN_S) $(LIB_SHARED) $@
|
||||
|
||||
.PHONY: distclean_lib distclean
|
||||
|
||||
distclean_lib:
|
||||
|
||||
@@ -22,10 +22,9 @@
|
||||
#include "configure.h"
|
||||
#include "libdevmapper.h"
|
||||
#include "libdevmapper-event.h"
|
||||
#include "list.h"
|
||||
#include "dmeventd.h"
|
||||
//#include "libmultilog.h"
|
||||
#include "log.h"
|
||||
#include "dm-logging.h"
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
@@ -36,6 +35,7 @@
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <arpa/inet.h> /* for htonl, ntohl */
|
||||
|
||||
#ifdef linux
|
||||
@@ -57,11 +57,11 @@ static volatile sig_atomic_t _thread_registries_empty = 1; /* registries are emp
|
||||
static int _debug = 0;
|
||||
|
||||
/* List (un)link macros. */
|
||||
#define LINK(x, head) list_add(head, &(x)->list)
|
||||
#define LINK(x, head) dm_list_add(head, &(x)->list)
|
||||
#define LINK_DSO(dso) LINK(dso, &_dso_registry)
|
||||
#define LINK_THREAD(thread) LINK(thread, &_thread_registry)
|
||||
|
||||
#define UNLINK(x) list_del(&(x)->list)
|
||||
#define UNLINK(x) dm_list_del(&(x)->list)
|
||||
#define UNLINK_DSO(x) UNLINK(x)
|
||||
#define UNLINK_THREAD(x) UNLINK(x)
|
||||
|
||||
@@ -100,7 +100,7 @@ static pthread_mutex_t _global_mutex;
|
||||
|
||||
/* Data kept about a DSO. */
|
||||
struct dso_data {
|
||||
struct list list;
|
||||
struct dm_list list;
|
||||
|
||||
char *dso_name; /* DSO name (eg, "evms", "dmraid", "lvm2"). */
|
||||
|
||||
@@ -142,7 +142,7 @@ struct dso_data {
|
||||
int (*unregister_device)(const char *device, const char *uuid,
|
||||
int major, int minor, void **user);
|
||||
};
|
||||
static LIST_INIT(_dso_registry);
|
||||
static DM_LIST_INIT(_dso_registry);
|
||||
|
||||
/* Structure to keep parsed register variables from client message. */
|
||||
struct message_data {
|
||||
@@ -167,7 +167,7 @@ struct message_data {
|
||||
* occurs and the event processing function of the DSO gets called.
|
||||
*/
|
||||
struct thread_status {
|
||||
struct list list;
|
||||
struct dm_list list;
|
||||
|
||||
pthread_t thread;
|
||||
|
||||
@@ -188,14 +188,14 @@ struct thread_status {
|
||||
struct dm_task *current_task;
|
||||
time_t next_time;
|
||||
uint32_t timeout;
|
||||
struct list timeout_list;
|
||||
struct dm_list timeout_list;
|
||||
void *dso_private; /* dso per-thread status variable */
|
||||
};
|
||||
static LIST_INIT(_thread_registry);
|
||||
static LIST_INIT(_thread_registry_unused);
|
||||
static DM_LIST_INIT(_thread_registry);
|
||||
static DM_LIST_INIT(_thread_registry_unused);
|
||||
|
||||
static int _timeout_running;
|
||||
static LIST_INIT(_timeout_registry);
|
||||
static DM_LIST_INIT(_timeout_registry);
|
||||
static pthread_mutex_t _timeout_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_cond_t _timeout_cond = PTHREAD_COND_INITIALIZER;
|
||||
|
||||
@@ -238,7 +238,7 @@ static struct thread_status *_alloc_thread_status(struct message_data *data,
|
||||
ret->dso_data = dso_data;
|
||||
ret->events = data->events.field;
|
||||
ret->timeout = data->timeout.secs;
|
||||
list_init(&ret->timeout_list);
|
||||
dm_list_init(&ret->timeout_list);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -458,7 +458,7 @@ static struct thread_status *_lookup_thread_status(struct message_data *data)
|
||||
{
|
||||
struct thread_status *thread;
|
||||
|
||||
list_iterate_items(thread, &_thread_registry)
|
||||
dm_list_iterate_items(thread, &_thread_registry)
|
||||
if (!strcmp(data->device_uuid, thread->device.uuid))
|
||||
return thread;
|
||||
|
||||
@@ -488,13 +488,13 @@ static void *_timeout_thread(void *unused __attribute((unused)))
|
||||
pthread_cleanup_push(_exit_timeout, NULL);
|
||||
pthread_mutex_lock(&_timeout_mutex);
|
||||
|
||||
while (!list_empty(&_timeout_registry)) {
|
||||
while (!dm_list_empty(&_timeout_registry)) {
|
||||
struct thread_status *thread;
|
||||
|
||||
timeout.tv_sec = 0;
|
||||
curr_time = time(NULL);
|
||||
|
||||
list_iterate_items_gen(thread, &_timeout_registry, timeout_list) {
|
||||
dm_list_iterate_items_gen(thread, &_timeout_registry, timeout_list) {
|
||||
if (thread->next_time <= curr_time) {
|
||||
thread->next_time = curr_time + thread->timeout;
|
||||
pthread_kill(thread->thread, SIGALRM);
|
||||
@@ -521,8 +521,8 @@ static int _register_for_timeout(struct thread_status *thread)
|
||||
|
||||
thread->next_time = time(NULL) + thread->timeout;
|
||||
|
||||
if (list_empty(&thread->timeout_list)) {
|
||||
list_add(&_timeout_registry, &thread->timeout_list);
|
||||
if (dm_list_empty(&thread->timeout_list)) {
|
||||
dm_list_add(&_timeout_registry, &thread->timeout_list);
|
||||
if (_timeout_running)
|
||||
pthread_cond_signal(&_timeout_cond);
|
||||
}
|
||||
@@ -542,9 +542,9 @@ static int _register_for_timeout(struct thread_status *thread)
|
||||
static void _unregister_for_timeout(struct thread_status *thread)
|
||||
{
|
||||
pthread_mutex_lock(&_timeout_mutex);
|
||||
if (!list_empty(&thread->timeout_list)) {
|
||||
list_del(&thread->timeout_list);
|
||||
list_init(&thread->timeout_list);
|
||||
if (!dm_list_empty(&thread->timeout_list)) {
|
||||
dm_list_del(&thread->timeout_list);
|
||||
dm_list_init(&thread->timeout_list);
|
||||
}
|
||||
pthread_mutex_unlock(&_timeout_mutex);
|
||||
}
|
||||
@@ -697,7 +697,7 @@ static void _monitor_unregister(void *arg)
|
||||
}
|
||||
/* we may have been relinked to unused registry since we were
|
||||
called, so check that */
|
||||
list_iterate_items(thread_iter, &_thread_registry_unused)
|
||||
dm_list_iterate_items(thread_iter, &_thread_registry_unused)
|
||||
if (thread_iter == thread) {
|
||||
thread->status = DM_THREAD_DONE;
|
||||
_unlock_mutex();
|
||||
@@ -838,7 +838,7 @@ static struct dso_data *_lookup_dso(struct message_data *data)
|
||||
{
|
||||
struct dso_data *dso_data, *ret = NULL;
|
||||
|
||||
list_iterate_items(dso_data, &_dso_registry)
|
||||
dm_list_iterate_items(dso_data, &_dso_registry)
|
||||
if (!strcmp(data->dso_name, dso_data->dso_name)) {
|
||||
_lib_get(dso_data);
|
||||
ret = dso_data;
|
||||
@@ -1109,7 +1109,7 @@ static int _get_registered_dev(struct message_data *message_data, int next)
|
||||
_lock_mutex();
|
||||
|
||||
/* Iterate list of threads checking if we want a particular one. */
|
||||
list_iterate_items(thread, &_thread_registry)
|
||||
dm_list_iterate_items(thread, &_thread_registry)
|
||||
if (_want_registered_device(message_data->dso_name,
|
||||
message_data->device_uuid,
|
||||
thread)) {
|
||||
@@ -1132,10 +1132,10 @@ static int _get_registered_dev(struct message_data *message_data, int next)
|
||||
thread = hit;
|
||||
|
||||
while (1) {
|
||||
if (list_end(&_thread_registry, &thread->list))
|
||||
if (dm_list_end(&_thread_registry, &thread->list))
|
||||
goto out;
|
||||
|
||||
thread = list_item(thread->list.n, struct thread_status);
|
||||
thread = dm_list_item(thread->list.n, struct thread_status);
|
||||
if (_want_registered_device(message_data->dso_name, NULL, thread)) {
|
||||
hit = thread;
|
||||
break;
|
||||
@@ -1439,12 +1439,12 @@ static void _process_request(struct dm_event_fifos *fifos)
|
||||
static void _cleanup_unused_threads(void)
|
||||
{
|
||||
int ret;
|
||||
struct list *l;
|
||||
struct dm_list *l;
|
||||
struct thread_status *thread;
|
||||
|
||||
_lock_mutex();
|
||||
while ((l = list_first(&_thread_registry_unused))) {
|
||||
thread = list_item(l, struct thread_status);
|
||||
while ((l = dm_list_first(&_thread_registry_unused))) {
|
||||
thread = dm_list_item(l, struct thread_status);
|
||||
if (thread->processing)
|
||||
break; /* cleanup on the next round */
|
||||
|
||||
@@ -1469,7 +1469,7 @@ static void _cleanup_unused_threads(void)
|
||||
break;
|
||||
}
|
||||
|
||||
list_del(l);
|
||||
dm_list_del(l);
|
||||
syslog(LOG_ERR,
|
||||
"thread can't be on unused list unless !thread->events");
|
||||
thread->status = DM_THREAD_RUNNING;
|
||||
@@ -1479,7 +1479,7 @@ static void _cleanup_unused_threads(void)
|
||||
}
|
||||
|
||||
if (thread->status == DM_THREAD_DONE) {
|
||||
list_del(l);
|
||||
dm_list_del(l);
|
||||
pthread_join(thread->thread, NULL);
|
||||
_lib_put(thread->dso_data);
|
||||
_free_thread_status(thread);
|
||||
@@ -1740,8 +1740,8 @@ int main(int argc, char *argv[])
|
||||
while (!_exit_now) {
|
||||
_process_request(&fifos);
|
||||
_cleanup_unused_threads();
|
||||
if (!list_empty(&_thread_registry)
|
||||
|| !list_empty(&_thread_registry_unused))
|
||||
if (!dm_list_empty(&_thread_registry)
|
||||
|| !dm_list_empty(&_thread_registry_unused))
|
||||
_thread_registries_empty = 0;
|
||||
else
|
||||
_thread_registries_empty = 1;
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "lib.h"
|
||||
#include "dmlib.h"
|
||||
#include "libdevmapper-event.h"
|
||||
//#include "libmultilog.h"
|
||||
#include "dmeventd.h"
|
||||
|
||||
@@ -16,7 +16,7 @@ srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
SUBDIRS += mirror
|
||||
SUBDIRS += mirror snapshot
|
||||
|
||||
include $(top_srcdir)/make.tmpl
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#
|
||||
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
# Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
|
||||
# Copyright (C) 2004-2005, 2008 Red Hat, Inc. All rights reserved.
|
||||
#
|
||||
# This file is part of LVM2.
|
||||
#
|
||||
@@ -17,7 +17,7 @@ top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
INCLUDES += -I${top_srcdir}/tools
|
||||
CLDFLAGS += -L${top_srcdir}/tools -ldevmapper -llvm2cmd
|
||||
CLDFLAGS += -L${top_srcdir}/tools -ldevmapper @LVM2CMD_LIB@
|
||||
|
||||
SOURCES = dmeventd_mirror.c
|
||||
|
||||
@@ -27,10 +27,11 @@ else
|
||||
LIB_SHARED = libdevmapper-event-lvm2mirror.so
|
||||
endif
|
||||
|
||||
LIB_VERSION = $(LIB_VERSION_LVM)
|
||||
|
||||
include $(top_srcdir)/make.tmpl
|
||||
|
||||
install: libdevmapper-event-lvm2mirror.$(LIB_SUFFIX)
|
||||
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \
|
||||
$(libdir)/$<.$(LIB_VERSION)
|
||||
$(LN_S) -f $<.$(LIB_VERSION) $(libdir)/$<
|
||||
|
||||
|
||||
@@ -125,8 +125,9 @@ out_parse:
|
||||
return ME_IGNORE;
|
||||
}
|
||||
|
||||
static void _temporary_log_fn(int level, const char *file,
|
||||
int line, const char *format)
|
||||
static void _temporary_log_fn(int level, const char *file __attribute((unused)),
|
||||
int line __attribute((unused)),
|
||||
const char *format)
|
||||
{
|
||||
if (!strncmp(format, "WARNING: ", 9) && (level < 5))
|
||||
syslog(LOG_CRIT, "%s", format);
|
||||
@@ -151,7 +152,7 @@ static int _remove_failed_devices(const char *device)
|
||||
}
|
||||
|
||||
/* FIXME Is any sanity-checking required on %s? */
|
||||
if (CMD_SIZE <= snprintf(cmd_str, CMD_SIZE, "vgreduce --config devices{ignore_suspended_devices=1} --removemissing %s", vg)) {
|
||||
if (CMD_SIZE <= snprintf(cmd_str, CMD_SIZE, "vgreduce --config devices{ignore_suspended_devices=1} --removemissing --force %s", vg)) {
|
||||
/* this error should be caught above, but doesn't hurt to check again */
|
||||
syslog(LOG_ERR, "Unable to form LVM command: Device name too long");
|
||||
dm_pool_empty(_mem_pool); /* FIXME: not safe with multiple threads */
|
||||
@@ -164,7 +165,8 @@ static int _remove_failed_devices(const char *device)
|
||||
return (r == 1) ? 0 : -1;
|
||||
}
|
||||
|
||||
void process_event(struct dm_task *dmt, enum dm_event_mask event,
|
||||
void process_event(struct dm_task *dmt,
|
||||
enum dm_event_mask event __attribute((unused)),
|
||||
void **unused __attribute((unused)))
|
||||
{
|
||||
void *next = NULL;
|
||||
@@ -222,8 +224,11 @@ void process_event(struct dm_task *dmt, enum dm_event_mask event,
|
||||
pthread_mutex_unlock(&_event_mutex);
|
||||
}
|
||||
|
||||
int register_device(const char *device, const char *uuid, int major, int minor,
|
||||
void **unused __attribute((unused)))
|
||||
int register_device(const char *device,
|
||||
const char *uuid __attribute((unused)),
|
||||
int major __attribute((unused)),
|
||||
int minor __attribute((unused)),
|
||||
void **unused __attribute((unused)))
|
||||
{
|
||||
int r = 0;
|
||||
|
||||
@@ -259,8 +264,11 @@ out:
|
||||
return r;
|
||||
}
|
||||
|
||||
int unregister_device(const char *device, const char *uuid, int major, int minor,
|
||||
void **unused __attribute((unused)))
|
||||
int unregister_device(const char *device,
|
||||
const char *uuid __attribute((unused)),
|
||||
int major __attribute((unused)),
|
||||
int minor __attribute((unused)),
|
||||
void **unused __attribute((unused)))
|
||||
{
|
||||
pthread_mutex_lock(&_register_mutex);
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#
|
||||
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
# Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
|
||||
# Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
|
||||
#
|
||||
# This file is part of LVM2.
|
||||
# This file is part of the LVM2.
|
||||
#
|
||||
# This copyrighted material is made available to anyone wishing to use,
|
||||
# modify, copy, or redistribute it subject to the terms and conditions
|
||||
@@ -17,20 +17,21 @@ top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
INCLUDES += -I${top_srcdir}/tools
|
||||
CLDFLAGS += -L${top_srcdir}/tools -ldevmapper -llvm2cmd
|
||||
CLDFLAGS += -L${top_srcdir}/tools -ldevmapper @LVM2CMD_LIB@
|
||||
|
||||
SOURCES = dmeventd_mirror.c
|
||||
SOURCES = dmeventd_snapshot.c
|
||||
|
||||
ifeq ("@LIB_SUFFIX@","dylib")
|
||||
LIB_SHARED = libdevmapper-event-lvm2mirror.dylib
|
||||
LIB_SHARED = libdevmapper-event-lvm2snapshot.dylib
|
||||
else
|
||||
LIB_SHARED = libdevmapper-event-lvm2mirror.so
|
||||
LIB_SHARED = libdevmapper-event-lvm2snapshot.so
|
||||
endif
|
||||
|
||||
LIB_VERSION = $(LIB_VERSION_LVM)
|
||||
|
||||
include $(top_srcdir)/make.tmpl
|
||||
|
||||
install: libdevmapper-event-lvm2mirror.$(LIB_SUFFIX)
|
||||
install: libdevmapper-event-lvm2snapshot.$(LIB_SUFFIX)
|
||||
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \
|
||||
$(libdir)/$<.$(LIB_VERSION)
|
||||
$(LN_S) -f $<.$(LIB_VERSION) $(libdir)/$<
|
||||
|
||||
213
daemons/dmeventd/plugins/snapshot/dmeventd_snapshot.c
Normal file
213
daemons/dmeventd/plugins/snapshot/dmeventd_snapshot.c
Normal file
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* Copyright (C) 2007-2008 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use,
|
||||
* modify, copy, or redistribute it subject to the terms and conditions
|
||||
* of the GNU Lesser General Public License v.2.1.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "libdevmapper.h"
|
||||
#include "libdevmapper-event.h"
|
||||
#include "lvm2cmd.h"
|
||||
#include "lvm-string.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <syslog.h> /* FIXME Replace syslog with multilog */
|
||||
/* FIXME Missing openlog? */
|
||||
|
||||
/* First warning when snapshot is 80% full. */
|
||||
#define WARNING_THRESH 80
|
||||
/* Further warnings at 85%, 90% and 95% fullness. */
|
||||
#define WARNING_STEP 5
|
||||
|
||||
static pthread_mutex_t _register_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/*
|
||||
* Number of active registrations.
|
||||
*/
|
||||
static int _register_count = 0;
|
||||
|
||||
static struct dm_pool *_mem_pool = NULL;
|
||||
static void *_lvm_handle = NULL;
|
||||
|
||||
struct snap_status {
|
||||
int invalid;
|
||||
int used;
|
||||
int max;
|
||||
};
|
||||
|
||||
/*
|
||||
* Currently only one event can be processed at a time.
|
||||
*/
|
||||
static pthread_mutex_t _event_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static void _temporary_log_fn(int level,
|
||||
const char *file __attribute((unused)),
|
||||
int line __attribute((unused)),
|
||||
const char *format)
|
||||
{
|
||||
if (!strncmp(format, "WARNING: ", 9) && (level < 5))
|
||||
syslog(LOG_CRIT, "%s", format);
|
||||
else
|
||||
syslog(LOG_DEBUG, "%s", format);
|
||||
}
|
||||
|
||||
/* FIXME possibly reconcile this with target_percent when we gain
|
||||
access to regular LVM library here. */
|
||||
static void _parse_snapshot_params(char *params, struct snap_status *stat)
|
||||
{
|
||||
char *p;
|
||||
/*
|
||||
* xx/xx -- fractions used/max
|
||||
* Invalid -- snapshot invalidated
|
||||
* Unknown -- status unknown
|
||||
*/
|
||||
stat->used = stat->max = 0;
|
||||
|
||||
if (!strncmp(params, "Invalid", 7)) {
|
||||
stat->invalid = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* When we return without setting non-zero max, the parent is
|
||||
* responsible for reporting errors.
|
||||
*/
|
||||
if (!strncmp(params, "Unknown", 7))
|
||||
return;
|
||||
|
||||
if (!(p = strstr(params, "/")))
|
||||
return;
|
||||
|
||||
*p = '\0';
|
||||
p++;
|
||||
|
||||
stat->used = atoi(params);
|
||||
stat->max = atoi(p);
|
||||
}
|
||||
|
||||
void process_event(struct dm_task *dmt,
|
||||
enum dm_event_mask event __attribute((unused)),
|
||||
void **private)
|
||||
{
|
||||
void *next = NULL;
|
||||
uint64_t start, length;
|
||||
char *target_type = NULL;
|
||||
char *params;
|
||||
struct snap_status stat = { 0 };
|
||||
const char *device = dm_task_get_name(dmt);
|
||||
int percent, *percent_warning = (int*)private;
|
||||
|
||||
/* No longer monitoring, waiting for remove */
|
||||
if (!*percent_warning)
|
||||
return;
|
||||
|
||||
if (pthread_mutex_trylock(&_event_mutex)) {
|
||||
syslog(LOG_NOTICE, "Another thread is handling an event. Waiting...");
|
||||
pthread_mutex_lock(&_event_mutex);
|
||||
}
|
||||
|
||||
dm_get_next_target(dmt, next, &start, &length, &target_type, ¶ms);
|
||||
if (!target_type)
|
||||
goto out;
|
||||
|
||||
_parse_snapshot_params(params, &stat);
|
||||
/*
|
||||
* If the snapshot has been invalidated or we failed to parse
|
||||
* the status string. Report the full status string to syslog.
|
||||
*/
|
||||
if (stat.invalid || !stat.max) {
|
||||
syslog(LOG_ERR, "Snapshot %s changed state to: %s\n", device, params);
|
||||
*percent_warning = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
percent = 100 * stat.used / stat.max;
|
||||
if (percent >= *percent_warning) {
|
||||
syslog(LOG_WARNING, "Snapshot %s is now %i%% full.\n", device, percent);
|
||||
/* Print warning on the next multiple of WARNING_STEP. */
|
||||
*percent_warning = (percent / WARNING_STEP) * WARNING_STEP + WARNING_STEP;
|
||||
}
|
||||
out:
|
||||
pthread_mutex_unlock(&_event_mutex);
|
||||
}
|
||||
|
||||
int register_device(const char *device,
|
||||
const char *uuid __attribute((unused)),
|
||||
int major __attribute((unused)),
|
||||
int minor __attribute((unused)),
|
||||
void **private)
|
||||
{
|
||||
int r = 0;
|
||||
int *percent_warning = (int*)private;
|
||||
|
||||
pthread_mutex_lock(&_register_mutex);
|
||||
|
||||
/*
|
||||
* Need some space for allocations. 1024 should be more
|
||||
* than enough for what we need (device mapper name splitting)
|
||||
*/
|
||||
if (!_mem_pool && !(_mem_pool = dm_pool_create("snapshot_dso", 1024)))
|
||||
goto out;
|
||||
|
||||
*percent_warning = WARNING_THRESH; /* Print warning if snapshot is full */
|
||||
|
||||
if (!_lvm_handle) {
|
||||
lvm2_log_fn(_temporary_log_fn);
|
||||
if (!(_lvm_handle = lvm2_init())) {
|
||||
dm_pool_destroy(_mem_pool);
|
||||
_mem_pool = NULL;
|
||||
goto out;
|
||||
}
|
||||
lvm2_log_level(_lvm_handle, LVM2_LOG_SUPPRESS);
|
||||
/* FIXME Temporary: move to dmeventd core */
|
||||
lvm2_run(_lvm_handle, "_memlock_inc");
|
||||
}
|
||||
|
||||
syslog(LOG_INFO, "Monitoring snapshot %s\n", device);
|
||||
|
||||
_register_count++;
|
||||
r = 1;
|
||||
|
||||
out:
|
||||
pthread_mutex_unlock(&_register_mutex);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int unregister_device(const char *device,
|
||||
const char *uuid __attribute((unused)),
|
||||
int major __attribute((unused)),
|
||||
int minor __attribute((unused)),
|
||||
void **unused __attribute((unused)))
|
||||
{
|
||||
pthread_mutex_lock(&_register_mutex);
|
||||
|
||||
syslog(LOG_INFO, "No longer monitoring snapshot %s\n",
|
||||
device);
|
||||
|
||||
if (!--_register_count) {
|
||||
dm_pool_destroy(_mem_pool);
|
||||
_mem_pool = NULL;
|
||||
lvm2_run(_lvm_handle, "_memlock_dec");
|
||||
lvm2_exit(_lvm_handle);
|
||||
_lvm_handle = NULL;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&_register_mutex);
|
||||
|
||||
return 1;
|
||||
}
|
||||
6
debian/README.Debian
vendored
6
debian/README.Debian
vendored
@@ -1,6 +0,0 @@
|
||||
LVM2 requires the device-mapper kernel module (dm-mod). This is
|
||||
available as a kernel patch for 2.4 (in kernel-patch-device-mapper), and
|
||||
is distributed with linux 2.5 and above. The LVM1 kernel module (lvm-mod)
|
||||
will not work with lvm2 packages. dm-mod and lvm-mod may both be loaded
|
||||
in the kernel at the same time with no problems. Without dm-mod, this
|
||||
package is pretty useless.
|
||||
82
debian/changelog
vendored
82
debian/changelog
vendored
@@ -1,82 +0,0 @@
|
||||
lvm2 (1.95.15-1) unstable; urgency=low
|
||||
|
||||
* New upstream release.
|
||||
* Remove undocumented manpage symlinks.
|
||||
* Update description to be more informative. (Closes: #173499)
|
||||
* Add kernel-patch-device-mapper suggestion.
|
||||
* Update standards version.
|
||||
|
||||
-- Andres Salomon <dilinger@mp3revolution.net> Sun, 16 Feb 2002 04:21:26 -0400
|
||||
|
||||
lvm2 (1.95.11-1) unstable; urgency=low
|
||||
|
||||
* New upstream release. (Closes: #171436)
|
||||
* Removed TODO and INTRO from debian/docs; added WHATS_NEW.
|
||||
* Remove vgcfgrestore.8 undocumented symlink.
|
||||
* Added a README.Debian, mentioning the device-mapper kernel module
|
||||
requirement that lvm2 has. (Closes: #171674, #163020)
|
||||
* Get rid of debian/conffiles (debhelper's smart enough to figure that out).
|
||||
* debian/copyright fix to appease lintian.
|
||||
* Fix typo in tools/commands.h that caused /usr/sbin/; to be created.
|
||||
|
||||
-- Andres Salomon <dilinger@mp3revolution.net> Mon, 9 Dec 2002 02:51:02 -0400
|
||||
|
||||
lvm2 (1.95.10-2) unstable; urgency=low
|
||||
|
||||
* Fix software raid problems by ensuring lvm init script runs after
|
||||
raidtools init script. (Closes: #152569)
|
||||
|
||||
-- Andres Salomon <dilinger@mp3revolution.net> Tue, 3 Sep 2002 04:05:43 -0400
|
||||
|
||||
lvm2 (1.95.10-1) unstable; urgency=low
|
||||
|
||||
* New upstream release (Beta 3.2).
|
||||
* Change all references to /dev/device-mapper/control to
|
||||
/dev/mapper/control.
|
||||
|
||||
-- Andres Salomon <dilinger@mp3revolution.net> Sun, 1 Sep 2002 18:55:12 -0400
|
||||
|
||||
lvm2 (0.95.05-3) unstable; urgency=low
|
||||
|
||||
* Get rid of awk dependency in init script. (Closes: #146257)
|
||||
|
||||
-- Andres Salomon <dilinger@mp3revolution.net> Sun, 12 May 2002 04:39:06 -0500
|
||||
|
||||
lvm2 (0.95.05-2) unstable; urgency=low
|
||||
|
||||
* Use ${shlibs:Depends} in Depends.
|
||||
* Get rid of postinst/postrm scripts, use debhelper's init script instead.
|
||||
* Add Conflicts against lvm10, lvm-common.
|
||||
* Fix endian issues on big-endian machines.
|
||||
|
||||
-- Andres Salomon <dilinger@mp3revolution.net> Thu, 2 May 2002 23:53:53 -0500
|
||||
|
||||
lvm2 (0.95.05-1) unstable; urgency=low
|
||||
|
||||
* New release (Beta2).
|
||||
|
||||
-- Andres Salomon <dilinger@mp3revolution.net> Thu, 25 Apr 2002 00:37:41 -0500
|
||||
|
||||
lvm2 (0.95.04cvs20020306-1) unstable; urgency=low
|
||||
|
||||
* CVS updated.
|
||||
* Convert from debian native package.
|
||||
|
||||
-- Andres Salomon <dilinger@mp3revolution.net> Wed, 6 Mar 2002 00:43:21 -0500
|
||||
|
||||
lvm2 (0.95.04cvs20020304) unstable; urgency=low
|
||||
|
||||
* CVS updated.
|
||||
* Enhance init script; create devmapper control device, etc.
|
||||
* Add dmsetup as a suggestion.
|
||||
* Add /etc/lvm/lvm.conf conffile.
|
||||
* Add undocumented(7) for the commands missing manpages.
|
||||
|
||||
-- Andres Salomon <dilinger@mp3revolution.net> Mon, 4 Mar 2002 04:51:26 -0500
|
||||
|
||||
lvm2 (0.95.02cvs20020220) unstable; urgency=low
|
||||
|
||||
* Initial Release.
|
||||
|
||||
-- Andres Salomon <dilinger@mp3revolution.net> Wed, 20 Feb 2002 03:17:25 -0500
|
||||
|
||||
24
debian/control
vendored
24
debian/control
vendored
@@ -1,24 +0,0 @@
|
||||
Source: lvm2
|
||||
Section: admin
|
||||
Priority: optional
|
||||
Maintainer: Andres Salomon <dilinger@mp3revolution.net>
|
||||
Build-Depends: debhelper (>> 3.0.0), libdevmapper-dev (>= 0.96.04), libreadline4-dev
|
||||
Standards-Version: 3.5.8.0
|
||||
|
||||
Package: lvm2
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}
|
||||
Conflicts: lvm10, lvm-common
|
||||
Replaces: lvm10, lvm-common
|
||||
Provides: lvm-binaries
|
||||
Suggests: dmsetup, kernel-patch-device-mapper
|
||||
Description: The Linux Logical Volume Manager
|
||||
This is LVM2, the rewrite of The Linux Logical Volume Manager. LVM
|
||||
supports enterprise level volume management of disk and disk subsystems
|
||||
by grouping arbitrary disks into volume groups. The total capacity of
|
||||
volume groups can be allocated to logical volumes, which are accessed as
|
||||
regular block devices.
|
||||
.
|
||||
LVM2 is currently stable, but has some unimplemented features (most notably,
|
||||
pvmove and e2fsadm). It is not yet recommended for production use. It is
|
||||
backwards-compatible with LVM1 (lvm10), and requires Linux kernel 2.4.
|
||||
25
debian/copyright
vendored
25
debian/copyright
vendored
@@ -1,25 +0,0 @@
|
||||
This package was debianized by Andres Salomon <dilinger@mp3revolution.net> on
|
||||
Wed, 20 Feb 2002 03:17:25 -0500.
|
||||
|
||||
It was downloaded from http://www.sistina.com/products_lvm.htm
|
||||
|
||||
Upstream Author: LVM Development Team
|
||||
|
||||
Copyright (c) 2001-2002 LVM Development Team
|
||||
|
||||
LVM2 is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
LVM2 is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
|
||||
On Debian systems, the full text of the GPL can be found in
|
||||
/usr/share/common-licenses/GPL
|
||||
4
debian/dirs
vendored
4
debian/dirs
vendored
@@ -1,4 +0,0 @@
|
||||
etc/lvm
|
||||
usr/share/man/man5
|
||||
usr/share/man/man8
|
||||
sbin
|
||||
5
debian/docs
vendored
5
debian/docs
vendored
@@ -1,5 +0,0 @@
|
||||
BUGS
|
||||
README
|
||||
VERSION
|
||||
WHATS_NEW
|
||||
doc/*
|
||||
64
debian/init.d
vendored
64
debian/init.d
vendored
@@ -1,64 +0,0 @@
|
||||
#! /bin/sh
|
||||
#
|
||||
# lvm2 This script handles LVM2 initialization/shutdown.
|
||||
#
|
||||
# Written by Andres Salomon <dilinger@mp3revolution.net>.
|
||||
#
|
||||
|
||||
PATH=/sbin:/bin:/usr/sbin:/usr/bin
|
||||
NAME=lvm2
|
||||
DESC=LVM
|
||||
|
||||
test -x /sbin/vgchange || exit 0
|
||||
modprobe dm-mod >/dev/null 2>&1
|
||||
|
||||
# Create necessary files in /dev for device-mapper
|
||||
create_devfiles() {
|
||||
DIR="/dev/mapper"
|
||||
FILE="$DIR/control"
|
||||
major=$(grep "[0-9] misc$" /proc/devices | sed 's/[ ]\+misc//')
|
||||
minor=$(grep "[0-9] device-mapper$" /proc/misc | sed 's/[ ]\+device-mapper//')
|
||||
|
||||
if test ! -d $DIR; then
|
||||
mkdir --mode=755 $DIR >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
if test ! -c $FILE -a ! -z "$minor"; then
|
||||
mknod --mode=600 $FILE c $major $minor >/dev/null 2>&1
|
||||
fi
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
echo -n "Initializing $DESC: "
|
||||
create_devfiles
|
||||
vgchange -a y
|
||||
|
||||
# # Mount all LVM devices
|
||||
# for vg in $( vgchange -a y 2>/dev/null | grep active | awk -F\" '{print $2}' ); do
|
||||
# MTPT=$( grep $vg /etc/fstab | awk '{print $2}' )
|
||||
# mount $MTPT
|
||||
# done
|
||||
echo "$NAME."
|
||||
;;
|
||||
stop)
|
||||
echo -n "Shutting down $DESC: "
|
||||
# We don't really try all that hard to shut it down; far too many
|
||||
# things that can keep it from successfully shutting down.
|
||||
vgchange -a n
|
||||
echo "$NAME."
|
||||
;;
|
||||
restart|force-reload)
|
||||
echo -n "Restarting $DESC: "
|
||||
vgchange -a n
|
||||
sleep 1
|
||||
vgchange -a y
|
||||
echo "$NAME."
|
||||
;;
|
||||
*)
|
||||
echo "Usage: /etc/init.d/$NAME {start|stop|restart|force-reload}" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
26
debian/manpages
vendored
26
debian/manpages
vendored
@@ -1,26 +0,0 @@
|
||||
debian/lvm2/usr/share/man/man5/lvm.conf.5
|
||||
debian/lvm2/usr/share/man/man8/lvchange.8
|
||||
debian/lvm2/usr/share/man/man8/lvcreate.8
|
||||
debian/lvm2/usr/share/man/man8/lvdisplay.8
|
||||
debian/lvm2/usr/share/man/man8/lvextend.8
|
||||
debian/lvm2/usr/share/man/man8/lvm.8
|
||||
debian/lvm2/usr/share/man/man8/lvmchange.8
|
||||
debian/lvm2/usr/share/man/man8/lvreduce.8
|
||||
debian/lvm2/usr/share/man/man8/lvremove.8
|
||||
debian/lvm2/usr/share/man/man8/lvrename.8
|
||||
debian/lvm2/usr/share/man/man8/lvscan.8
|
||||
debian/lvm2/usr/share/man/man8/pvchange.8
|
||||
debian/lvm2/usr/share/man/man8/pvcreate.8
|
||||
debian/lvm2/usr/share/man/man8/pvdisplay.8
|
||||
debian/lvm2/usr/share/man/man8/pvscan.8
|
||||
debian/lvm2/usr/share/man/man8/vgcfgbackup.8
|
||||
debian/lvm2/usr/share/man/man8/vgchange.8
|
||||
debian/lvm2/usr/share/man/man8/vgck.8
|
||||
debian/lvm2/usr/share/man/man8/vgcreate.8
|
||||
debian/lvm2/usr/share/man/man8/vgdisplay.8
|
||||
debian/lvm2/usr/share/man/man8/vgextend.8
|
||||
debian/lvm2/usr/share/man/man8/vgmerge.8
|
||||
debian/lvm2/usr/share/man/man8/vgreduce.8
|
||||
debian/lvm2/usr/share/man/man8/vgremove.8
|
||||
debian/lvm2/usr/share/man/man8/vgrename.8
|
||||
debian/lvm2/usr/share/man/man8/vgscan.8
|
||||
119
debian/rules
vendored
119
debian/rules
vendored
@@ -1,119 +0,0 @@
|
||||
#!/usr/bin/make -f
|
||||
# Sample debian/rules that uses debhelper.
|
||||
# GNU copyright 1997 by Joey Hess.
|
||||
#
|
||||
# This version is for a hypothetical package that builds an
|
||||
# architecture-dependant package, as well as an architecture-independent
|
||||
# package.
|
||||
|
||||
# Uncomment this to turn on verbose mode.
|
||||
#export DH_VERBOSE=1
|
||||
|
||||
# This is the debhelper compatibility version to use.
|
||||
export DH_COMPAT=3
|
||||
|
||||
# These are used for cross-compiling and for saving the configure script
|
||||
# from having to guess our platform (since we know it already)
|
||||
DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
|
||||
DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
|
||||
|
||||
ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS)))
|
||||
CFLAGS += -g
|
||||
endif
|
||||
ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
|
||||
INSTALL_PROGRAM += -s
|
||||
endif
|
||||
|
||||
configure: configure-stamp
|
||||
configure-stamp:
|
||||
dh_testdir
|
||||
# Add here commands to configure the package.
|
||||
./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) --prefix=/ --mandir=\$${prefix}/usr/share/man --infodir=\$${prefix}/usr/share/info
|
||||
|
||||
touch configure-stamp
|
||||
|
||||
build-arch: configure-stamp build-arch-stamp
|
||||
build-arch-stamp:
|
||||
dh_testdir
|
||||
|
||||
# Add here command to compile/build the package.
|
||||
$(MAKE)
|
||||
|
||||
touch build-arch-stamp
|
||||
|
||||
build-indep: configure-stamp build-indep-stamp
|
||||
build-indep-stamp:
|
||||
dh_testdir
|
||||
|
||||
# Add here command to compile/build the arch indep package.
|
||||
# It's ok not to do anything here, if you don't need to build
|
||||
# anything for this package.
|
||||
#/usr/bin/docbook-to-man debian/lvm2.sgml > lvm2.1
|
||||
|
||||
touch build-indep-stamp
|
||||
|
||||
build: build-arch build-indep
|
||||
|
||||
clean:
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
rm -f build-stamp configure-stamp
|
||||
|
||||
# Add here commands to clean up after the build process.
|
||||
-$(MAKE) distclean
|
||||
-test -r /usr/share/misc/config.sub && \
|
||||
cp -f /usr/share/misc/config.sub config.sub
|
||||
-test -r /usr/share/misc/config.guess && \
|
||||
cp -f /usr/share/misc/config.guess config.guess
|
||||
|
||||
|
||||
dh_clean
|
||||
|
||||
install: DH_OPTIONS=
|
||||
install: build
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
dh_clean -k
|
||||
dh_installdirs
|
||||
|
||||
# Add here commands to install the package into debian/lvm2.
|
||||
$(MAKE) install prefix=$(CURDIR)/debian/lvm2
|
||||
install -m 0644 doc/example.conf debian/lvm2/etc/lvm/lvm.conf
|
||||
|
||||
|
||||
# Build architecture-independent files here.
|
||||
# Pass -i to all debhelper commands in this target to reduce clutter.
|
||||
binary-indep: build install
|
||||
# nada.
|
||||
|
||||
# Build architecture-dependent files here.
|
||||
binary-arch: build install
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
|
||||
# dh_installdebconf
|
||||
dh_installdocs
|
||||
dh_installexamples
|
||||
# dh_installlogrotate -a
|
||||
# dh_installemacsen -a
|
||||
# dh_installpam -a
|
||||
# dh_installmime -a
|
||||
dh_installinit --update-rcd-params="start 26 S . start 50 0 6 ."
|
||||
dh_installcron
|
||||
dh_installman
|
||||
dh_installinfo
|
||||
dh_installchangelogs
|
||||
dh_strip
|
||||
dh_link
|
||||
dh_compress
|
||||
dh_fixperms
|
||||
dh_makeshlibs
|
||||
dh_installdeb
|
||||
# dh_perl -a
|
||||
dh_shlibdeps
|
||||
dh_gencontrol
|
||||
dh_md5sums
|
||||
dh_builddeb
|
||||
|
||||
binary: binary-indep binary-arch
|
||||
.PHONY: build clean binary-indep binary-arch binary install configure
|
||||
@@ -1,281 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use,
|
||||
* modify, copy, or redistribute it subject to the terms and conditions
|
||||
* of the GNU Lesser General Public License v.2.1.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "lvm2cmd.h"
|
||||
|
||||
#include <libdevmapper.h>
|
||||
#include <libdevmapper-event.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <syslog.h> /* FIXME Replace syslog with multilog */
|
||||
/* FIXME Missing openlog? */
|
||||
|
||||
#define ME_IGNORE 0
|
||||
#define ME_INSYNC 1
|
||||
#define ME_FAILURE 2
|
||||
|
||||
/*
|
||||
* register_device() is called first and performs initialisation.
|
||||
* Only one device may be registered or unregistered at a time.
|
||||
*/
|
||||
static pthread_mutex_t _register_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/*
|
||||
* Number of active registrations.
|
||||
*/
|
||||
static int _register_count = 0;
|
||||
|
||||
static struct dm_pool *_mem_pool = NULL;
|
||||
static void *_lvm_handle = NULL;
|
||||
|
||||
/*
|
||||
* Currently only one event can be processed at a time.
|
||||
*/
|
||||
static pthread_mutex_t _event_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static int _get_mirror_event(char *params)
|
||||
{
|
||||
int i, r = ME_INSYNC;
|
||||
char **args = NULL;
|
||||
char *dev_status_str;
|
||||
char *log_status_str;
|
||||
char *sync_str;
|
||||
char *p = NULL;
|
||||
int log_argc, num_devs;
|
||||
|
||||
/*
|
||||
* dm core parms: 0 409600 mirror
|
||||
* 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)))
|
||||
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;
|
||||
|
||||
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 */
|
||||
for (i = 0; i < num_devs; i++)
|
||||
if (dev_status_str[i] == 'D') {
|
||||
syslog(LOG_ERR, "Mirror device, %s, has failed.\n", args[i]);
|
||||
r = ME_FAILURE;
|
||||
}
|
||||
|
||||
/* Check for bad disk log device */
|
||||
if (log_argc > 1 && log_status_str[0] == 'D') {
|
||||
syslog(LOG_ERR, "Log device, %s, has failed.\n",
|
||||
args[2 + num_devs + log_argc]);
|
||||
r = ME_FAILURE;
|
||||
}
|
||||
|
||||
if (r == ME_FAILURE)
|
||||
goto out;
|
||||
|
||||
p = strstr(sync_str, "/");
|
||||
if (p) {
|
||||
p[0] = '\0';
|
||||
if (strcmp(sync_str, p+1))
|
||||
r = ME_IGNORE;
|
||||
p[0] = '/';
|
||||
} else
|
||||
goto out_parse;
|
||||
|
||||
out:
|
||||
if (args)
|
||||
dm_free(args);
|
||||
return r;
|
||||
|
||||
out_parse:
|
||||
if (args)
|
||||
dm_free(args);
|
||||
syslog(LOG_ERR, "Unable to parse mirror status string.");
|
||||
return ME_IGNORE;
|
||||
}
|
||||
|
||||
static void _temporary_log_fn(int level, const char *file,
|
||||
int line, const char *format)
|
||||
{
|
||||
if (!strncmp(format, "WARNING: ", 9) && (level < 5))
|
||||
syslog(LOG_CRIT, "%s", format);
|
||||
else
|
||||
syslog(LOG_DEBUG, "%s", format);
|
||||
}
|
||||
|
||||
static int _remove_failed_devices(const char *device)
|
||||
{
|
||||
int r;
|
||||
#define CMD_SIZE 256 /* FIXME Use system restriction */
|
||||
char cmd_str[CMD_SIZE];
|
||||
char *vg = NULL, *lv = NULL, *layer = NULL;
|
||||
|
||||
if (strlen(device) > 200) /* FIXME Use real restriction */
|
||||
return -ENAMETOOLONG; /* FIXME These return code distinctions are not used so remove them! */
|
||||
|
||||
if (!dm_split_lvm_name(_mem_pool, device, &vg, &lv, &layer)) {
|
||||
syslog(LOG_ERR, "Unable to determine VG name from %s",
|
||||
device);
|
||||
return -ENOMEM; /* FIXME Replace with generic error return - reason for failure has already got logged */
|
||||
}
|
||||
|
||||
/* FIXME Is any sanity-checking required on %s? */
|
||||
if (CMD_SIZE <= snprintf(cmd_str, CMD_SIZE, "vgreduce --config devices{ignore_suspended_devices=1} --removemissing %s", vg)) {
|
||||
/* this error should be caught above, but doesn't hurt to check again */
|
||||
syslog(LOG_ERR, "Unable to form LVM command: Device name too long");
|
||||
dm_pool_empty(_mem_pool); /* FIXME: not safe with multiple threads */
|
||||
return -ENAMETOOLONG; /* FIXME Replace with generic error return - reason for failure has already got logged */
|
||||
}
|
||||
|
||||
r = lvm2_run(_lvm_handle, cmd_str);
|
||||
|
||||
dm_pool_empty(_mem_pool); /* FIXME: not safe with multiple threads */
|
||||
return (r == 1) ? 0 : -1;
|
||||
}
|
||||
|
||||
void process_event(struct dm_task *dmt, enum dm_event_mask event,
|
||||
void **unused __attribute((unused)))
|
||||
{
|
||||
void *next = NULL;
|
||||
uint64_t start, length;
|
||||
char *target_type = NULL;
|
||||
char *params;
|
||||
const char *device = dm_task_get_name(dmt);
|
||||
|
||||
if (pthread_mutex_trylock(&_event_mutex)) {
|
||||
syslog(LOG_NOTICE, "Another thread is handling an event. Waiting...");
|
||||
pthread_mutex_lock(&_event_mutex);
|
||||
}
|
||||
do {
|
||||
next = dm_get_next_target(dmt, next, &start, &length,
|
||||
&target_type, ¶ms);
|
||||
|
||||
if (!target_type) {
|
||||
syslog(LOG_INFO, "%s mapping lost.\n", device);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(target_type, "mirror")) {
|
||||
syslog(LOG_INFO, "%s has unmirrored portion.\n", device);
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(_get_mirror_event(params)) {
|
||||
case ME_INSYNC:
|
||||
/* FIXME: all we really know is that this
|
||||
_part_ of the device is in sync
|
||||
Also, this is not an error
|
||||
*/
|
||||
syslog(LOG_NOTICE, "%s is now in-sync\n", device);
|
||||
break;
|
||||
case ME_FAILURE:
|
||||
syslog(LOG_ERR, "Device failure in %s\n", device);
|
||||
if (_remove_failed_devices(device))
|
||||
/* FIXME Why are all the error return codes unused? Get rid of them? */
|
||||
syslog(LOG_ERR, "Failed to remove faulty devices in %s\n",
|
||||
device);
|
||||
/* Should check before warning user that device is now linear
|
||||
else
|
||||
syslog(LOG_NOTICE, "%s is now a linear device.\n",
|
||||
device);
|
||||
*/
|
||||
break;
|
||||
case ME_IGNORE:
|
||||
break;
|
||||
default:
|
||||
/* FIXME Provide value then! */
|
||||
syslog(LOG_INFO, "Unknown event received.\n");
|
||||
}
|
||||
} while (next);
|
||||
|
||||
pthread_mutex_unlock(&_event_mutex);
|
||||
}
|
||||
|
||||
int register_device(const char *device, const char *uuid, int major, int minor,
|
||||
void **unused __attribute((unused)))
|
||||
{
|
||||
int r = 0;
|
||||
|
||||
pthread_mutex_lock(&_register_mutex);
|
||||
|
||||
syslog(LOG_INFO, "Monitoring mirror device %s for events\n", device);
|
||||
|
||||
/*
|
||||
* Need some space for allocations. 1024 should be more
|
||||
* than enough for what we need (device mapper name splitting)
|
||||
*/
|
||||
if (!_mem_pool && !(_mem_pool = dm_pool_create("mirror_dso", 1024)))
|
||||
goto out;
|
||||
|
||||
if (!_lvm_handle) {
|
||||
lvm2_log_fn(_temporary_log_fn);
|
||||
if (!(_lvm_handle = lvm2_init())) {
|
||||
dm_pool_destroy(_mem_pool);
|
||||
_mem_pool = NULL;
|
||||
goto out;
|
||||
}
|
||||
lvm2_log_level(_lvm_handle, LVM2_LOG_SUPPRESS);
|
||||
/* FIXME Temporary: move to dmeventd core */
|
||||
lvm2_run(_lvm_handle, "_memlock_inc");
|
||||
}
|
||||
|
||||
_register_count++;
|
||||
r = 1;
|
||||
|
||||
out:
|
||||
pthread_mutex_unlock(&_register_mutex);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int unregister_device(const char *device, const char *uuid, int major, int minor,
|
||||
void **unused __attribute((unused)))
|
||||
{
|
||||
pthread_mutex_lock(&_register_mutex);
|
||||
|
||||
syslog(LOG_INFO, "No longer monitoring mirror device %s for events\n",
|
||||
device);
|
||||
|
||||
if (!--_register_count) {
|
||||
dm_pool_destroy(_mem_pool);
|
||||
_mem_pool = NULL;
|
||||
lvm2_run(_lvm_handle, "_memlock_dec");
|
||||
lvm2_exit(_lvm_handle);
|
||||
_lvm_handle = NULL;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&_register_mutex);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -25,7 +25,8 @@ devices {
|
||||
# list of regular expressions in turn and the first match is used.
|
||||
preferred_names = [ ]
|
||||
|
||||
# preferred_names = [ "^/dev/mpath/", "^/dev/[hs]d" ]
|
||||
# Try to avoid using undescriptive /dev/dm-N names, if present.
|
||||
# preferred_names = [ "^/dev/mpath/", "^/dev/mapper/mpath", "^/dev/[hs]d" ]
|
||||
|
||||
# A filter that tells LVM2 to only use a restricted set of devices.
|
||||
# The filter consists of an array of regular expressions. These
|
||||
@@ -92,6 +93,11 @@ devices {
|
||||
# 1 enables; 0 disables.
|
||||
md_component_detection = 1
|
||||
|
||||
# By default, if a PV is placed directly upon an md device, LVM2
|
||||
# will align its data blocks with the the chunk_size exposed in sysfs.
|
||||
# 1 enables; 0 disables.
|
||||
md_chunk_alignment = 1
|
||||
|
||||
# If, while scanning the system for PVs, LVM2 encounters a device-mapper
|
||||
# device that has its I/O suspended, it waits for it to become accessible.
|
||||
# Set this to 1 to skip such devices. This should only be needed
|
||||
@@ -265,11 +271,13 @@ global {
|
||||
}
|
||||
|
||||
activation {
|
||||
# Device used in place of missing stripes if activating incomplete volume.
|
||||
# For now, you need to set this up yourself first (e.g. with 'dmsetup')
|
||||
# For example, you could make it return I/O errors using the 'error'
|
||||
# target or make it return zeros.
|
||||
missing_stripe_filler = "/dev/ioerror"
|
||||
# How to fill in missing stripes if activating an incomplete volume.
|
||||
# Using "error" will make inaccessible parts of the device return
|
||||
# I/O errors on access. You can instead use a device path, in which
|
||||
# case, that device will be used to in place of missing stripes.
|
||||
# But note that using anything other than "error" with mirrored
|
||||
# or snapshotted volumes is likely to result in data corruption.
|
||||
missing_stripe_filler = "error"
|
||||
|
||||
# How much stack (in KB) to reserve for use while devices suspended
|
||||
reserved_stack = 256
|
||||
@@ -384,10 +392,20 @@ activation {
|
||||
# dmeventd {
|
||||
# mirror_library is the library used when monitoring a mirror device.
|
||||
#
|
||||
# "libdevmapper-event-lvm2mirror.so" attempts to recover from failures.
|
||||
# It removes failed devices from a volume group and reconfigures a
|
||||
# mirror as necessary.
|
||||
#
|
||||
# "libdevmapper-event-lvm2mirror.so" attempts to recover from
|
||||
# failures. It removes failed devices from a volume group and
|
||||
# reconfigures a mirror as necessary. If no mirror library is
|
||||
# provided, mirrors are not monitored through dmeventd.
|
||||
|
||||
# mirror_library = "libdevmapper-event-lvm2mirror.so"
|
||||
|
||||
# snapshot_library is the library used when monitoring a snapshot device.
|
||||
#
|
||||
# "libdevmapper-event-lvm2snapshot.so" monitors the filling of
|
||||
# snapshots and emits a warning through syslog, when the use of
|
||||
# snapshot exceedes 80%. The warning is repeated when 85%, 90% and
|
||||
# 95% of the snapshot are filled.
|
||||
|
||||
# snapshot_library = "libdevmapper-event-lvm2snapshot.so"
|
||||
#}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
../daemons/clvmd/clvm.h
|
||||
../daemons/dmeventd/libdevmapper-event.h
|
||||
../lib/activate/activate.h
|
||||
../lib/activate/targets.h
|
||||
../lib/cache/lvmcache.h
|
||||
@@ -7,7 +8,6 @@
|
||||
../lib/config/config.h
|
||||
../lib/config/defaults.h
|
||||
../lib/datastruct/btree.h
|
||||
../lib/datastruct/list.h
|
||||
../lib/datastruct/lvm-types.h
|
||||
../lib/datastruct/str_list.h
|
||||
../lib/device/dev-cache.h
|
||||
@@ -28,6 +28,7 @@
|
||||
../lib/label/label.h
|
||||
../lib/locking/locking.h
|
||||
../lib/log/log.h
|
||||
../lib/log/lvm-logging.h
|
||||
../lib/metadata/lv_alloc.h
|
||||
../lib/metadata/metadata.h
|
||||
../lib/metadata/metadata-exported.h
|
||||
@@ -43,10 +44,16 @@
|
||||
../lib/misc/lib.h
|
||||
../lib/misc/lvm-exec.h
|
||||
../lib/misc/lvm-file.h
|
||||
../lib/misc/lvm-globals.h
|
||||
../lib/misc/lvm-string.h
|
||||
../lib/misc/lvm-wrappers.h
|
||||
../lib/misc/sharedlib.h
|
||||
../lib/report/report.h
|
||||
../lib/uuid/uuid.h
|
||||
../libdm/libdevmapper.h
|
||||
../libdm/misc/dm-ioctl.h
|
||||
../libdm/misc/dm-logging.h
|
||||
../libdm/misc/dmlib.h
|
||||
../libdm/misc/kdev_t.h
|
||||
../po/pogen.h
|
||||
../tools/version.h
|
||||
|
||||
@@ -20,7 +20,7 @@ VPATH = @srcdir@
|
||||
|
||||
LN_S = @LN_S@
|
||||
|
||||
.PHONY: clean distclean all install pofile install_cluster
|
||||
.PHONY: clean distclean all install pofile install_cluster install_device-mapper
|
||||
|
||||
all: .symlinks_created
|
||||
|
||||
@@ -35,11 +35,15 @@ distclean:
|
||||
|
||||
pofile: all
|
||||
|
||||
device-mapper: all
|
||||
|
||||
clean:
|
||||
|
||||
install:
|
||||
|
||||
install_cluster:
|
||||
|
||||
install_device-mapper:
|
||||
|
||||
cflow:
|
||||
|
||||
|
||||
@@ -38,7 +38,6 @@ SOURCES =\
|
||||
commands/toolcontext.c \
|
||||
config/config.c \
|
||||
datastruct/btree.c \
|
||||
datastruct/list.c \
|
||||
datastruct/str_list.c \
|
||||
device/dev-cache.c \
|
||||
device/dev-io.c \
|
||||
@@ -61,6 +60,7 @@ SOURCES =\
|
||||
format_text/import_vsn1.c \
|
||||
format_text/tags.c \
|
||||
format_text/text_label.c \
|
||||
freeseg/freeseg.c \
|
||||
label/label.c \
|
||||
locking/file_locking.c \
|
||||
locking/locking.c \
|
||||
@@ -77,6 +77,7 @@ SOURCES =\
|
||||
misc/crc.c \
|
||||
misc/lvm-exec.c \
|
||||
misc/lvm-file.c \
|
||||
misc/lvm-globals.c \
|
||||
misc/lvm-string.c \
|
||||
misc/lvm-wrappers.c \
|
||||
misc/timestamp.c \
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
@@ -52,11 +52,11 @@ int lvm1_present(struct cmd_context *cmd)
|
||||
}
|
||||
|
||||
int list_segment_modules(struct dm_pool *mem, const struct lv_segment *seg,
|
||||
struct list *modules)
|
||||
struct dm_list *modules)
|
||||
{
|
||||
unsigned int s;
|
||||
struct lv_segment *seg2, *snap_seg;
|
||||
struct list *snh;
|
||||
struct dm_list *snh;
|
||||
|
||||
if (seg->segtype->ops->modules_needed &&
|
||||
!seg->segtype->ops->modules_needed(mem, seg, modules)) {
|
||||
@@ -65,9 +65,9 @@ int list_segment_modules(struct dm_pool *mem, const struct lv_segment *seg,
|
||||
}
|
||||
|
||||
if (lv_is_origin(seg->lv))
|
||||
list_iterate(snh, &seg->lv->snapshot_segs)
|
||||
dm_list_iterate(snh, &seg->lv->snapshot_segs)
|
||||
if (!list_lv_modules(mem,
|
||||
list_struct_base(snh,
|
||||
dm_list_struct_base(snh,
|
||||
struct lv_segment,
|
||||
origin_list)->cow,
|
||||
modules))
|
||||
@@ -100,11 +100,11 @@ int list_segment_modules(struct dm_pool *mem, const struct lv_segment *seg,
|
||||
}
|
||||
|
||||
int list_lv_modules(struct dm_pool *mem, const struct logical_volume *lv,
|
||||
struct list *modules)
|
||||
struct dm_list *modules)
|
||||
{
|
||||
struct lv_segment *seg;
|
||||
|
||||
list_iterate_items(seg, &lv->segments)
|
||||
dm_list_iterate_items(seg, &lv->segments)
|
||||
if (!list_segment_modules(mem, seg, modules))
|
||||
return_0;
|
||||
|
||||
@@ -264,7 +264,7 @@ static int _passes_activation_filter(struct cmd_context *cmd,
|
||||
|
||||
if (!(cn = find_config_tree_node(cmd, "activation/volume_list"))) {
|
||||
/* If no host tags defined, activate */
|
||||
if (list_empty(&cmd->tags))
|
||||
if (dm_list_empty(&cmd->tags))
|
||||
return 1;
|
||||
|
||||
/* If any host tag matches any LV or VG tag, activate */
|
||||
@@ -391,12 +391,26 @@ int target_version(const char *target_name, uint32_t *maj,
|
||||
return r;
|
||||
}
|
||||
|
||||
int module_present(const char *target_name)
|
||||
{
|
||||
int ret = 0;
|
||||
#ifdef MODPROBE_CMD
|
||||
char module[128];
|
||||
|
||||
if (dm_snprintf(module, sizeof(module), "dm-%s", target_name) < 0) {
|
||||
log_error("module_present module name too long: %s",
|
||||
target_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = exec_cmd(MODPROBE_CMD, module, "", "");
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
int target_present(const char *target_name, int use_modprobe)
|
||||
{
|
||||
uint32_t maj, min, patchlevel;
|
||||
#ifdef MODPROBE_CMD
|
||||
char module[128];
|
||||
#endif
|
||||
|
||||
if (!activation())
|
||||
return 0;
|
||||
@@ -406,14 +420,7 @@ int target_present(const char *target_name, int use_modprobe)
|
||||
if (target_version(target_name, &maj, &min, &patchlevel))
|
||||
return 1;
|
||||
|
||||
if (dm_snprintf(module, sizeof(module), "dm-%s", target_name)
|
||||
< 0) {
|
||||
log_error("target_present module name too long: %s",
|
||||
target_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!exec_cmd(MODPROBE_CMD, module, "", ""))
|
||||
if (!module_present(target_name))
|
||||
return_0;
|
||||
}
|
||||
#endif
|
||||
@@ -508,6 +515,13 @@ int lv_mirror_percent(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct dev_manager *dm;
|
||||
struct lvinfo info;
|
||||
|
||||
/* If mirrored LV is temporarily shrinked to 1 area (= linear),
|
||||
* it should be considered in-sync. */
|
||||
if (dm_list_size(&lv->segments) == 1 && first_seg(lv)->area_count == 1) {
|
||||
*percent = 100.0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!activation())
|
||||
return 0;
|
||||
|
||||
@@ -625,7 +639,7 @@ static int _lvs_in_vg_activated(struct volume_group *vg, unsigned by_uuid_only)
|
||||
if (!activation())
|
||||
return 0;
|
||||
|
||||
list_iterate_items(lvl, &vg->lvs) {
|
||||
dm_list_iterate_items(lvl, &vg->lvs) {
|
||||
if (lvl->lv->status & VISIBLE_LV)
|
||||
count += (_lv_active(vg->cmd, lvl->lv, by_uuid_only) == 1);
|
||||
}
|
||||
@@ -651,7 +665,7 @@ int lvs_in_vg_opened(const struct volume_group *vg)
|
||||
if (!activation())
|
||||
return 0;
|
||||
|
||||
list_iterate_items(lvl, &vg->lvs) {
|
||||
dm_list_iterate_items(lvl, &vg->lvs) {
|
||||
if (lvl->lv->status & VISIBLE_LV)
|
||||
count += (_lv_open_count(vg->cmd, lvl->lv) > 0);
|
||||
}
|
||||
@@ -659,6 +673,38 @@ int lvs_in_vg_opened(const struct volume_group *vg)
|
||||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine whether an LV is active locally or in a cluster.
|
||||
* Assumes vg lock held.
|
||||
* Returns:
|
||||
* 0 - not active locally or on any node in cluster
|
||||
* 1 - active either locally or some node in the cluster
|
||||
*/
|
||||
int lv_is_active(struct logical_volume *lv)
|
||||
{
|
||||
if (_lv_active(lv->vg->cmd, lv, 0))
|
||||
return 1;
|
||||
|
||||
if (!vg_is_clustered(lv->vg))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* FIXME: Cluster does not report per-node LV activation status.
|
||||
* Currently the best we can do is try exclusive local activation.
|
||||
* If that succeeds, we know the LV is not active elsewhere in the
|
||||
* cluster.
|
||||
*/
|
||||
if (activate_lv_excl(lv->vg->cmd, lv)) {
|
||||
deactivate_lv(lv->vg->cmd, lv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Exclusive local activation failed so assume it is active elsewhere.
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns 0 if an attempt to (un)monitor the device failed.
|
||||
* Returns 1 otherwise.
|
||||
@@ -669,9 +715,10 @@ int monitor_dev_for_events(struct cmd_context *cmd,
|
||||
#ifdef DMEVENTD
|
||||
int i, pending = 0, monitored;
|
||||
int r = 1;
|
||||
struct list *tmp;
|
||||
struct dm_list *tmp, *snh, *snht;
|
||||
struct lv_segment *seg;
|
||||
int (*monitor_fn) (struct lv_segment *s, int e);
|
||||
uint32_t s;
|
||||
|
||||
/* skip dmeventd code altogether */
|
||||
if (dmeventd_monitor_mode() == DMEVENTD_MONITOR_IGNORE)
|
||||
@@ -683,8 +730,43 @@ int monitor_dev_for_events(struct cmd_context *cmd,
|
||||
if (monitor && !dmeventd_monitor_mode())
|
||||
return 1;
|
||||
|
||||
list_iterate(tmp, &lv->segments) {
|
||||
seg = list_item(tmp, struct lv_segment);
|
||||
/*
|
||||
* In case of a snapshot device, we monitor lv->snapshot->lv,
|
||||
* not the actual LV itself.
|
||||
*/
|
||||
if (lv_is_cow(lv))
|
||||
return monitor_dev_for_events(cmd, lv->snapshot->lv, monitor);
|
||||
|
||||
/*
|
||||
* In case this LV is a snapshot origin, we instead monitor
|
||||
* each of its respective snapshots (the origin itself does
|
||||
* not need to be monitored).
|
||||
*
|
||||
* TODO: This may change when snapshots of mirrors are allowed.
|
||||
*/
|
||||
if (lv_is_origin(lv)) {
|
||||
dm_list_iterate_safe(snh, snht, &lv->snapshot_segs)
|
||||
if (!monitor_dev_for_events(cmd, dm_list_struct_base(snh,
|
||||
struct lv_segment, origin_list)->cow, monitor))
|
||||
r = 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
dm_list_iterate(tmp, &lv->segments) {
|
||||
seg = dm_list_item(tmp, struct lv_segment);
|
||||
|
||||
/* Recurse for AREA_LV */
|
||||
for (s = 0; s < seg->area_count; s++) {
|
||||
if (seg_type(seg, s) != AREA_LV)
|
||||
continue;
|
||||
if (!monitor_dev_for_events(cmd, seg_lv(seg, s),
|
||||
monitor)) {
|
||||
log_error("Failed to %smonitor %s",
|
||||
monitor ? "" : "un",
|
||||
seg_lv(seg, s)->name);
|
||||
r = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!seg_monitored(seg) || (seg->status & PVMOVE))
|
||||
continue;
|
||||
@@ -945,6 +1027,12 @@ static int _lv_activate(struct cmd_context *cmd, const char *lvid_s,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((!lv->vg->cmd->partial_activation) && (lv->status & PARTIAL_LV)) {
|
||||
log_error("Refusing activation of partial LV %s. Use --partial to override.",
|
||||
lv->name);
|
||||
return_0;
|
||||
}
|
||||
|
||||
if (test_mode()) {
|
||||
_skip("Activating '%s'.", lv->name);
|
||||
return 1;
|
||||
|
||||
@@ -30,6 +30,9 @@ struct lvinfo {
|
||||
uint32_t read_ahead;
|
||||
};
|
||||
|
||||
/* target attribute flags */
|
||||
#define MIRROR_LOG_CLUSTERED 0x00000001U
|
||||
|
||||
void set_activation(int activation);
|
||||
int activation(void);
|
||||
|
||||
@@ -37,13 +40,14 @@ int driver_version(char *version, size_t size);
|
||||
int library_version(char *version, size_t size);
|
||||
int lvm1_present(struct cmd_context *cmd);
|
||||
|
||||
int module_present(const char *target_name);
|
||||
int target_present(const char *target_name, int use_modprobe);
|
||||
int target_version(const char *target_name, uint32_t *maj,
|
||||
uint32_t *min, uint32_t *patchlevel);
|
||||
int list_segment_modules(struct dm_pool *mem, const struct lv_segment *seg,
|
||||
struct list *modules);
|
||||
struct dm_list *modules);
|
||||
int list_lv_modules(struct dm_pool *mem, const struct logical_volume *lv,
|
||||
struct list *modules);
|
||||
struct dm_list *modules);
|
||||
|
||||
void activation_release(void);
|
||||
void activation_exit(void);
|
||||
@@ -87,6 +91,7 @@ int lvs_in_vg_activated(struct volume_group *vg);
|
||||
int lvs_in_vg_activated_by_uuid_only(struct volume_group *vg);
|
||||
int lvs_in_vg_opened(const struct volume_group *vg);
|
||||
|
||||
int lv_is_active(struct logical_volume *lv);
|
||||
|
||||
int monitor_dev_for_events(struct cmd_context *cmd,
|
||||
struct logical_volume *lv, int do_reg);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
@@ -47,7 +47,6 @@ struct dev_manager {
|
||||
|
||||
struct cmd_context *cmd;
|
||||
|
||||
const char *stripe_filler;
|
||||
void *target_state;
|
||||
uint32_t pvmove_mirror_count;
|
||||
|
||||
@@ -59,8 +58,6 @@ struct lv_layer {
|
||||
const char *old_name;
|
||||
};
|
||||
|
||||
static const char *stripe_filler = NULL;
|
||||
|
||||
static char *_build_dlid(struct dm_pool *mem, const char *lvid, const char *layer)
|
||||
{
|
||||
char *dlid;
|
||||
@@ -100,10 +97,8 @@ static struct dm_task *_setup_task(const char *name, const char *uuid,
|
||||
{
|
||||
struct dm_task *dmt;
|
||||
|
||||
if (!(dmt = dm_task_create(task))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
if (!(dmt = dm_task_create(task)))
|
||||
return_NULL;
|
||||
|
||||
if (name)
|
||||
dm_task_set_name(dmt, name);
|
||||
@@ -127,10 +122,8 @@ static int _info_run(const char *name, const char *dlid, struct dm_info *info,
|
||||
|
||||
dmtask = mknodes ? DM_DEVICE_MKNODES : DM_DEVICE_INFO;
|
||||
|
||||
if (!(dmt = _setup_task(name, dlid, 0, dmtask))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(dmt = _setup_task(name, dlid, 0, dmtask)))
|
||||
return_0;
|
||||
|
||||
if (!with_open_count)
|
||||
if (!dm_task_no_open_count(dmt))
|
||||
@@ -160,9 +153,9 @@ int device_is_usable(dev_t dev)
|
||||
struct dm_task *dmt;
|
||||
struct dm_info info;
|
||||
const char *name;
|
||||
uint64_t start, length;
|
||||
char *target_type = NULL;
|
||||
char *params;
|
||||
uint64_t start, length;
|
||||
char *target_type = NULL;
|
||||
char *params;
|
||||
void *next = NULL;
|
||||
int r = 0;
|
||||
|
||||
@@ -190,13 +183,13 @@ int device_is_usable(dev_t dev)
|
||||
/* FIXME Also check for mirror block_on_error and mpath no paths */
|
||||
/* For now, we exclude all mirrors */
|
||||
|
||||
do {
|
||||
next = dm_get_next_target(dmt, next, &start, &length,
|
||||
&target_type, ¶ms);
|
||||
/* Skip if target type doesn't match */
|
||||
if (target_type && !strcmp(target_type, "mirror"))
|
||||
do {
|
||||
next = dm_get_next_target(dmt, next, &start, &length,
|
||||
&target_type, ¶ms);
|
||||
/* Skip if target type doesn't match */
|
||||
if (target_type && !strcmp(target_type, "mirror"))
|
||||
goto out;
|
||||
} while (next);
|
||||
} while (next);
|
||||
|
||||
/* FIXME Also check dependencies? */
|
||||
|
||||
@@ -259,10 +252,8 @@ static int _status_run(const char *name, const char *uuid,
|
||||
char *type = NULL;
|
||||
char *params = NULL;
|
||||
|
||||
if (!(dmt = _setup_task(name, uuid, 0, DM_DEVICE_STATUS))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(dmt = _setup_task(name, uuid, 0, DM_DEVICE_STATUS)))
|
||||
return_0;
|
||||
|
||||
if (!dm_task_no_open_count(dmt))
|
||||
log_error("Failed to disable open_count");
|
||||
@@ -339,7 +330,7 @@ static int _percent_run(struct dev_manager *dm, const char *name,
|
||||
uint64_t start, length;
|
||||
char *type = NULL;
|
||||
char *params = NULL;
|
||||
struct list *segh = &lv->segments;
|
||||
struct dm_list *segh = &lv->segments;
|
||||
struct lv_segment *seg = NULL;
|
||||
struct segment_type *segtype;
|
||||
|
||||
@@ -348,10 +339,8 @@ static int _percent_run(struct dev_manager *dm, const char *name,
|
||||
*percent = -1;
|
||||
|
||||
if (!(dmt = _setup_task(name, dlid, event_nr,
|
||||
wait ? DM_DEVICE_WAITEVENT : DM_DEVICE_STATUS))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
wait ? DM_DEVICE_WAITEVENT : DM_DEVICE_STATUS)))
|
||||
return_0;
|
||||
|
||||
if (!dm_task_no_open_count(dmt))
|
||||
log_error("Failed to disable open_count");
|
||||
@@ -369,12 +358,12 @@ static int _percent_run(struct dev_manager *dm, const char *name,
|
||||
next = dm_get_next_target(dmt, next, &start, &length, &type,
|
||||
¶ms);
|
||||
if (lv) {
|
||||
if (!(segh = list_next(&lv->segments, segh))) {
|
||||
if (!(segh = dm_list_next(&lv->segments, segh))) {
|
||||
log_error("Number of segments in active LV %s "
|
||||
"does not match metadata", lv->name);
|
||||
goto out;
|
||||
}
|
||||
seg = list_item(segh, struct lv_segment);
|
||||
seg = dm_list_item(segh, struct lv_segment);
|
||||
}
|
||||
|
||||
if (!type || !params || strcmp(type, target_type))
|
||||
@@ -387,13 +376,12 @@ static int _percent_run(struct dev_manager *dm, const char *name,
|
||||
!segtype->ops->target_percent(&dm->target_state, dm->mem,
|
||||
dm->cmd, seg, params,
|
||||
&total_numerator,
|
||||
&total_denominator,
|
||||
percent))
|
||||
&total_denominator))
|
||||
goto_out;
|
||||
|
||||
} while (next);
|
||||
|
||||
if (lv && (segh = list_next(&lv->segments, segh))) {
|
||||
if (lv && (segh = dm_list_next(&lv->segments, segh))) {
|
||||
log_error("Number of segments in active LV %s does not "
|
||||
"match metadata", lv->name);
|
||||
goto out;
|
||||
@@ -401,7 +389,7 @@ static int _percent_run(struct dev_manager *dm, const char *name,
|
||||
|
||||
if (total_denominator)
|
||||
*percent = (float) total_numerator *100 / total_denominator;
|
||||
else if (*percent < 0)
|
||||
else
|
||||
*percent = 100;
|
||||
|
||||
log_debug("LV percent: %f", *percent);
|
||||
@@ -443,10 +431,8 @@ struct dev_manager *dev_manager_create(struct cmd_context *cmd,
|
||||
struct dm_pool *mem;
|
||||
struct dev_manager *dm;
|
||||
|
||||
if (!(mem = dm_pool_create("dev_manager", 16 * 1024))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
if (!(mem = dm_pool_create("dev_manager", 16 * 1024)))
|
||||
return_NULL;
|
||||
|
||||
if (!(dm = dm_pool_alloc(mem, sizeof(*dm))))
|
||||
goto_bad;
|
||||
@@ -454,13 +440,6 @@ struct dev_manager *dev_manager_create(struct cmd_context *cmd,
|
||||
dm->cmd = cmd;
|
||||
dm->mem = mem;
|
||||
|
||||
if (!stripe_filler) {
|
||||
stripe_filler = find_config_tree_str(cmd,
|
||||
"activation/missing_stripe_filler",
|
||||
DEFAULT_STRIPE_FILLER);
|
||||
}
|
||||
dm->stripe_filler = stripe_filler;
|
||||
|
||||
if (!(dm->vg_name = dm_pool_strdup(dm->mem, vg_name)))
|
||||
goto_bad;
|
||||
|
||||
@@ -509,10 +488,8 @@ int dev_manager_snapshot_percent(struct dev_manager *dm,
|
||||
*/
|
||||
log_debug("Getting device status percentage for %s", name);
|
||||
if (!(_percent(dm, name, dlid, "snapshot", 0, NULL, percent,
|
||||
NULL))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
NULL)))
|
||||
return_0;
|
||||
|
||||
/* FIXME dm_pool_free ? */
|
||||
|
||||
@@ -544,10 +521,8 @@ int dev_manager_mirror_percent(struct dev_manager *dm,
|
||||
|
||||
log_debug("Getting device mirror status percentage for %s", name);
|
||||
if (!(_percent(dm, name, dlid, "mirror", wait, lv, percent,
|
||||
event_nr))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
event_nr)))
|
||||
return_0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -601,7 +576,7 @@ static int _belong_to_vg(const char *vgname, const char *name)
|
||||
old_origin = snap_seg->origin;
|
||||
|
||||
/* Was this the last active snapshot with this origin? */
|
||||
list_iterate_items(lvl, active_head) {
|
||||
dm_list_iterate_items(lvl, active_head) {
|
||||
active = lvl->lv;
|
||||
if ((snap_seg = find_cow(active)) &&
|
||||
snap_seg->origin == old_origin) {
|
||||
@@ -643,11 +618,11 @@ static int _add_dev_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
|
||||
if (!(dlid = build_dlid(dm, lv->lvid.s, layer)))
|
||||
return_0;
|
||||
|
||||
log_debug("Getting device info for %s [%s]", name, dlid);
|
||||
if (!_info(name, dlid, 0, 1, 0, &info, NULL)) {
|
||||
log_error("Failed to get info for %s [%s].", name, dlid);
|
||||
return 0;
|
||||
}
|
||||
log_debug("Getting device info for %s [%s]", name, dlid);
|
||||
if (!_info(name, dlid, 0, 1, 0, &info, NULL)) {
|
||||
log_error("Failed to get info for %s [%s].", name, dlid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (info.exists && !dm_tree_add_dev(dtree, info.major, info.minor)) {
|
||||
log_error("Failed to add device (%" PRIu32 ":%" PRIu32") to dtree",
|
||||
@@ -682,7 +657,7 @@ static int _add_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree, struc
|
||||
static struct dm_tree *_create_partial_dtree(struct dev_manager *dm, struct logical_volume *lv)
|
||||
{
|
||||
struct dm_tree *dtree;
|
||||
struct list *snh, *snht;
|
||||
struct dm_list *snh, *snht;
|
||||
struct lv_segment *seg;
|
||||
uint32_t s;
|
||||
|
||||
@@ -691,35 +666,91 @@ static struct dm_tree *_create_partial_dtree(struct dev_manager *dm, struct logi
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!_add_lv_to_dtree(dm, dtree, lv)) {
|
||||
stack;
|
||||
goto fail;
|
||||
}
|
||||
if (!_add_lv_to_dtree(dm, dtree, lv))
|
||||
goto_bad;
|
||||
|
||||
/* Add any snapshots of this LV */
|
||||
list_iterate_safe(snh, snht, &lv->snapshot_segs)
|
||||
if (!_add_lv_to_dtree(dm, dtree, list_struct_base(snh, struct lv_segment, origin_list)->cow)) {
|
||||
stack;
|
||||
goto fail;
|
||||
}
|
||||
dm_list_iterate_safe(snh, snht, &lv->snapshot_segs)
|
||||
if (!_add_lv_to_dtree(dm, dtree, dm_list_struct_base(snh, struct lv_segment, origin_list)->cow))
|
||||
goto_bad;
|
||||
|
||||
/* Add any LVs used by segments in this LV */
|
||||
list_iterate_items(seg, &lv->segments)
|
||||
dm_list_iterate_items(seg, &lv->segments)
|
||||
for (s = 0; s < seg->area_count; s++)
|
||||
if (seg_type(seg, s) == AREA_LV && seg_lv(seg, s)) {
|
||||
if (!_add_lv_to_dtree(dm, dtree, seg_lv(seg, s))) {
|
||||
stack;
|
||||
goto fail;
|
||||
}
|
||||
if (!_add_lv_to_dtree(dm, dtree, seg_lv(seg, s)))
|
||||
goto_bad;
|
||||
}
|
||||
|
||||
return dtree;
|
||||
|
||||
fail:
|
||||
bad:
|
||||
dm_tree_free(dtree);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *_add_error_device(struct dev_manager *dm, struct dm_tree *dtree,
|
||||
struct lv_segment *seg, int s)
|
||||
{
|
||||
char *id, *name;
|
||||
char errid[32];
|
||||
struct dm_tree_node *node;
|
||||
struct lv_segment *seg_i;
|
||||
int segno = -1, i = 0;;
|
||||
uint64_t size = seg->len * seg->lv->vg->extent_size;
|
||||
|
||||
dm_list_iterate_items(seg_i, &seg->lv->segments) {
|
||||
if (seg == seg_i)
|
||||
segno = i;
|
||||
++i;
|
||||
}
|
||||
|
||||
if (segno < 0) {
|
||||
log_error("_add_error_device called with bad segment");
|
||||
return_NULL;
|
||||
}
|
||||
|
||||
sprintf(errid, "missing_%d_%d", segno, s);
|
||||
|
||||
if (!(id = build_dlid(dm, seg->lv->lvid.s, errid)))
|
||||
return_NULL;
|
||||
|
||||
if (!(name = build_dm_name(dm->mem, seg->lv->vg->name,
|
||||
seg->lv->name, errid)))
|
||||
return_NULL;
|
||||
if (!(node = dm_tree_add_new_dev(dtree, name, id, 0, 0, 0, 0, 0)))
|
||||
return_NULL;
|
||||
if (!dm_tree_node_add_error_target(node, size))
|
||||
return_NULL;
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
static int _add_error_area(struct dev_manager *dm, struct dm_tree_node *node,
|
||||
struct lv_segment *seg, int s)
|
||||
{
|
||||
char *dlid;
|
||||
uint64_t extent_size = seg->lv->vg->extent_size;
|
||||
|
||||
if (!strcmp(dm->cmd->stripe_filler, "error")) {
|
||||
/*
|
||||
* FIXME, the tree pointer is first field of dm_tree_node, but
|
||||
* we don't have the struct definition available.
|
||||
*/
|
||||
struct dm_tree **tree = (struct dm_tree **) node;
|
||||
dlid = _add_error_device(dm, *tree, seg, s);
|
||||
if (!dlid)
|
||||
return_0;
|
||||
dm_tree_node_add_target_area(node, NULL, dlid,
|
||||
extent_size * seg_le(seg, s));
|
||||
} else
|
||||
dm_tree_node_add_target_area(node,
|
||||
dm->cmd->stripe_filler,
|
||||
NULL, UINT64_C(0));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int add_areas_line(struct dev_manager *dm, struct lv_segment *seg,
|
||||
struct dm_tree_node *node, uint32_t start_area,
|
||||
uint32_t areas)
|
||||
@@ -733,11 +764,10 @@ int add_areas_line(struct dev_manager *dm, struct lv_segment *seg,
|
||||
(!seg_pvseg(seg, s) ||
|
||||
!seg_pv(seg, s) ||
|
||||
!seg_dev(seg, s))) ||
|
||||
(seg_type(seg, s) == AREA_LV && !seg_lv(seg, s)))
|
||||
dm_tree_node_add_target_area(node,
|
||||
dm->stripe_filler,
|
||||
NULL, UINT64_C(0));
|
||||
else if (seg_type(seg, s) == AREA_PV)
|
||||
(seg_type(seg, s) == AREA_LV && !seg_lv(seg, s))) {
|
||||
if (!_add_error_area(dm, node, seg, s))
|
||||
return_0;
|
||||
} else if (seg_type(seg, s) == AREA_PV)
|
||||
dm_tree_node_add_target_area(node,
|
||||
dev_name(seg_dev(seg, s)),
|
||||
NULL,
|
||||
@@ -832,7 +862,7 @@ static int _add_segment_to_dtree(struct dev_manager *dm,
|
||||
const char *layer)
|
||||
{
|
||||
uint32_t s;
|
||||
struct list *snh;
|
||||
struct dm_list *snh;
|
||||
struct lv_segment *seg_present;
|
||||
|
||||
/* Ensure required device-mapper targets are loaded */
|
||||
@@ -843,7 +873,7 @@ static int _add_segment_to_dtree(struct dev_manager *dm,
|
||||
layer ? "-" : "", layer ? : "");
|
||||
|
||||
if (seg_present->segtype->ops->target_present &&
|
||||
!seg_present->segtype->ops->target_present(seg_present)) {
|
||||
!seg_present->segtype->ops->target_present(seg_present, NULL)) {
|
||||
log_error("Can't expand LV %s: %s target support missing "
|
||||
"from kernel?", seg->lv->name, seg_present->segtype->name);
|
||||
return 0;
|
||||
@@ -856,7 +886,7 @@ static int _add_segment_to_dtree(struct dev_manager *dm,
|
||||
|
||||
/* If this is a snapshot origin, add real LV */
|
||||
if (lv_is_origin(seg->lv) && !layer) {
|
||||
if (seg->lv->vg->status & CLUSTERED) {
|
||||
if (vg_is_clustered(seg->lv->vg)) {
|
||||
log_error("Clustered snapshots are not yet supported");
|
||||
return 0;
|
||||
}
|
||||
@@ -885,8 +915,8 @@ static int _add_segment_to_dtree(struct dev_manager *dm,
|
||||
|
||||
if (lv_is_origin(seg->lv) && !layer)
|
||||
/* Add any snapshots of this LV */
|
||||
list_iterate(snh, &seg->lv->snapshot_segs)
|
||||
if (!_add_new_lv_to_dtree(dm, dtree, list_struct_base(snh, struct lv_segment, origin_list)->cow, NULL))
|
||||
dm_list_iterate(snh, &seg->lv->snapshot_segs)
|
||||
if (!_add_new_lv_to_dtree(dm, dtree, dm_list_struct_base(snh, struct lv_segment, origin_list)->cow, NULL))
|
||||
return_0;
|
||||
|
||||
return 1;
|
||||
@@ -940,7 +970,7 @@ static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
|
||||
|
||||
/* Create table */
|
||||
dm->pvmove_mirror_count = 0u;
|
||||
list_iterate_items(seg, &lv->segments) {
|
||||
dm_list_iterate_items(seg, &lv->segments) {
|
||||
if (!_add_segment_to_dtree(dm, dtree, dnode, seg, layer))
|
||||
return_0;
|
||||
/* These aren't real segments in the LVM2 metadata */
|
||||
@@ -948,14 +978,15 @@ static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
|
||||
break;
|
||||
if (lv_is_cow(lv) && !layer)
|
||||
break;
|
||||
if (max_stripe_size < seg->stripe_size)
|
||||
max_stripe_size = seg->stripe_size;
|
||||
if (max_stripe_size < seg->stripe_size * seg->area_count)
|
||||
max_stripe_size = seg->stripe_size * seg->area_count;
|
||||
}
|
||||
|
||||
if (read_ahead == DM_READ_AHEAD_AUTO)
|
||||
read_ahead = max_stripe_size;
|
||||
else
|
||||
if (read_ahead == DM_READ_AHEAD_AUTO) {
|
||||
/* we need RA at least twice a whole stripe - see the comment in md/raid0.c */
|
||||
read_ahead = max_stripe_size * 2;
|
||||
read_ahead_flags = DM_READ_AHEAD_MINIMUM_FLAG;
|
||||
}
|
||||
|
||||
dm_tree_node_set_read_ahead(dnode, read_ahead, read_ahead_flags);
|
||||
|
||||
@@ -986,10 +1017,10 @@ static int _create_lv_symlinks(struct dev_manager *dm, struct dm_tree_node *root
|
||||
name = dm_tree_node_get_name(child);
|
||||
|
||||
if (name && lvlayer->old_name && *lvlayer->old_name && strcmp(name, lvlayer->old_name)) {
|
||||
if (!dm_split_lvm_name(dm->mem, lvlayer->old_name, &vgname, &lvname, &layer)) {
|
||||
log_error("_create_lv_symlinks: Couldn't split up old device name %s", lvlayer->old_name);
|
||||
return 0;
|
||||
}
|
||||
if (!dm_split_lvm_name(dm->mem, lvlayer->old_name, &vgname, &lvname, &layer)) {
|
||||
log_error("_create_lv_symlinks: Couldn't split up old device name %s", lvlayer->old_name);
|
||||
return 0;
|
||||
}
|
||||
fs_rename_lv(lvlayer->lv, name, lvname);
|
||||
} else if (!dev_manager_lv_mknodes(lvlayer->lv))
|
||||
r = 0;
|
||||
@@ -1009,11 +1040,14 @@ static int _remove_lv_symlinks(struct dev_manager *dm, struct dm_tree_node *root
|
||||
int r = 1;
|
||||
|
||||
while ((child = dm_tree_next_child(&handle, root, 0))) {
|
||||
if (!dm_split_lvm_name(dm->mem, dm_tree_node_get_name(child), &vgname, &lvname, &layer)) {
|
||||
if (!dm_split_lvm_name(dm->mem, dm_tree_node_get_name(child), &vgname, &lvname, &layer)) {
|
||||
r = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!*vgname)
|
||||
continue;
|
||||
|
||||
/* only top level layer has symlinks */
|
||||
if (*layer)
|
||||
continue;
|
||||
@@ -1038,10 +1072,10 @@ static int _clean_tree(struct dev_manager *dm, struct dm_tree_node *root)
|
||||
if (!(uuid = dm_tree_node_get_uuid(child)))
|
||||
continue;
|
||||
|
||||
if (!dm_split_lvm_name(dm->mem, name, &vgname, &lvname, &layer)) {
|
||||
log_error("_clean_tree: Couldn't split up device name %s.", name);
|
||||
return 0;
|
||||
}
|
||||
if (!dm_split_lvm_name(dm->mem, name, &vgname, &lvname, &layer)) {
|
||||
log_error("_clean_tree: Couldn't split up device name %s.", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Not meant to be top level? */
|
||||
if (!*layer)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
@@ -138,7 +138,7 @@ static int _mk_link(const char *dev_dir, const char *vg_name,
|
||||
}
|
||||
|
||||
/* To reach this point, the VG must have been locked.
|
||||
* As locking fails if the VG is active under LVM1, it's
|
||||
* As locking fails if the VG is active under LVM1, it's
|
||||
* now safe to remove any LVM1 devices we find here
|
||||
* (as well as any existing LVM2 symlink). */
|
||||
if (!lstat(lvm1_group_path, &buf)) {
|
||||
@@ -175,10 +175,8 @@ static int _mk_link(const char *dev_dir, const char *vg_name,
|
||||
}
|
||||
|
||||
#ifdef HAVE_SELINUX
|
||||
if (!dm_set_selinux_context(lv_path, S_IFLNK)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!dm_set_selinux_context(lv_path, S_IFLNK))
|
||||
return_0;
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
@@ -225,17 +223,13 @@ static int _do_fs_op(fs_op_t type, const char *dev_dir, const char *vg_name,
|
||||
switch (type) {
|
||||
case FS_ADD:
|
||||
if (!_mk_dir(dev_dir, vg_name) ||
|
||||
!_mk_link(dev_dir, vg_name, lv_name, dev)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
!_mk_link(dev_dir, vg_name, lv_name, dev))
|
||||
return_0;
|
||||
break;
|
||||
case FS_DEL:
|
||||
if (!_rm_link(dev_dir, vg_name, lv_name) ||
|
||||
!_rm_dir(dev_dir, vg_name)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
!_rm_dir(dev_dir, vg_name))
|
||||
return_0;
|
||||
break;
|
||||
/* FIXME Use rename() */
|
||||
case FS_RENAME:
|
||||
@@ -249,10 +243,10 @@ static int _do_fs_op(fs_op_t type, const char *dev_dir, const char *vg_name,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static LIST_INIT(_fs_ops);
|
||||
static DM_LIST_INIT(_fs_ops);
|
||||
|
||||
struct fs_op_parms {
|
||||
struct list list;
|
||||
struct dm_list list;
|
||||
fs_op_t type;
|
||||
char *dev_dir;
|
||||
char *vg_name;
|
||||
@@ -292,21 +286,21 @@ static int _stack_fs_op(fs_op_t type, const char *dev_dir, const char *vg_name,
|
||||
_store_str(&pos, &fsp->dev, dev);
|
||||
_store_str(&pos, &fsp->old_lv_name, old_lv_name);
|
||||
|
||||
list_add(&_fs_ops, &fsp->list);
|
||||
dm_list_add(&_fs_ops, &fsp->list);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void _pop_fs_ops(void)
|
||||
{
|
||||
struct list *fsph, *fspht;
|
||||
struct dm_list *fsph, *fspht;
|
||||
struct fs_op_parms *fsp;
|
||||
|
||||
list_iterate_safe(fsph, fspht, &_fs_ops) {
|
||||
fsp = list_item(fsph, struct fs_op_parms);
|
||||
dm_list_iterate_safe(fsph, fspht, &_fs_ops) {
|
||||
fsp = dm_list_item(fsph, struct fs_op_parms);
|
||||
_do_fs_op(fsp->type, fsp->dev_dir, fsp->vg_name, fsp->lv_name,
|
||||
fsp->dev, fsp->old_lv_name);
|
||||
list_del(&fsp->list);
|
||||
dm_list_del(&fsp->list);
|
||||
dm_free(fsp);
|
||||
}
|
||||
}
|
||||
@@ -316,10 +310,8 @@ static int _fs_op(fs_op_t type, const char *dev_dir, const char *vg_name,
|
||||
{
|
||||
if (memlock()) {
|
||||
if (!_stack_fs_op(type, dev_dir, vg_name, lv_name, dev,
|
||||
old_lv_name)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
old_lv_name))
|
||||
return_0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
619
lib/cache/lvmcache.c
vendored
619
lib/cache/lvmcache.c
vendored
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
*
|
||||
@@ -17,22 +17,28 @@
|
||||
#include "lvmcache.h"
|
||||
#include "toolcontext.h"
|
||||
#include "dev-cache.h"
|
||||
#include "locking.h"
|
||||
#include "metadata.h"
|
||||
#include "filter.h"
|
||||
#include "memlock.h"
|
||||
#include "str_list.h"
|
||||
#include "format-text.h"
|
||||
#include "format_pool.h"
|
||||
#include "format1.h"
|
||||
|
||||
static struct dm_hash_table *_pvid_hash = NULL;
|
||||
static struct dm_hash_table *_vgid_hash = NULL;
|
||||
static struct dm_hash_table *_vgname_hash = NULL;
|
||||
static struct dm_hash_table *_lock_hash = NULL;
|
||||
static struct list _vginfos;
|
||||
static struct dm_list _vginfos;
|
||||
static int _scanning_in_progress = 0;
|
||||
static int _has_scanned = 0;
|
||||
static int _vgs_locked = 0;
|
||||
static int _vg_global_lock_held = 0; /* Global lock held when cache wiped? */
|
||||
|
||||
int lvmcache_init(void)
|
||||
{
|
||||
list_init(&_vginfos);
|
||||
dm_list_init(&_vginfos);
|
||||
|
||||
if (!(_vgname_hash = dm_hash_create(128)))
|
||||
return 0;
|
||||
@@ -46,9 +52,125 @@ int lvmcache_init(void)
|
||||
if (!(_lock_hash = dm_hash_create(128)))
|
||||
return 0;
|
||||
|
||||
if (_vg_global_lock_held)
|
||||
lvmcache_lock_vgname(VG_GLOBAL, 0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Volume Group metadata cache functions */
|
||||
static void _free_cached_vgmetadata(struct lvmcache_vginfo *vginfo)
|
||||
{
|
||||
if (!vginfo || !vginfo->vgmetadata)
|
||||
return;
|
||||
|
||||
dm_free(vginfo->vgmetadata);
|
||||
|
||||
vginfo->vgmetadata = NULL;
|
||||
|
||||
log_debug("Metadata cache: VG %s wiped.", vginfo->vgname);
|
||||
}
|
||||
|
||||
static void _store_metadata(struct lvmcache_vginfo *vginfo,
|
||||
struct volume_group *vg, unsigned precommitted)
|
||||
{
|
||||
int size;
|
||||
|
||||
if (vginfo->vgmetadata)
|
||||
_free_cached_vgmetadata(vginfo);
|
||||
|
||||
if (!(size = export_vg_to_buffer(vg, &vginfo->vgmetadata))) {
|
||||
stack;
|
||||
return;
|
||||
}
|
||||
|
||||
vginfo->precommitted = precommitted;
|
||||
|
||||
log_debug("Metadata cache: VG %s stored (%d bytes%s).", vginfo->vgname,
|
||||
size, precommitted ? ", precommitted" : "");
|
||||
}
|
||||
|
||||
static void _update_cache_info_lock_state(struct lvmcache_info *info,
|
||||
int locked,
|
||||
int *cached_vgmetadata_valid)
|
||||
{
|
||||
int was_locked = (info->status & CACHE_LOCKED) ? 1 : 0;
|
||||
|
||||
/*
|
||||
* Cache becomes invalid whenever lock state changes unless
|
||||
* exclusive VG_GLOBAL is held (i.e. while scanning).
|
||||
*/
|
||||
if (!vgname_is_locked(VG_GLOBAL) && (was_locked != locked)) {
|
||||
info->status |= CACHE_INVALID;
|
||||
*cached_vgmetadata_valid = 0;
|
||||
}
|
||||
|
||||
if (locked)
|
||||
info->status |= CACHE_LOCKED;
|
||||
else
|
||||
info->status &= ~CACHE_LOCKED;
|
||||
}
|
||||
|
||||
static void _update_cache_vginfo_lock_state(struct lvmcache_vginfo *vginfo,
|
||||
int locked)
|
||||
{
|
||||
struct lvmcache_info *info;
|
||||
int cached_vgmetadata_valid = 1;
|
||||
|
||||
dm_list_iterate_items(info, &vginfo->infos)
|
||||
_update_cache_info_lock_state(info, locked,
|
||||
&cached_vgmetadata_valid);
|
||||
|
||||
if (!cached_vgmetadata_valid)
|
||||
_free_cached_vgmetadata(vginfo);
|
||||
}
|
||||
|
||||
static void _update_cache_lock_state(const char *vgname, int locked)
|
||||
{
|
||||
struct lvmcache_vginfo *vginfo;
|
||||
|
||||
if (!(vginfo = vginfo_from_vgname(vgname, NULL)))
|
||||
return;
|
||||
|
||||
_update_cache_vginfo_lock_state(vginfo, locked);
|
||||
}
|
||||
|
||||
static void _drop_metadata(const char *vgname)
|
||||
{
|
||||
struct lvmcache_vginfo *vginfo;
|
||||
struct lvmcache_info *info;
|
||||
|
||||
if (!(vginfo = vginfo_from_vgname(vgname, NULL)))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Invalidate cached PV labels.
|
||||
* If cached precommitted metadata exists that means we
|
||||
* already invalidated the PV labels (before caching it)
|
||||
* and we must not do it again.
|
||||
*/
|
||||
|
||||
if (!vginfo->precommitted)
|
||||
dm_list_iterate_items(info, &vginfo->infos)
|
||||
info->status |= CACHE_INVALID;
|
||||
|
||||
_free_cached_vgmetadata(vginfo);
|
||||
}
|
||||
|
||||
void lvmcache_drop_metadata(const char *vgname)
|
||||
{
|
||||
/* For VG_ORPHANS, we need to invalidate all labels on orphan PVs. */
|
||||
if (!strcmp(vgname, VG_ORPHANS)) {
|
||||
_drop_metadata(FMT_TEXT_ORPHAN_VG_NAME);
|
||||
_drop_metadata(FMT_LVM1_ORPHAN_VG_NAME);
|
||||
_drop_metadata(FMT_POOL_ORPHAN_VG_NAME);
|
||||
|
||||
/* Indicate that PVs could now be missing from the cache */
|
||||
init_full_scan_done(0);
|
||||
} else if (!vgname_is_locked(VG_GLOBAL))
|
||||
_drop_metadata(vgname);
|
||||
}
|
||||
|
||||
void lvmcache_lock_vgname(const char *vgname, int read_only __attribute((unused)))
|
||||
{
|
||||
if (!_lock_hash && !lvmcache_init()) {
|
||||
@@ -56,10 +178,17 @@ void lvmcache_lock_vgname(const char *vgname, int read_only __attribute((unused)
|
||||
return;
|
||||
}
|
||||
|
||||
if (dm_hash_lookup(_lock_hash, vgname))
|
||||
log_error("Internal error: Nested locking attempted on VG %s.",
|
||||
vgname);
|
||||
|
||||
if (!dm_hash_insert(_lock_hash, vgname, (void *) 1))
|
||||
log_error("Cache locking failure for %s", vgname);
|
||||
|
||||
_vgs_locked++;
|
||||
_update_cache_lock_state(vgname, 1);
|
||||
|
||||
if (strcmp(vgname, VG_GLOBAL))
|
||||
_vgs_locked++;
|
||||
}
|
||||
|
||||
int vgname_is_locked(const char *vgname)
|
||||
@@ -72,11 +201,16 @@ int vgname_is_locked(const char *vgname)
|
||||
|
||||
void lvmcache_unlock_vgname(const char *vgname)
|
||||
{
|
||||
/* FIXME: Clear all CACHE_LOCKED flags in this vg */
|
||||
if (!dm_hash_lookup(_lock_hash, vgname))
|
||||
log_error("Internal error: Attempt to unlock unlocked VG %s.",
|
||||
vgname);
|
||||
|
||||
_update_cache_lock_state(vgname, 0);
|
||||
|
||||
dm_hash_remove(_lock_hash, vgname);
|
||||
|
||||
/* FIXME Do this per-VG */
|
||||
if (!--_vgs_locked)
|
||||
if (strcmp(vgname, VG_GLOBAL) && !--_vgs_locked)
|
||||
dev_close_all();
|
||||
}
|
||||
|
||||
@@ -85,11 +219,34 @@ int vgs_locked(void)
|
||||
return _vgs_locked;
|
||||
}
|
||||
|
||||
static void _vginfo_attach_info(struct lvmcache_vginfo *vginfo,
|
||||
struct lvmcache_info *info)
|
||||
{
|
||||
if (!vginfo)
|
||||
return;
|
||||
|
||||
info->vginfo = vginfo;
|
||||
dm_list_add(&vginfo->infos, &info->list);
|
||||
}
|
||||
|
||||
static void _vginfo_detach_info(struct lvmcache_info *info)
|
||||
{
|
||||
if (!dm_list_empty(&info->list)) {
|
||||
dm_list_del(&info->list);
|
||||
dm_list_init(&info->list);
|
||||
}
|
||||
|
||||
info->vginfo = NULL;
|
||||
}
|
||||
|
||||
/* If vgid supplied, require a match. */
|
||||
struct lvmcache_vginfo *vginfo_from_vgname(const char *vgname, const char *vgid)
|
||||
{
|
||||
struct lvmcache_vginfo *vginfo;
|
||||
|
||||
if (!vgname)
|
||||
return vginfo_from_vgid(vgid);
|
||||
|
||||
if (!_vgname_hash)
|
||||
return NULL;
|
||||
|
||||
@@ -97,7 +254,7 @@ struct lvmcache_vginfo *vginfo_from_vgname(const char *vgname, const char *vgid)
|
||||
return NULL;
|
||||
|
||||
if (vgid)
|
||||
do
|
||||
do
|
||||
if (!strncmp(vgid, vginfo->vgid, ID_LEN))
|
||||
return vginfo;
|
||||
while ((vginfo = vginfo->next));
|
||||
@@ -110,8 +267,8 @@ const struct format_type *fmt_from_vgname(const char *vgname, const char *vgid)
|
||||
struct lvmcache_vginfo *vginfo;
|
||||
struct lvmcache_info *info;
|
||||
struct label *label;
|
||||
struct list *devh, *tmp;
|
||||
struct list devs;
|
||||
struct dm_list *devh, *tmp;
|
||||
struct dm_list devs;
|
||||
struct device_list *devl;
|
||||
char vgid_found[ID_LEN + 1] __attribute((aligned(8)));
|
||||
|
||||
@@ -120,22 +277,22 @@ const struct format_type *fmt_from_vgname(const char *vgname, const char *vgid)
|
||||
|
||||
/* This function is normally called before reading metadata so
|
||||
* we check cached labels here. Unfortunately vginfo is volatile. */
|
||||
list_init(&devs);
|
||||
list_iterate_items(info, &vginfo->infos) {
|
||||
dm_list_init(&devs);
|
||||
dm_list_iterate_items(info, &vginfo->infos) {
|
||||
if (!(devl = dm_malloc(sizeof(*devl)))) {
|
||||
log_error("device_list element allocation failed");
|
||||
return NULL;
|
||||
}
|
||||
devl->dev = info->dev;
|
||||
list_add(&devs, &devl->list);
|
||||
dm_list_add(&devs, &devl->list);
|
||||
}
|
||||
|
||||
memcpy(vgid_found, vginfo->vgid, sizeof(vgid_found));
|
||||
|
||||
list_iterate_safe(devh, tmp, &devs) {
|
||||
devl = list_item(devh, struct device_list);
|
||||
dm_list_iterate_safe(devh, tmp, &devs) {
|
||||
devl = dm_list_item(devh, struct device_list);
|
||||
label_read(devl->dev, &label, UINT64_C(0));
|
||||
list_del(&devl->list);
|
||||
dm_list_del(&devl->list);
|
||||
dm_free(devl);
|
||||
}
|
||||
|
||||
@@ -170,9 +327,6 @@ const char *vgname_from_vgid(struct dm_pool *mem, const char *vgid)
|
||||
struct lvmcache_vginfo *vginfo;
|
||||
const char *vgname = NULL;
|
||||
|
||||
if (!*vgid)
|
||||
vgname = ORPHAN;
|
||||
|
||||
if ((vginfo = vginfo_from_vgid(vgid)))
|
||||
vgname = vginfo->vgname;
|
||||
|
||||
@@ -182,7 +336,56 @@ const char *vgname_from_vgid(struct dm_pool *mem, const char *vgid)
|
||||
return vgname;
|
||||
}
|
||||
|
||||
struct lvmcache_info *info_from_pvid(const char *pvid)
|
||||
static int _info_is_valid(struct lvmcache_info *info)
|
||||
{
|
||||
if (info->status & CACHE_INVALID)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* The caller must hold the VG lock to manipulate metadata.
|
||||
* In a cluster, remote nodes sometimes read metadata in the
|
||||
* knowledge that the controlling node is holding the lock.
|
||||
* So if the VG appears to be unlocked here, it should be safe
|
||||
* to use the cached value.
|
||||
*/
|
||||
if (info->vginfo && !vgname_is_locked(info->vginfo->vgname))
|
||||
return 1;
|
||||
|
||||
if (!(info->status & CACHE_LOCKED))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _vginfo_is_valid(struct lvmcache_vginfo *vginfo)
|
||||
{
|
||||
struct lvmcache_info *info;
|
||||
|
||||
/* Invalid if any info is invalid */
|
||||
dm_list_iterate_items(info, &vginfo->infos)
|
||||
if (!_info_is_valid(info))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* vginfo is invalid if it does not contain at least one valid info */
|
||||
static int _vginfo_is_invalid(struct lvmcache_vginfo *vginfo)
|
||||
{
|
||||
struct lvmcache_info *info;
|
||||
|
||||
dm_list_iterate_items(info, &vginfo->infos)
|
||||
if (_info_is_valid(info))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* If valid_only is set, data will only be returned if the cached data is
|
||||
* known still to be valid.
|
||||
*/
|
||||
struct lvmcache_info *info_from_pvid(const char *pvid, int valid_only)
|
||||
{
|
||||
struct lvmcache_info *info;
|
||||
char id[ID_LEN + 1] __attribute((aligned(8)));
|
||||
@@ -196,6 +399,9 @@ struct lvmcache_info *info_from_pvid(const char *pvid)
|
||||
if (!(info = dm_hash_lookup(_pvid_hash, id)))
|
||||
return NULL;
|
||||
|
||||
if (valid_only && !_info_is_valid(info))
|
||||
return NULL;
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
@@ -221,7 +427,6 @@ int lvmcache_label_scan(struct cmd_context *cmd, int full_scan)
|
||||
struct device *dev;
|
||||
struct format_type *fmt;
|
||||
|
||||
static int _scanning_in_progress = 0;
|
||||
int r = 0;
|
||||
|
||||
/* Avoid recursion when a PVID can't be found! */
|
||||
@@ -253,7 +458,7 @@ int lvmcache_label_scan(struct cmd_context *cmd, int full_scan)
|
||||
_has_scanned = 1;
|
||||
|
||||
/* Perform any format-specific scanning e.g. text files */
|
||||
list_iterate_items(fmt, &cmd->formats) {
|
||||
dm_list_iterate_items(fmt, &cmd->formats) {
|
||||
if (fmt->ops->scan && !fmt->ops->scan(fmt))
|
||||
goto out;
|
||||
}
|
||||
@@ -266,9 +471,54 @@ int lvmcache_label_scan(struct cmd_context *cmd, int full_scan)
|
||||
return r;
|
||||
}
|
||||
|
||||
struct list *lvmcache_get_vgids(struct cmd_context *cmd, int full_scan)
|
||||
struct volume_group *lvmcache_get_vg(const char *vgid, unsigned precommitted)
|
||||
{
|
||||
struct list *vgids;
|
||||
struct lvmcache_vginfo *vginfo;
|
||||
struct volume_group *vg;
|
||||
struct format_instance *fid;
|
||||
|
||||
if (!vgid || !(vginfo = vginfo_from_vgid(vgid)) || !vginfo->vgmetadata)
|
||||
return NULL;
|
||||
|
||||
if (!_vginfo_is_valid(vginfo))
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Don't return cached data if either:
|
||||
* (i) precommitted metadata is requested but we don't have it cached
|
||||
* - caller should read it off disk;
|
||||
* (ii) live metadata is requested but we have precommitted metadata cached
|
||||
* and no devices are suspended so caller may read it off disk.
|
||||
*
|
||||
* If live metadata is requested but we have precommitted metadata cached
|
||||
* and devices are suspended, we assume this precommitted metadata has
|
||||
* already been preloaded and committed so it's OK to return it as live.
|
||||
* Note that we do not clear the PRECOMMITTED flag.
|
||||
*/
|
||||
if ((precommitted && !vginfo->precommitted) ||
|
||||
(!precommitted && vginfo->precommitted && !memlock()))
|
||||
return NULL;
|
||||
|
||||
if (!(fid = vginfo->fmt->ops->create_instance(vginfo->fmt,
|
||||
vginfo->vgname,
|
||||
vgid, NULL)))
|
||||
return_NULL;
|
||||
|
||||
if (!(vg = import_vg_from_buffer(vginfo->vgmetadata, fid)) ||
|
||||
!vg_validate(vg)) {
|
||||
_free_cached_vgmetadata(vginfo);
|
||||
return_NULL;
|
||||
}
|
||||
|
||||
log_debug("Using cached %smetadata for VG %s.",
|
||||
vginfo->precommitted ? "pre-committed" : "", vginfo->vgname);
|
||||
|
||||
return vg;
|
||||
}
|
||||
|
||||
struct dm_list *lvmcache_get_vgids(struct cmd_context *cmd, int full_scan)
|
||||
{
|
||||
struct dm_list *vgids;
|
||||
struct lvmcache_vginfo *vginfo;
|
||||
|
||||
lvmcache_label_scan(cmd, full_scan);
|
||||
@@ -278,8 +528,8 @@ struct list *lvmcache_get_vgids(struct cmd_context *cmd, int full_scan)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list_iterate_items(vginfo, &_vginfos) {
|
||||
if (!str_list_add(cmd->mem, vgids,
|
||||
dm_list_iterate_items(vginfo, &_vginfos) {
|
||||
if (!str_list_add(cmd->mem, vgids,
|
||||
dm_pool_strdup(cmd->mem, vginfo->vgid))) {
|
||||
log_error("strlist allocation failed");
|
||||
return NULL;
|
||||
@@ -289,9 +539,9 @@ struct list *lvmcache_get_vgids(struct cmd_context *cmd, int full_scan)
|
||||
return vgids;
|
||||
}
|
||||
|
||||
struct list *lvmcache_get_vgnames(struct cmd_context *cmd, int full_scan)
|
||||
struct dm_list *lvmcache_get_vgnames(struct cmd_context *cmd, int full_scan)
|
||||
{
|
||||
struct list *vgnames;
|
||||
struct dm_list *vgnames;
|
||||
struct lvmcache_vginfo *vginfo;
|
||||
|
||||
lvmcache_label_scan(cmd, full_scan);
|
||||
@@ -301,8 +551,8 @@ struct list *lvmcache_get_vgnames(struct cmd_context *cmd, int full_scan)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list_iterate_items(vginfo, &_vginfos) {
|
||||
if (!str_list_add(cmd->mem, vgnames,
|
||||
dm_list_iterate_items(vginfo, &_vginfos) {
|
||||
if (!str_list_add(cmd->mem, vgnames,
|
||||
dm_pool_strdup(cmd->mem, vginfo->vgname))) {
|
||||
log_error("strlist allocation failed");
|
||||
return NULL;
|
||||
@@ -312,10 +562,10 @@ struct list *lvmcache_get_vgnames(struct cmd_context *cmd, int full_scan)
|
||||
return vgnames;
|
||||
}
|
||||
|
||||
struct list *lvmcache_get_pvids(struct cmd_context *cmd, const char *vgname,
|
||||
struct dm_list *lvmcache_get_pvids(struct cmd_context *cmd, const char *vgname,
|
||||
const char *vgid)
|
||||
{
|
||||
struct list *pvids;
|
||||
struct dm_list *pvids;
|
||||
struct lvmcache_vginfo *vginfo;
|
||||
struct lvmcache_info *info;
|
||||
|
||||
@@ -327,8 +577,8 @@ struct list *lvmcache_get_pvids(struct cmd_context *cmd, const char *vgname,
|
||||
if (!(vginfo = vginfo_from_vgname(vgname, vgid)))
|
||||
return pvids;
|
||||
|
||||
list_iterate_items(info, &vginfo->infos) {
|
||||
if (!str_list_add(cmd->mem, pvids,
|
||||
dm_list_iterate_items(info, &vginfo->infos) {
|
||||
if (!str_list_add(cmd->mem, pvids,
|
||||
dm_pool_strdup(cmd->mem, info->dev->pvid))) {
|
||||
log_error("strlist allocation failed");
|
||||
return NULL;
|
||||
@@ -344,7 +594,7 @@ struct device *device_from_pvid(struct cmd_context *cmd, struct id *pvid)
|
||||
struct lvmcache_info *info;
|
||||
|
||||
/* Already cached ? */
|
||||
if ((info = info_from_pvid((char *) pvid))) {
|
||||
if ((info = info_from_pvid((char *) pvid, 0))) {
|
||||
if (label_read(info->dev, &label, UINT64_C(0))) {
|
||||
info = (struct lvmcache_info *) label->info;
|
||||
if (id_equal(pvid, (struct id *) &info->dev->pvid))
|
||||
@@ -355,7 +605,7 @@ struct device *device_from_pvid(struct cmd_context *cmd, struct id *pvid)
|
||||
lvmcache_label_scan(cmd, 0);
|
||||
|
||||
/* Try again */
|
||||
if ((info = info_from_pvid((char *) pvid))) {
|
||||
if ((info = info_from_pvid((char *) pvid, 0))) {
|
||||
if (label_read(info->dev, &label, UINT64_C(0))) {
|
||||
info = (struct lvmcache_info *) label->info;
|
||||
if (id_equal(pvid, (struct id *) &info->dev->pvid))
|
||||
@@ -369,7 +619,7 @@ struct device *device_from_pvid(struct cmd_context *cmd, struct id *pvid)
|
||||
lvmcache_label_scan(cmd, 2);
|
||||
|
||||
/* Try again */
|
||||
if ((info = info_from_pvid((char *) pvid))) {
|
||||
if ((info = info_from_pvid((char *) pvid, 0))) {
|
||||
if (label_read(info->dev, &label, UINT64_C(0))) {
|
||||
info = (struct lvmcache_info *) label->info;
|
||||
if (id_equal(pvid, (struct id *) &info->dev->pvid))
|
||||
@@ -380,34 +630,62 @@ struct device *device_from_pvid(struct cmd_context *cmd, struct id *pvid)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int _drop_vginfo(struct lvmcache_info *info)
|
||||
static int _free_vginfo(struct lvmcache_vginfo *vginfo)
|
||||
{
|
||||
if (!list_empty(&info->list)) {
|
||||
list_del(&info->list);
|
||||
list_init(&info->list);
|
||||
}
|
||||
struct lvmcache_vginfo *primary_vginfo, *vginfo2;
|
||||
int r = 1;
|
||||
|
||||
if (info->vginfo && list_empty(&info->vginfo->infos)) {
|
||||
dm_hash_remove(_vgname_hash, info->vginfo->vgname);
|
||||
if (info->vginfo->next) {
|
||||
if (!dm_hash_insert(_vgname_hash, info->vginfo->vgname, info->vginfo->next)) {
|
||||
log_error("vg hash re-insertion failed: %s",
|
||||
info->vginfo->vgname);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
_free_cached_vgmetadata(vginfo);
|
||||
|
||||
if (info->vginfo->vgname)
|
||||
dm_free(info->vginfo->vgname);
|
||||
if (info->vginfo->creation_host)
|
||||
dm_free(info->vginfo->creation_host);
|
||||
if (*info->vginfo->vgid)
|
||||
dm_hash_remove(_vgid_hash, info->vginfo->vgid);
|
||||
list_del(&info->vginfo->list);
|
||||
dm_free(info->vginfo);
|
||||
}
|
||||
vginfo2 = primary_vginfo = vginfo_from_vgname(vginfo->vgname, NULL);
|
||||
|
||||
info->vginfo = NULL;
|
||||
if (vginfo == primary_vginfo) {
|
||||
dm_hash_remove(_vgname_hash, vginfo->vgname);
|
||||
if (vginfo->next && !dm_hash_insert(_vgname_hash, vginfo->vgname,
|
||||
vginfo->next)) {
|
||||
log_error("_vgname_hash re-insertion for %s failed",
|
||||
vginfo->vgname);
|
||||
r = 0;
|
||||
}
|
||||
} else do
|
||||
if (vginfo2->next == vginfo) {
|
||||
vginfo2->next = vginfo->next;
|
||||
break;
|
||||
}
|
||||
while ((vginfo2 = primary_vginfo->next));
|
||||
|
||||
if (vginfo->vgname)
|
||||
dm_free(vginfo->vgname);
|
||||
|
||||
if (vginfo->creation_host)
|
||||
dm_free(vginfo->creation_host);
|
||||
|
||||
if (*vginfo->vgid && _vgid_hash &&
|
||||
vginfo_from_vgid(vginfo->vgid) == vginfo)
|
||||
dm_hash_remove(_vgid_hash, vginfo->vgid);
|
||||
|
||||
dm_list_del(&vginfo->list);
|
||||
|
||||
dm_free(vginfo);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* vginfo must be info->vginfo unless info is NULL
|
||||
*/
|
||||
static int _drop_vginfo(struct lvmcache_info *info, struct lvmcache_vginfo *vginfo)
|
||||
{
|
||||
if (info)
|
||||
_vginfo_detach_info(info);
|
||||
|
||||
/* vginfo still referenced? */
|
||||
if (!vginfo || is_orphan_vg(vginfo->vgname) ||
|
||||
!dm_list_empty(&vginfo->infos))
|
||||
return 1;
|
||||
|
||||
if (!_free_vginfo(vginfo))
|
||||
return_0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -418,10 +696,10 @@ void lvmcache_del(struct lvmcache_info *info)
|
||||
if (info->dev->pvid[0] && _pvid_hash)
|
||||
dm_hash_remove(_pvid_hash, info->dev->pvid);
|
||||
|
||||
_drop_vginfo(info);
|
||||
_drop_vginfo(info, info->vginfo);
|
||||
|
||||
info->label->labeller->ops->destroy_label(info->label->labeller,
|
||||
info->label);
|
||||
info->label);
|
||||
dm_free(info);
|
||||
|
||||
return;
|
||||
@@ -443,29 +721,36 @@ static int _lvmcache_update_pvid(struct lvmcache_info *info, const char *pvid)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _lvmcache_update_vgid(struct lvmcache_info *info, const char *vgid)
|
||||
/*
|
||||
* vginfo must be info->vginfo unless info is NULL (orphans)
|
||||
*/
|
||||
static int _lvmcache_update_vgid(struct lvmcache_info *info,
|
||||
struct lvmcache_vginfo *vginfo,
|
||||
const char *vgid)
|
||||
{
|
||||
if (!vgid || !info->vginfo ||
|
||||
!strncmp(info->vginfo->vgid, vgid, ID_LEN))
|
||||
if (!vgid || !vginfo ||
|
||||
!strncmp(vginfo->vgid, vgid, ID_LEN))
|
||||
return 1;
|
||||
|
||||
if (info->vginfo && *info->vginfo->vgid)
|
||||
dm_hash_remove(_vgid_hash, info->vginfo->vgid);
|
||||
if (vginfo && *vginfo->vgid)
|
||||
dm_hash_remove(_vgid_hash, vginfo->vgid);
|
||||
if (!vgid) {
|
||||
log_debug("lvmcache: %s: clearing VGID", dev_name(info->dev));
|
||||
log_debug("lvmcache: %s: clearing VGID", info ? dev_name(info->dev) : vginfo->vgname);
|
||||
return 1;
|
||||
}
|
||||
|
||||
strncpy(info->vginfo->vgid, vgid, ID_LEN);
|
||||
info->vginfo->vgid[ID_LEN] = '\0';
|
||||
if (!dm_hash_insert(_vgid_hash, info->vginfo->vgid, info->vginfo)) {
|
||||
strncpy(vginfo->vgid, vgid, ID_LEN);
|
||||
vginfo->vgid[ID_LEN] = '\0';
|
||||
if (!dm_hash_insert(_vgid_hash, vginfo->vgid, vginfo)) {
|
||||
log_error("_lvmcache_update: vgid hash insertion failed: %s",
|
||||
info->vginfo->vgid);
|
||||
vginfo->vgid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
log_debug("lvmcache: %s: setting %s VGID to %s", dev_name(info->dev),
|
||||
info->vginfo->vgname, info->vginfo->vgid);
|
||||
if (!is_orphan_vg(vginfo->vgname))
|
||||
log_debug("lvmcache: %s: setting %s VGID to %s",
|
||||
dev_name(info->dev), vginfo->vgname,
|
||||
vginfo->vgid);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -556,25 +841,20 @@ static int _insert_vginfo(struct lvmcache_vginfo *new_vginfo, const char *vgid,
|
||||
|
||||
static int _lvmcache_update_vgname(struct lvmcache_info *info,
|
||||
const char *vgname, const char *vgid,
|
||||
uint32_t vgstatus, const char *creation_host)
|
||||
uint32_t vgstatus, const char *creation_host,
|
||||
const struct format_type *fmt)
|
||||
{
|
||||
struct lvmcache_vginfo *vginfo, *primary_vginfo;
|
||||
struct lvmcache_vginfo *vginfo, *primary_vginfo, *orphan_vginfo;
|
||||
struct lvmcache_info *info2, *info3;
|
||||
char mdabuf[32];
|
||||
// struct lvmcache_vginfo *old_vginfo, *next;
|
||||
|
||||
/* If vgname is NULL and we don't already have a vgname,
|
||||
* assume ORPHAN - we want every entry to have a vginfo
|
||||
* attached for scanning reasons.
|
||||
*/
|
||||
if (!vgname && !info->vginfo) {
|
||||
vgname = ORPHAN;
|
||||
vgid = ORPHAN;
|
||||
}
|
||||
|
||||
if (!vgname || (info->vginfo && !strcmp(info->vginfo->vgname, vgname)))
|
||||
if (!vgname || (info && info->vginfo && !strcmp(info->vginfo->vgname, vgname)))
|
||||
return 1;
|
||||
|
||||
/* Remove existing vginfo entry */
|
||||
_drop_vginfo(info);
|
||||
if (info)
|
||||
_drop_vginfo(info, info->vginfo);
|
||||
|
||||
/* Get existing vginfo or create new one */
|
||||
if (!(vginfo = vginfo_from_vgname(vgname, vgid))) {
|
||||
@@ -587,9 +867,9 @@ static int _lvmcache_update_vgname(struct lvmcache_info *info,
|
||||
dm_hash_remove(_vgname_hash, old_vginfo->vgname);
|
||||
if (old_vginfo->next) {
|
||||
if (!dm_hash_insert(_vgname_hash, old_vginfo->vgname, old_vginfo->next)) {
|
||||
log_error("vg hash re-insertion failed: %s",
|
||||
log_error("vg hash re-insertion failed: %s",
|
||||
old_vginfo->vgname);
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else do {
|
||||
@@ -606,11 +886,11 @@ static int _lvmcache_update_vgname(struct lvmcache_info *info,
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Rename so can assume new name does not already exist
|
||||
// Rename so can assume new name does not already exist
|
||||
if (!dm_hash_insert(_vgname_hash, vginfo->vgname, vginfo->next)) {
|
||||
log_error("vg hash re-insertion failed: %s",
|
||||
vginfo->vgname);
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
***/
|
||||
@@ -624,8 +904,30 @@ static int _lvmcache_update_vgname(struct lvmcache_info *info,
|
||||
log_error("cache vgname alloc failed for %s", vgname);
|
||||
return 0;
|
||||
}
|
||||
list_init(&vginfo->infos);
|
||||
primary_vginfo = vginfo_from_vgname(vgname, NULL);
|
||||
dm_list_init(&vginfo->infos);
|
||||
|
||||
/*
|
||||
* If we're scanning and there's an invalidated entry, remove it.
|
||||
* Otherwise we risk bogus warnings of duplicate VGs.
|
||||
*/
|
||||
while ((primary_vginfo = vginfo_from_vgname(vgname, NULL)) &&
|
||||
_scanning_in_progress && _vginfo_is_invalid(primary_vginfo))
|
||||
dm_list_iterate_items_safe(info2, info3, &primary_vginfo->infos) {
|
||||
orphan_vginfo = vginfo_from_vgname(primary_vginfo->fmt->orphan_vg_name, NULL);
|
||||
_drop_vginfo(info2, primary_vginfo);
|
||||
_vginfo_attach_info(orphan_vginfo, info2);
|
||||
if (info2->mdas.n)
|
||||
sprintf(mdabuf, " with %u mdas",
|
||||
dm_list_size(&info2->mdas));
|
||||
else
|
||||
mdabuf[0] = '\0';
|
||||
log_debug("lvmcache: %s: now in VG %s%s%s%s%s",
|
||||
dev_name(info2->dev),
|
||||
vgname, orphan_vginfo->vgid[0] ? " (" : "",
|
||||
orphan_vginfo->vgid[0] ? orphan_vginfo->vgid : "",
|
||||
orphan_vginfo->vgid[0] ? ")" : "", mdabuf);
|
||||
}
|
||||
|
||||
if (!_insert_vginfo(vginfo, vgid, vgstatus, creation_host,
|
||||
primary_vginfo)) {
|
||||
dm_free(vginfo->vgname);
|
||||
@@ -634,25 +936,36 @@ static int _lvmcache_update_vgname(struct lvmcache_info *info,
|
||||
}
|
||||
/* Ensure orphans appear last on list_iterate */
|
||||
if (is_orphan_vg(vgname))
|
||||
list_add(&_vginfos, &vginfo->list);
|
||||
dm_list_add(&_vginfos, &vginfo->list);
|
||||
else
|
||||
list_add_h(&_vginfos, &vginfo->list);
|
||||
dm_list_add_h(&_vginfos, &vginfo->list);
|
||||
/***
|
||||
}
|
||||
***/
|
||||
}
|
||||
|
||||
info->vginfo = vginfo;
|
||||
list_add(&vginfo->infos, &info->list);
|
||||
if (info)
|
||||
_vginfo_attach_info(vginfo, info);
|
||||
else if (!_lvmcache_update_vgid(NULL, vginfo, vgid)) /* Orphans */
|
||||
return_0;
|
||||
|
||||
_update_cache_vginfo_lock_state(vginfo, vgname_is_locked(vgname));
|
||||
|
||||
/* FIXME Check consistency of list! */
|
||||
vginfo->fmt = info->fmt;
|
||||
vginfo->fmt = fmt;
|
||||
|
||||
log_debug("lvmcache: %s: now %s%s%s%s%s", dev_name(info->dev),
|
||||
!is_orphan_vg(vgname) ? "in VG " : "orphaned", vgname,
|
||||
vginfo->vgid[0] ? " (" : "",
|
||||
vginfo->vgid[0] ? vginfo->vgid : "",
|
||||
vginfo->vgid[0] ? ")" : "");
|
||||
if (info) {
|
||||
if (info->mdas.n)
|
||||
sprintf(mdabuf, " with %u mdas", dm_list_size(&info->mdas));
|
||||
else
|
||||
mdabuf[0] = '\0';
|
||||
log_debug("lvmcache: %s: now in VG %s%s%s%s%s",
|
||||
dev_name(info->dev),
|
||||
vgname, vginfo->vgid[0] ? " (" : "",
|
||||
vginfo->vgid[0] ? vginfo->vgid : "",
|
||||
vginfo->vgid[0] ? ")" : "", mdabuf);
|
||||
} else
|
||||
log_debug("lvmcache: initialised VG %s", vgname);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -692,37 +1005,69 @@ static int _lvmcache_update_vgstatus(struct lvmcache_info *info, uint32_t vgstat
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lvmcache_add_orphan_vginfo(const char *vgname, struct format_type *fmt)
|
||||
{
|
||||
if (!_lock_hash && !lvmcache_init()) {
|
||||
log_error("Internal cache initialisation failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return _lvmcache_update_vgname(NULL, vgname, vgname, 0, "", fmt);
|
||||
}
|
||||
|
||||
int lvmcache_update_vgname_and_id(struct lvmcache_info *info,
|
||||
const char *vgname, const char *vgid,
|
||||
uint32_t vgstatus, const char *creation_host)
|
||||
{
|
||||
if (!vgname && !info->vginfo) {
|
||||
log_error("Internal error: NULL vgname handed to cache");
|
||||
/* FIXME Remove this */
|
||||
vgname = info->fmt->orphan_vg_name;
|
||||
vgid = vgname;
|
||||
}
|
||||
|
||||
/* If PV without mdas is already in a real VG, don't make it orphan */
|
||||
if (is_orphan_vg(vgname) && info->vginfo && !dm_list_size(&info->mdas) &&
|
||||
!is_orphan_vg(info->vginfo->vgname) && memlock())
|
||||
return 1;
|
||||
|
||||
/* If moving PV from orphan to real VG, always mark it valid */
|
||||
if (!is_orphan_vg(vgname))
|
||||
info->status &= ~CACHE_INVALID;
|
||||
|
||||
if (!_lvmcache_update_vgname(info, vgname, vgid, vgstatus,
|
||||
creation_host) ||
|
||||
!_lvmcache_update_vgid(info, vgid) ||
|
||||
creation_host, info->fmt) ||
|
||||
!_lvmcache_update_vgid(info, info->vginfo, vgid) ||
|
||||
!_lvmcache_update_vgstatus(info, vgstatus, creation_host))
|
||||
return_0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lvmcache_update_vg(struct volume_group *vg)
|
||||
int lvmcache_update_vg(struct volume_group *vg, unsigned precommitted)
|
||||
{
|
||||
struct pv_list *pvl;
|
||||
struct lvmcache_info *info;
|
||||
struct lvmcache_vginfo *vginfo;
|
||||
char pvid_s[ID_LEN + 1] __attribute((aligned(8)));
|
||||
|
||||
pvid_s[sizeof(pvid_s) - 1] = '\0';
|
||||
|
||||
list_iterate_items(pvl, &vg->pvs) {
|
||||
dm_list_iterate_items(pvl, &vg->pvs) {
|
||||
strncpy(pvid_s, (char *) &pvl->pv->id, sizeof(pvid_s) - 1);
|
||||
/* FIXME Could pvl->pv->dev->pvid ever be different? */
|
||||
if ((info = info_from_pvid(pvid_s)) &&
|
||||
if ((info = info_from_pvid(pvid_s, 0)) &&
|
||||
!lvmcache_update_vgname_and_id(info, vg->name,
|
||||
(char *) &vg->id,
|
||||
vg->status, NULL))
|
||||
return_0;
|
||||
}
|
||||
|
||||
/* store text representation of vg to cache */
|
||||
if (vg->cmd->current_settings.cache_vgmetadata &&
|
||||
(vginfo = vginfo_from_vgname(vg->name, NULL)))
|
||||
_store_metadata(vginfo, vg, precommitted);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -743,12 +1088,10 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
|
||||
strncpy(pvid_s, pvid, sizeof(pvid_s));
|
||||
pvid_s[sizeof(pvid_s) - 1] = '\0';
|
||||
|
||||
if (!(existing = info_from_pvid(pvid_s)) &&
|
||||
!(existing = info_from_pvid(dev->pvid))) {
|
||||
if (!(label = label_create(labeller))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
if (!(existing = info_from_pvid(pvid_s, 0)) &&
|
||||
!(existing = info_from_pvid(dev->pvid, 0))) {
|
||||
if (!(label = label_create(labeller)))
|
||||
return_NULL;
|
||||
if (!(info = dm_malloc(sizeof(*info)))) {
|
||||
log_error("lvmcache_info allocation failed");
|
||||
label_destroy(label);
|
||||
@@ -758,7 +1101,7 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
|
||||
|
||||
label->info = info;
|
||||
info->label = label;
|
||||
list_init(&info->list);
|
||||
dm_list_init(&info->list);
|
||||
info->dev = dev;
|
||||
} else {
|
||||
if (existing->dev != dev) {
|
||||
@@ -804,11 +1147,9 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
|
||||
/* Has labeller changed? */
|
||||
if (info->label->labeller != labeller) {
|
||||
label_destroy(info->label);
|
||||
if (!(info->label = label_create(labeller))) {
|
||||
if (!(info->label = label_create(labeller)))
|
||||
/* FIXME leaves info without label! */
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
return_NULL;
|
||||
info->label->info = info;
|
||||
}
|
||||
label = info->label;
|
||||
@@ -840,8 +1181,7 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
|
||||
|
||||
static void _lvmcache_destroy_entry(struct lvmcache_info *info)
|
||||
{
|
||||
if (!list_empty(&info->list))
|
||||
list_del(&info->list);
|
||||
_vginfo_detach_info(info);
|
||||
strcpy(info->dev->pvid, "");
|
||||
label_destroy(info->label);
|
||||
dm_free(info);
|
||||
@@ -853,21 +1193,30 @@ static void _lvmcache_destroy_vgnamelist(struct lvmcache_vginfo *vginfo)
|
||||
|
||||
do {
|
||||
next = vginfo->next;
|
||||
if (vginfo->vgname)
|
||||
dm_free(vginfo->vgname);
|
||||
if (vginfo->creation_host)
|
||||
dm_free(vginfo->creation_host);
|
||||
dm_free(vginfo);
|
||||
if (!_free_vginfo(vginfo))
|
||||
stack;
|
||||
} while ((vginfo = next));
|
||||
}
|
||||
|
||||
static void _lvmcache_destroy_lockname(int present __attribute((unused)))
|
||||
static void _lvmcache_destroy_lockname(struct dm_hash_node *n)
|
||||
{
|
||||
/* Nothing to do */
|
||||
char *vgname;
|
||||
|
||||
if (!dm_hash_get_data(_lock_hash, n))
|
||||
return;
|
||||
|
||||
vgname = dm_hash_get_key(_lock_hash, n);
|
||||
|
||||
if (!strcmp(vgname, VG_GLOBAL))
|
||||
_vg_global_lock_held = 1;
|
||||
else
|
||||
log_error("Internal error: Volume Group %s was not unlocked",
|
||||
dm_hash_get_key(_lock_hash, n));
|
||||
}
|
||||
|
||||
void lvmcache_destroy(void)
|
||||
void lvmcache_destroy(struct cmd_context *cmd, int retain_orphans)
|
||||
{
|
||||
struct dm_hash_node *n;
|
||||
log_verbose("Wiping internal VG cache");
|
||||
|
||||
_has_scanned = 0;
|
||||
@@ -891,10 +1240,16 @@ void lvmcache_destroy(void)
|
||||
}
|
||||
|
||||
if (_lock_hash) {
|
||||
dm_hash_iter(_lock_hash, (dm_hash_iterate_fn) _lvmcache_destroy_lockname);
|
||||
dm_hash_iterate(n, _lock_hash)
|
||||
_lvmcache_destroy_lockname(n);
|
||||
dm_hash_destroy(_lock_hash);
|
||||
_lock_hash = NULL;
|
||||
}
|
||||
|
||||
list_init(&_vginfos);
|
||||
if (!dm_list_empty(&_vginfos))
|
||||
log_error("Internal error: _vginfos list should be empty");
|
||||
dm_list_init(&_vginfos);
|
||||
|
||||
if (retain_orphans)
|
||||
init_lvmcache_orphans(cmd);
|
||||
}
|
||||
|
||||
34
lib/cache/lvmcache.h
vendored
34
lib/cache/lvmcache.h
vendored
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
*
|
||||
@@ -20,7 +20,8 @@
|
||||
#include "uuid.h"
|
||||
#include "label.h"
|
||||
|
||||
#define ORPHAN ""
|
||||
#define ORPHAN_PREFIX "#"
|
||||
#define ORPHAN_VG_NAME(fmt) ORPHAN_PREFIX "orphans_" fmt
|
||||
|
||||
#define CACHE_INVALID 0x00000001
|
||||
#define CACHE_LOCKED 0x00000002
|
||||
@@ -34,8 +35,8 @@ struct volume_group;
|
||||
|
||||
/* One per VG */
|
||||
struct lvmcache_vginfo {
|
||||
struct list list; /* Join these vginfos together */
|
||||
struct list infos; /* List head for lvmcache_infos */
|
||||
struct dm_list list; /* Join these vginfos together */
|
||||
struct dm_list infos; /* List head for lvmcache_infos */
|
||||
const struct format_type *fmt;
|
||||
char *vgname; /* "" == orphan */
|
||||
uint32_t status;
|
||||
@@ -43,13 +44,15 @@ struct lvmcache_vginfo {
|
||||
char _padding[7];
|
||||
struct lvmcache_vginfo *next; /* Another VG with same name? */
|
||||
char *creation_host;
|
||||
char *vgmetadata; /* Copy of VG metadata as format_text string */
|
||||
unsigned precommitted; /* Is vgmetadata live or precommitted? */
|
||||
};
|
||||
|
||||
/* One per device */
|
||||
struct lvmcache_info {
|
||||
struct list list; /* Join VG members together */
|
||||
struct list mdas; /* list head for metadata areas */
|
||||
struct list das; /* list head for data areas */
|
||||
struct dm_list list; /* Join VG members together */
|
||||
struct dm_list mdas; /* list head for metadata areas */
|
||||
struct dm_list das; /* list head for data areas */
|
||||
struct lvmcache_vginfo *vginfo; /* NULL == unknown */
|
||||
struct label *label;
|
||||
const struct format_type *fmt;
|
||||
@@ -59,7 +62,7 @@ struct lvmcache_info {
|
||||
};
|
||||
|
||||
int lvmcache_init(void);
|
||||
void lvmcache_destroy(void);
|
||||
void lvmcache_destroy(struct cmd_context *cmd, int retain_orphans);
|
||||
|
||||
/* Set full_scan to 1 to reread every filtered device label or
|
||||
* 2 to rescan /dev for new devices */
|
||||
@@ -70,13 +73,14 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
|
||||
struct device *dev,
|
||||
const char *vgname, const char *vgid,
|
||||
uint32_t vgstatus);
|
||||
int lvmcache_add_orphan_vginfo(const char *vgname, struct format_type *fmt);
|
||||
void lvmcache_del(struct lvmcache_info *info);
|
||||
|
||||
/* Update things */
|
||||
int lvmcache_update_vgname_and_id(struct lvmcache_info *info,
|
||||
const char *vgname, const char *vgid,
|
||||
uint32_t vgstatus, const char *hostname);
|
||||
int lvmcache_update_vg(struct volume_group *vg);
|
||||
int lvmcache_update_vg(struct volume_group *vg, unsigned precommitted);
|
||||
|
||||
void lvmcache_lock_vgname(const char *vgname, int read_only);
|
||||
void lvmcache_unlock_vgname(const char *vgname);
|
||||
@@ -86,7 +90,7 @@ const struct format_type *fmt_from_vgname(const char *vgname, const char *vgid);
|
||||
struct lvmcache_vginfo *vginfo_from_vgname(const char *vgname,
|
||||
const char *vgid);
|
||||
struct lvmcache_vginfo *vginfo_from_vgid(const char *vgid);
|
||||
struct lvmcache_info *info_from_pvid(const char *pvid);
|
||||
struct lvmcache_info *info_from_pvid(const char *pvid, int valid_only);
|
||||
const char *vgname_from_vgid(struct dm_pool *mem, const char *vgid);
|
||||
struct device *device_from_pvid(struct cmd_context *cmd, struct id *pvid);
|
||||
int vgs_locked(void);
|
||||
@@ -94,14 +98,18 @@ int vgname_is_locked(const char *vgname);
|
||||
|
||||
/* Returns list of struct str_lists containing pool-allocated copy of vgnames */
|
||||
/* Set full_scan to 1 to reread every filtered device label */
|
||||
struct list *lvmcache_get_vgnames(struct cmd_context *cmd, int full_scan);
|
||||
struct dm_list *lvmcache_get_vgnames(struct cmd_context *cmd, int full_scan);
|
||||
|
||||
/* Returns list of struct str_lists containing pool-allocated copy of vgids */
|
||||
/* Set full_scan to 1 to reread every filtered device label */
|
||||
struct list *lvmcache_get_vgids(struct cmd_context *cmd, int full_scan);
|
||||
struct dm_list *lvmcache_get_vgids(struct cmd_context *cmd, int full_scan);
|
||||
|
||||
/* Returns list of struct str_lists containing pool-allocated copy of pvids */
|
||||
struct list *lvmcache_get_pvids(struct cmd_context *cmd, const char *vgname,
|
||||
struct dm_list *lvmcache_get_pvids(struct cmd_context *cmd, const char *vgname,
|
||||
const char *vgid);
|
||||
|
||||
/* Returns cached volume group metadata. */
|
||||
struct volume_group *lvmcache_get_vg(const char *vgid, unsigned precommitted);
|
||||
void lvmcache_drop_metadata(const char *vgname);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
@@ -75,6 +75,49 @@ static int _get_env_vars(struct cmd_context *cmd)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void _get_sysfs_dir(struct cmd_context *cmd)
|
||||
{
|
||||
static char proc_mounts[PATH_MAX];
|
||||
static char *split[4], buffer[PATH_MAX + 16];
|
||||
FILE *fp;
|
||||
char *sys_mnt = NULL;
|
||||
|
||||
cmd->sysfs_dir[0] = '\0';
|
||||
if (!*cmd->proc_dir) {
|
||||
log_debug("No proc filesystem found: skipping sysfs detection");
|
||||
return;
|
||||
}
|
||||
|
||||
if (dm_snprintf(proc_mounts, sizeof(proc_mounts),
|
||||
"%s/mounts", cmd->proc_dir) < 0) {
|
||||
log_error("Failed to create /proc/mounts string for sysfs detection");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(fp = fopen(proc_mounts, "r"))) {
|
||||
log_sys_error("_get_sysfs_dir: fopen %s", proc_mounts);
|
||||
return;
|
||||
}
|
||||
|
||||
while (fgets(buffer, sizeof(buffer), fp)) {
|
||||
if (dm_split_words(buffer, 4, 0, split) == 4 &&
|
||||
!strcmp(split[2], "sysfs")) {
|
||||
sys_mnt = split[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (fclose(fp))
|
||||
log_sys_error("fclose", proc_mounts);
|
||||
|
||||
if (!sys_mnt) {
|
||||
log_error("Failed to find sysfs mount point");
|
||||
return;
|
||||
}
|
||||
|
||||
strncpy(cmd->sysfs_dir, sys_mnt, sizeof(cmd->sysfs_dir));
|
||||
}
|
||||
|
||||
static void _init_logging(struct cmd_context *cmd)
|
||||
{
|
||||
int append = 1;
|
||||
@@ -154,6 +197,7 @@ static int _process_config(struct cmd_context *cmd)
|
||||
{
|
||||
mode_t old_umask;
|
||||
const char *read_ahead;
|
||||
struct stat st;
|
||||
|
||||
/* umask */
|
||||
cmd->default_settings.umask = find_config_tree_int(cmd,
|
||||
@@ -189,6 +233,8 @@ static int _process_config(struct cmd_context *cmd)
|
||||
cmd->proc_dir[0] = '\0';
|
||||
}
|
||||
|
||||
_get_sysfs_dir(cmd);
|
||||
|
||||
/* activation? */
|
||||
cmd->default_settings.activation = find_config_tree_int(cmd,
|
||||
"global/activation",
|
||||
@@ -218,6 +264,30 @@ static int _process_config(struct cmd_context *cmd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
cmd->stripe_filler = find_config_tree_str(cmd,
|
||||
"activation/missing_stripe_filler",
|
||||
DEFAULT_STRIPE_FILLER);
|
||||
|
||||
/* FIXME Missing error code checks from the stats, not log_warn?, notify if setting overridden, delay message/check till it is actually used (eg consider if lvm shell - file could appear later after this check)? */
|
||||
if (!strcmp(cmd->stripe_filler, "/dev/ioerror") &&
|
||||
stat(cmd->stripe_filler, &st))
|
||||
cmd->stripe_filler = "error";
|
||||
|
||||
if (strcmp(cmd->stripe_filler, "error")) {
|
||||
if (stat(cmd->stripe_filler, &st)) {
|
||||
log_warn("WARNING: activation/missing_stripe_filler = \"%s\" "
|
||||
"is invalid,", cmd->stripe_filler);
|
||||
log_warn(" stat failed: %s", strerror(errno));
|
||||
log_warn("Falling back to \"error\" missing_stripe_filler.");
|
||||
cmd->stripe_filler = "error";
|
||||
} else if (!S_ISBLK(st.st_mode)) {
|
||||
log_warn("WARNING: activation/missing_stripe_filler = \"%s\" "
|
||||
"is not a block device.", cmd->stripe_filler);
|
||||
log_warn("Falling back to \"error\" missing_stripe_filler.");
|
||||
cmd->stripe_filler = "error";
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -282,10 +352,8 @@ static int _init_tags(struct cmd_context *cmd, struct config_tree *cft)
|
||||
if (!cmd->hosttags && find_config_int(cft->root, "tags/hosttags",
|
||||
DEFAULT_HOSTTAGS)) {
|
||||
/* FIXME Strip out invalid chars: only A-Za-z0-9_+.- */
|
||||
if (!_set_tag(cmd, cmd->hostname)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!_set_tag(cmd, cmd->hostname))
|
||||
return_0;
|
||||
cmd->hosttags = 1;
|
||||
}
|
||||
|
||||
@@ -301,17 +369,13 @@ static int _init_tags(struct cmd_context *cmd, struct config_tree *cft)
|
||||
}
|
||||
if (cn->child) {
|
||||
passes = 0;
|
||||
if (!_check_host_filters(cmd, cn->child, &passes)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!_check_host_filters(cmd, cn->child, &passes))
|
||||
return_0;
|
||||
if (!passes)
|
||||
continue;
|
||||
}
|
||||
if (!_set_tag(cmd, tag)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!_set_tag(cmd, tag))
|
||||
return_0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
@@ -346,7 +410,7 @@ static int _load_config_file(struct cmd_context *cmd, const char *tag)
|
||||
/* Is there a config file? */
|
||||
if (stat(config_file, &info) == -1) {
|
||||
if (errno == ENOENT) {
|
||||
list_add(&cmd->config_files, &cfl->list);
|
||||
dm_list_add(&cmd->config_files, &cfl->list);
|
||||
goto out;
|
||||
}
|
||||
log_sys_error("stat", config_file);
|
||||
@@ -361,7 +425,7 @@ static int _load_config_file(struct cmd_context *cmd, const char *tag)
|
||||
return 0;
|
||||
}
|
||||
|
||||
list_add(&cmd->config_files, &cfl->list);
|
||||
dm_list_add(&cmd->config_files, &cfl->list);
|
||||
|
||||
out:
|
||||
if (*tag)
|
||||
@@ -385,10 +449,8 @@ static int _init_lvm_conf(struct cmd_context *cmd)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!_load_config_file(cmd, "")) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!_load_config_file(cmd, ""))
|
||||
return_0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -399,12 +461,9 @@ static int _init_tag_configs(struct cmd_context *cmd)
|
||||
struct str_list *sl;
|
||||
|
||||
/* Tag list may grow while inside this loop */
|
||||
list_iterate_items(sl, &cmd->tags) {
|
||||
if (!_load_config_file(cmd, sl->str)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
dm_list_iterate_items(sl, &cmd->tags) {
|
||||
if (!_load_config_file(cmd, sl->str))
|
||||
return_0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
@@ -422,12 +481,10 @@ static int _merge_config_files(struct cmd_context *cmd)
|
||||
}
|
||||
}
|
||||
|
||||
list_iterate_items(cfl, &cmd->config_files) {
|
||||
dm_list_iterate_items(cfl, &cmd->config_files) {
|
||||
/* Merge all config trees into cmd->cft using merge/tag rules */
|
||||
if (!merge_config_tree(cmd, cmd->cft, cfl->cft)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!merge_config_tree(cmd, cmd->cft, cfl->cft))
|
||||
return_0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
@@ -435,10 +492,10 @@ static int _merge_config_files(struct cmd_context *cmd)
|
||||
|
||||
static void _destroy_tags(struct cmd_context *cmd)
|
||||
{
|
||||
struct list *slh, *slht;
|
||||
struct dm_list *slh, *slht;
|
||||
|
||||
list_iterate_safe(slh, slht, &cmd->tags) {
|
||||
list_del(slh);
|
||||
dm_list_iterate_safe(slh, slht, &cmd->tags) {
|
||||
dm_list_del(slh);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -446,7 +503,7 @@ int config_files_changed(struct cmd_context *cmd)
|
||||
{
|
||||
struct config_tree_list *cfl;
|
||||
|
||||
list_iterate_items(cfl, &cmd->config_files) {
|
||||
dm_list_iterate_items(cfl, &cmd->config_files) {
|
||||
if (config_file_changed(cfl->cft))
|
||||
return 1;
|
||||
}
|
||||
@@ -463,11 +520,11 @@ static void _destroy_tag_configs(struct cmd_context *cmd)
|
||||
cmd->cft = NULL;
|
||||
}
|
||||
|
||||
list_iterate_items(cfl, &cmd->config_files) {
|
||||
dm_list_iterate_items(cfl, &cmd->config_files) {
|
||||
destroy_config_tree(cfl->cft);
|
||||
}
|
||||
|
||||
list_init(&cmd->config_files);
|
||||
dm_list_init(&cmd->config_files);
|
||||
}
|
||||
|
||||
static int _init_dev_cache(struct cmd_context *cmd)
|
||||
@@ -542,12 +599,12 @@ static struct dev_filter *_init_filter_components(struct cmd_context *cmd)
|
||||
|
||||
/*
|
||||
* sysfs filter. Only available on 2.6 kernels. Non-critical.
|
||||
* Listed first because it's very efficient at eliminating
|
||||
* Listed first because it's very efficient at eliminating
|
||||
* unavailable devices.
|
||||
*/
|
||||
if (find_config_tree_bool(cmd, "devices/sysfs_scan",
|
||||
DEFAULT_SYSFS_SCAN)) {
|
||||
if ((filters[nr_filt] = sysfs_filter_create(cmd->proc_dir)))
|
||||
if ((filters[nr_filt] = sysfs_filter_create(cmd->sysfs_dir)))
|
||||
nr_filt++;
|
||||
}
|
||||
|
||||
@@ -668,14 +725,14 @@ static int _init_formats(struct cmd_context *cmd)
|
||||
if (!(fmt = init_lvm1_format(cmd)))
|
||||
return 0;
|
||||
fmt->library = NULL;
|
||||
list_add(&cmd->formats, &fmt->list);
|
||||
dm_list_add(&cmd->formats, &fmt->list);
|
||||
#endif
|
||||
|
||||
#ifdef POOL_INTERNAL
|
||||
if (!(fmt = init_pool_format(cmd)))
|
||||
return 0;
|
||||
fmt->library = NULL;
|
||||
list_add(&cmd->formats, &fmt->list);
|
||||
dm_list_add(&cmd->formats, &fmt->list);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBDL
|
||||
@@ -694,10 +751,8 @@ static int _init_formats(struct cmd_context *cmd)
|
||||
return 0;
|
||||
}
|
||||
if (!(lib = load_shared_library(cmd, cv->v.str,
|
||||
"format", 0))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
"format", 0)))
|
||||
return_0;
|
||||
|
||||
if (!(init_format_fn = dlsym(lib, "init_format"))) {
|
||||
log_error("Shared library %s does not contain "
|
||||
@@ -709,7 +764,7 @@ static int _init_formats(struct cmd_context *cmd)
|
||||
if (!(fmt = init_format_fn(cmd)))
|
||||
return 0;
|
||||
fmt->library = lib;
|
||||
list_add(&cmd->formats, &fmt->list);
|
||||
dm_list_add(&cmd->formats, &fmt->list);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -717,14 +772,14 @@ static int _init_formats(struct cmd_context *cmd)
|
||||
if (!(fmt = create_text_format(cmd)))
|
||||
return 0;
|
||||
fmt->library = NULL;
|
||||
list_add(&cmd->formats, &fmt->list);
|
||||
dm_list_add(&cmd->formats, &fmt->list);
|
||||
|
||||
cmd->fmt_backup = fmt;
|
||||
|
||||
format = find_config_tree_str(cmd, "global/format",
|
||||
DEFAULT_FORMAT);
|
||||
|
||||
list_iterate_items(fmt, &cmd->formats) {
|
||||
dm_list_iterate_items(fmt, &cmd->formats) {
|
||||
if (!strcasecmp(fmt->name, format) ||
|
||||
(fmt->alias && !strcasecmp(fmt->alias, format))) {
|
||||
cmd->default_settings.fmt = fmt;
|
||||
@@ -736,6 +791,17 @@ static int _init_formats(struct cmd_context *cmd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int init_lvmcache_orphans(struct cmd_context *cmd)
|
||||
{
|
||||
struct format_type *fmt;
|
||||
|
||||
dm_list_iterate_items(fmt, &cmd->formats)
|
||||
if (!lvmcache_add_orphan_vginfo(fmt->orphan_vg_name, fmt))
|
||||
return_0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _init_segtypes(struct cmd_context *cmd)
|
||||
{
|
||||
struct segment_type *segtype;
|
||||
@@ -747,30 +813,35 @@ static int _init_segtypes(struct cmd_context *cmd)
|
||||
if (!(segtype = init_striped_segtype(cmd)))
|
||||
return 0;
|
||||
segtype->library = NULL;
|
||||
list_add(&cmd->segtypes, &segtype->list);
|
||||
dm_list_add(&cmd->segtypes, &segtype->list);
|
||||
|
||||
if (!(segtype = init_zero_segtype(cmd)))
|
||||
return 0;
|
||||
segtype->library = NULL;
|
||||
list_add(&cmd->segtypes, &segtype->list);
|
||||
dm_list_add(&cmd->segtypes, &segtype->list);
|
||||
|
||||
if (!(segtype = init_error_segtype(cmd)))
|
||||
return 0;
|
||||
segtype->library = NULL;
|
||||
list_add(&cmd->segtypes, &segtype->list);
|
||||
dm_list_add(&cmd->segtypes, &segtype->list);
|
||||
|
||||
if (!(segtype = init_free_segtype(cmd)))
|
||||
return 0;
|
||||
segtype->library = NULL;
|
||||
dm_list_add(&cmd->segtypes, &segtype->list);
|
||||
|
||||
#ifdef SNAPSHOT_INTERNAL
|
||||
if (!(segtype = init_snapshot_segtype(cmd)))
|
||||
return 0;
|
||||
segtype->library = NULL;
|
||||
list_add(&cmd->segtypes, &segtype->list);
|
||||
dm_list_add(&cmd->segtypes, &segtype->list);
|
||||
#endif
|
||||
|
||||
#ifdef MIRRORED_INTERNAL
|
||||
if (!(segtype = init_mirrored_segtype(cmd)))
|
||||
return 0;
|
||||
segtype->library = NULL;
|
||||
list_add(&cmd->segtypes, &segtype->list);
|
||||
dm_list_add(&cmd->segtypes, &segtype->list);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBDL
|
||||
@@ -790,10 +861,8 @@ static int _init_segtypes(struct cmd_context *cmd)
|
||||
return 0;
|
||||
}
|
||||
if (!(lib = load_shared_library(cmd, cv->v.str,
|
||||
"segment type", 0))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
"segment type", 0)))
|
||||
return_0;
|
||||
|
||||
if (!(init_segtype_fn = dlsym(lib, "init_segtype"))) {
|
||||
log_error("Shared library %s does not contain "
|
||||
@@ -805,16 +874,16 @@ static int _init_segtypes(struct cmd_context *cmd)
|
||||
if (!(segtype = init_segtype_fn(cmd)))
|
||||
return 0;
|
||||
segtype->library = lib;
|
||||
list_add(&cmd->segtypes, &segtype->list);
|
||||
dm_list_add(&cmd->segtypes, &segtype->list);
|
||||
|
||||
list_iterate_items(segtype2, &cmd->segtypes) {
|
||||
dm_list_iterate_items(segtype2, &cmd->segtypes) {
|
||||
if ((segtype == segtype2) ||
|
||||
strcmp(segtype2->name, segtype->name))
|
||||
continue;
|
||||
log_error("Duplicate segment type %s: "
|
||||
"unloading shared library %s",
|
||||
segtype->name, cv->v.str);
|
||||
list_del(&segtype->list);
|
||||
dm_list_del(&segtype->list);
|
||||
segtype->ops->destroy(segtype);
|
||||
dlclose(lib);
|
||||
}
|
||||
@@ -937,11 +1006,12 @@ struct cmd_context *create_toolcontext(struct arg *the_args, unsigned is_static,
|
||||
cmd->args = the_args;
|
||||
cmd->is_static = is_static;
|
||||
cmd->is_long_lived = is_long_lived;
|
||||
cmd->handles_missing_pvs = 0;
|
||||
cmd->hosttags = 0;
|
||||
list_init(&cmd->formats);
|
||||
list_init(&cmd->segtypes);
|
||||
list_init(&cmd->tags);
|
||||
list_init(&cmd->config_files);
|
||||
dm_list_init(&cmd->formats);
|
||||
dm_list_init(&cmd->segtypes);
|
||||
dm_list_init(&cmd->tags);
|
||||
dm_list_init(&cmd->config_files);
|
||||
|
||||
strcpy(cmd->sys_dir, DEFAULT_SYS_DIR);
|
||||
|
||||
@@ -998,12 +1068,16 @@ struct cmd_context *create_toolcontext(struct arg *the_args, unsigned is_static,
|
||||
if (!_init_formats(cmd))
|
||||
goto error;
|
||||
|
||||
if (!init_lvmcache_orphans(cmd))
|
||||
goto error;
|
||||
|
||||
if (!_init_segtypes(cmd))
|
||||
goto error;
|
||||
|
||||
if (!_init_backup(cmd))
|
||||
goto error;
|
||||
|
||||
cmd->default_settings.cache_vgmetadata = 1;
|
||||
cmd->current_settings = cmd->default_settings;
|
||||
|
||||
cmd->config_valid = 1;
|
||||
@@ -1014,15 +1088,15 @@ struct cmd_context *create_toolcontext(struct arg *the_args, unsigned is_static,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void _destroy_formats(struct list *formats)
|
||||
static void _destroy_formats(struct dm_list *formats)
|
||||
{
|
||||
struct list *fmtl, *tmp;
|
||||
struct dm_list *fmtl, *tmp;
|
||||
struct format_type *fmt;
|
||||
void *lib;
|
||||
|
||||
list_iterate_safe(fmtl, tmp, formats) {
|
||||
fmt = list_item(fmtl, struct format_type);
|
||||
list_del(&fmt->list);
|
||||
dm_list_iterate_safe(fmtl, tmp, formats) {
|
||||
fmt = dm_list_item(fmtl, struct format_type);
|
||||
dm_list_del(&fmt->list);
|
||||
lib = fmt->library;
|
||||
fmt->ops->destroy(fmt);
|
||||
#ifdef HAVE_LIBDL
|
||||
@@ -1032,15 +1106,15 @@ static void _destroy_formats(struct list *formats)
|
||||
}
|
||||
}
|
||||
|
||||
static void _destroy_segtypes(struct list *segtypes)
|
||||
static void _destroy_segtypes(struct dm_list *segtypes)
|
||||
{
|
||||
struct list *sgtl, *tmp;
|
||||
struct dm_list *sgtl, *tmp;
|
||||
struct segment_type *segtype;
|
||||
void *lib;
|
||||
|
||||
list_iterate_safe(sgtl, tmp, segtypes) {
|
||||
segtype = list_item(sgtl, struct segment_type);
|
||||
list_del(&segtype->list);
|
||||
dm_list_iterate_safe(sgtl, tmp, segtypes) {
|
||||
segtype = dm_list_item(sgtl, struct segment_type);
|
||||
dm_list_del(&segtype->list);
|
||||
lib = segtype->library;
|
||||
segtype->ops->destroy(segtype);
|
||||
#ifdef HAVE_LIBDL
|
||||
@@ -1060,7 +1134,7 @@ int refresh_toolcontext(struct cmd_context *cmd)
|
||||
*/
|
||||
|
||||
activation_release();
|
||||
lvmcache_destroy();
|
||||
lvmcache_destroy(cmd, 0);
|
||||
label_exit();
|
||||
_destroy_segtypes(&cmd->segtypes);
|
||||
_destroy_formats(&cmd->formats);
|
||||
@@ -1102,6 +1176,9 @@ int refresh_toolcontext(struct cmd_context *cmd)
|
||||
if (!_init_formats(cmd))
|
||||
return 0;
|
||||
|
||||
if (!init_lvmcache_orphans(cmd))
|
||||
return 0;
|
||||
|
||||
if (!_init_segtypes(cmd))
|
||||
return 0;
|
||||
|
||||
@@ -1123,7 +1200,7 @@ void destroy_toolcontext(struct cmd_context *cmd)
|
||||
|
||||
archive_exit(cmd);
|
||||
backup_exit(cmd);
|
||||
lvmcache_destroy();
|
||||
lvmcache_destroy(cmd, 0);
|
||||
label_exit();
|
||||
_destroy_segtypes(&cmd->segtypes);
|
||||
_destroy_formats(&cmd->formats);
|
||||
|
||||
@@ -34,6 +34,7 @@ struct config_info {
|
||||
int archive; /* should we archive ? */
|
||||
int backup; /* should we backup ? */
|
||||
int read_ahead; /* DM_READ_AHEAD_NONE or _AUTO */
|
||||
int cache_vgmetadata;
|
||||
const char *msg_prefix;
|
||||
struct format_type *fmt;
|
||||
uint64_t unit_factor;
|
||||
@@ -56,8 +57,8 @@ struct cmd_context {
|
||||
const struct format_type *fmt; /* Current format to use by default */
|
||||
struct format_type *fmt_backup; /* Format to use for backups */
|
||||
|
||||
struct list formats; /* Available formats */
|
||||
struct list segtypes; /* Available segment types */
|
||||
struct dm_list formats; /* Available formats */
|
||||
struct dm_list segtypes; /* Available segment types */
|
||||
const char *hostname;
|
||||
const char *kernel_vsn;
|
||||
|
||||
@@ -65,13 +66,15 @@ struct cmd_context {
|
||||
struct command *command;
|
||||
struct arg *args;
|
||||
char **argv;
|
||||
unsigned is_static; /* Static binary? */
|
||||
unsigned is_long_lived; /* Optimises persistent_filter handling */
|
||||
unsigned is_static:1; /* Static binary? */
|
||||
unsigned is_long_lived:1; /* Optimises persistent_filter handling */
|
||||
unsigned handles_missing_pvs:1;
|
||||
unsigned partial_activation:1;
|
||||
|
||||
struct dev_filter *filter;
|
||||
int dump_filter; /* Dump filter when exiting? */
|
||||
|
||||
struct list config_files;
|
||||
struct dm_list config_files;
|
||||
int config_valid;
|
||||
struct config_tree *cft;
|
||||
struct config_tree *cft_override;
|
||||
@@ -80,19 +83,22 @@ struct cmd_context {
|
||||
|
||||
struct archive_params *archive_params;
|
||||
struct backup_params *backup_params;
|
||||
const char *stripe_filler;
|
||||
|
||||
/* List of defined tags */
|
||||
struct list tags;
|
||||
struct dm_list tags;
|
||||
int hosttags;
|
||||
|
||||
char sys_dir[PATH_MAX];
|
||||
char dev_dir[PATH_MAX];
|
||||
char proc_dir[PATH_MAX];
|
||||
char sysfs_dir[PATH_MAX];
|
||||
};
|
||||
|
||||
struct cmd_context *create_toolcontext(struct arg *the_args, unsigned is_static, unsigned is_long_lived);
|
||||
void destroy_toolcontext(struct cmd_context *cmd);
|
||||
int refresh_toolcontext(struct cmd_context *cmd);
|
||||
int config_files_changed(struct cmd_context *cmd);
|
||||
int init_lvmcache_orphans(struct cmd_context *cmd);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -34,7 +34,8 @@
|
||||
enum {
|
||||
TOK_INT,
|
||||
TOK_FLOAT,
|
||||
TOK_STRING,
|
||||
TOK_STRING, /* Single quotes */
|
||||
TOK_STRING_ESCAPED, /* Double quotes */
|
||||
TOK_EQ,
|
||||
TOK_SECTION_B,
|
||||
TOK_SECTION_E,
|
||||
@@ -196,10 +197,8 @@ int read_config_fd(struct config_tree *cft, struct device *dev,
|
||||
off_t mmap_offset = 0;
|
||||
char *buf = NULL;
|
||||
|
||||
if (!(p = dm_pool_alloc(c->mem, sizeof(*p)))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(p = dm_pool_alloc(c->mem, sizeof(*p))))
|
||||
return_0;
|
||||
p->mem = c->mem;
|
||||
|
||||
/* Only use mmap with regular files */
|
||||
@@ -217,10 +216,8 @@ int read_config_fd(struct config_tree *cft, struct device *dev,
|
||||
}
|
||||
p->fb = p->fb + mmap_offset;
|
||||
} else {
|
||||
if (!(buf = dm_malloc(size + size2))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(buf = dm_malloc(size + size2)))
|
||||
return_0;
|
||||
if (!dev_read_circular(dev, (uint64_t) offset, size,
|
||||
(uint64_t) offset2, size2, buf)) {
|
||||
goto out;
|
||||
@@ -237,10 +234,8 @@ int read_config_fd(struct config_tree *cft, struct device *dev,
|
||||
|
||||
p->fe = p->fb + size + size2;
|
||||
|
||||
if (!_parse_config_file(p, cft)) {
|
||||
stack;
|
||||
goto out;
|
||||
}
|
||||
if (!_parse_config_file(p, cft))
|
||||
goto_out;
|
||||
|
||||
r = 1;
|
||||
|
||||
@@ -378,7 +373,7 @@ static int _line_append(struct output_line *outline, const char *fmt, ...)
|
||||
va_end(ap);
|
||||
|
||||
if (!dm_pool_grow_object(outline->mem, &buf[0], strlen(buf))) {
|
||||
log_error("dm_pool_grew_object failed for config line");
|
||||
log_error("dm_pool_grow_object failed for config line");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -407,9 +402,16 @@ static int _line_end(struct output_line *outline)
|
||||
|
||||
static int _write_value(struct output_line *outline, struct config_value *v)
|
||||
{
|
||||
char *buf;
|
||||
|
||||
switch (v->type) {
|
||||
case CFG_STRING:
|
||||
line_append("\"%s\"", v->v.str);
|
||||
if (!(buf = alloca(escaped_len(v->v.str)))) {
|
||||
log_error("temporary stack allocation for a config "
|
||||
"string failed");
|
||||
return 0;
|
||||
}
|
||||
line_append("\"%s\"", escape_double_quotes(buf, v->v.str));
|
||||
break;
|
||||
|
||||
case CFG_FLOAT:
|
||||
@@ -537,10 +539,8 @@ static struct config_node *_file(struct parser *p)
|
||||
{
|
||||
struct config_node *root = NULL, *n, *l = NULL;
|
||||
while (p->t != TOK_EOF) {
|
||||
if (!(n = _section(p))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(n = _section(p)))
|
||||
return_0;
|
||||
|
||||
if (!root)
|
||||
root = n;
|
||||
@@ -555,25 +555,19 @@ static struct config_node *_section(struct parser *p)
|
||||
{
|
||||
/* IDENTIFIER SECTION_B_CHAR VALUE* SECTION_E_CHAR */
|
||||
struct config_node *root, *n, *l = NULL;
|
||||
if (!(root = _create_node(p))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(root = _create_node(p)))
|
||||
return_0;
|
||||
|
||||
if (!(root->key = _dup_tok(p))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(root->key = _dup_tok(p)))
|
||||
return_0;
|
||||
|
||||
match(TOK_IDENTIFIER);
|
||||
|
||||
if (p->t == TOK_SECTION_B) {
|
||||
match(TOK_SECTION_B);
|
||||
while (p->t != TOK_SECTION_E) {
|
||||
if (!(n = _section(p))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(n = _section(p)))
|
||||
return_0;
|
||||
|
||||
if (!root->child)
|
||||
root->child = n;
|
||||
@@ -584,10 +578,8 @@ static struct config_node *_section(struct parser *p)
|
||||
match(TOK_SECTION_E);
|
||||
} else {
|
||||
match(TOK_EQ);
|
||||
if (!(root->v = _value(p))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(root->v = _value(p)))
|
||||
return_0;
|
||||
}
|
||||
|
||||
return root;
|
||||
@@ -600,10 +592,8 @@ static struct config_value *_value(struct parser *p)
|
||||
if (p->t == TOK_ARRAY_B) {
|
||||
match(TOK_ARRAY_B);
|
||||
while (p->t != TOK_ARRAY_E) {
|
||||
if (!(l = _type(p))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(l = _type(p)))
|
||||
return_0;
|
||||
|
||||
if (!h)
|
||||
h = l;
|
||||
@@ -656,14 +646,23 @@ static struct config_value *_type(struct parser *p)
|
||||
v->type = CFG_STRING;
|
||||
|
||||
p->tb++, p->te--; /* strip "'s */
|
||||
if (!(v->v.str = _dup_tok(p))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(v->v.str = _dup_tok(p)))
|
||||
return_0;
|
||||
p->te++;
|
||||
match(TOK_STRING);
|
||||
break;
|
||||
|
||||
case TOK_STRING_ESCAPED:
|
||||
v->type = CFG_STRING;
|
||||
|
||||
p->tb++, p->te--; /* strip "'s */
|
||||
if (!(v->v.str = _dup_tok(p)))
|
||||
return_0;
|
||||
unescape_double_quotes(v->v.str);
|
||||
p->te++;
|
||||
match(TOK_STRING_ESCAPED);
|
||||
break;
|
||||
|
||||
default:
|
||||
log_error("Parse error at byte %" PRIptrdiff_t " (line %d): expected a value",
|
||||
p->tb - p->fb + 1, p->line);
|
||||
@@ -734,7 +733,7 @@ static void _get_token(struct parser *p, int tok_prev)
|
||||
break;
|
||||
|
||||
case '"':
|
||||
p->t = TOK_STRING;
|
||||
p->t = TOK_STRING_ESCAPED;
|
||||
p->te++;
|
||||
while ((p->te != p->fe) && (*p->te) && (*p->te != '"')) {
|
||||
if ((*p->te == '\\') && (p->te + 1 != p->fe) &&
|
||||
@@ -799,11 +798,9 @@ static void _get_token(struct parser *p, int tok_prev)
|
||||
static void _eat_space(struct parser *p)
|
||||
{
|
||||
while ((p->tb != p->fe) && (*p->tb)) {
|
||||
if (*p->te == '#') {
|
||||
if (*p->te == '#')
|
||||
while ((p->te != p->fe) && (*p->te) && (*p->te != '\n'))
|
||||
p->te++;
|
||||
p->line++;
|
||||
}
|
||||
|
||||
else if (isspace(*p->te)) {
|
||||
while ((p->te != p->fe) && (*p->te) && isspace(*p->te)) {
|
||||
@@ -847,10 +844,8 @@ static char *_dup_tok(struct parser *p)
|
||||
{
|
||||
size_t len = p->te - p->tb;
|
||||
char *str = dm_pool_alloc(p->mem, len + 1);
|
||||
if (!str) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!str)
|
||||
return_0;
|
||||
strncpy(str, p->tb, len);
|
||||
str[len] = '\0';
|
||||
return str;
|
||||
@@ -1016,7 +1011,7 @@ float find_config_tree_float(struct cmd_context *cmd, const char *path,
|
||||
return _find_config_float(cmd->cft_override ? cmd->cft_override->root : NULL, cmd->cft->root, path, fail);
|
||||
}
|
||||
|
||||
static int _str_in_array(const char *str, const char *values[])
|
||||
static int _str_in_array(const char *str, const char * const values[])
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -1029,9 +1024,8 @@ static int _str_in_array(const char *str, const char *values[])
|
||||
|
||||
static int _str_to_bool(const char *str, int fail)
|
||||
{
|
||||
static const char *_true_values[] = { "y", "yes", "on", "true", NULL };
|
||||
static const char *_false_values[] =
|
||||
{ "n", "no", "off", "false", NULL };
|
||||
const char * const _true_values[] = { "y", "yes", "on", "true", NULL };
|
||||
const char * const _false_values[] = { "n", "no", "off", "false", NULL };
|
||||
|
||||
if (_str_in_array(str, _true_values))
|
||||
return 1;
|
||||
@@ -1171,7 +1165,7 @@ static void _merge_section(struct config_node *cn1, struct config_node *cn2)
|
||||
}
|
||||
}
|
||||
|
||||
static int _match_host_tags(struct list *tags, struct config_node *tn)
|
||||
static int _match_host_tags(struct dm_list *tags, struct config_node *tn)
|
||||
{
|
||||
struct config_value *tv;
|
||||
const char *str;
|
||||
@@ -1254,7 +1248,7 @@ static unsigned _count_tokens(const char *str, unsigned len, int type)
|
||||
|
||||
c = _token_type_to_char(type);
|
||||
|
||||
return count_chars_len(str, len, c);
|
||||
return count_chars(str, len, c);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1281,7 +1275,7 @@ unsigned maybe_config_section(const char *str, unsigned len)
|
||||
begin_count = _count_tokens(str, len, TOK_SECTION_B);
|
||||
end_count = _count_tokens(str, len, TOK_SECTION_E);
|
||||
|
||||
if (begin_count && end_count && (begin_count - end_count == 0))
|
||||
if (begin_count && end_count && (begin_count == end_count))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
|
||||
@@ -49,7 +49,7 @@ struct config_tree {
|
||||
};
|
||||
|
||||
struct config_tree_list {
|
||||
struct list list;
|
||||
struct dm_list list;
|
||||
struct config_tree *cft;
|
||||
};
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#define DEFAULT_PROC_DIR "/proc"
|
||||
#define DEFAULT_SYSFS_SCAN 1
|
||||
#define DEFAULT_MD_COMPONENT_DETECTION 1
|
||||
#define DEFAULT_MD_CHUNK_ALIGNMENT 1
|
||||
#define DEFAULT_IGNORE_SUSPENDED_DEVICES 1
|
||||
|
||||
#define DEFAULT_LOCK_DIR "/var/lock/lvm"
|
||||
@@ -64,6 +65,7 @@
|
||||
#define DEFAULT_PVMETADATACOPIES 1
|
||||
#define DEFAULT_LABELSECTOR UINT64_C(1)
|
||||
#define DEFAULT_READ_AHEAD "auto"
|
||||
#define DEFAULT_EXTENT_SIZE 4096 /* In KB */
|
||||
|
||||
#define DEFAULT_MSG_PREFIX " "
|
||||
#define DEFAULT_CMD_NAME 0
|
||||
@@ -90,7 +92,7 @@
|
||||
# define DEFAULT_ACTIVATION 0
|
||||
#endif
|
||||
|
||||
#define DEFAULT_STRIPE_FILLER "/dev/ioerror"
|
||||
#define DEFAULT_STRIPE_FILLER "error"
|
||||
#define DEFAULT_MIRROR_REGION_SIZE 512 /* KB */
|
||||
#define DEFAULT_INTERVAL 15
|
||||
|
||||
@@ -100,20 +102,23 @@
|
||||
|
||||
#define DEFAULT_REP_ALIGNED 1
|
||||
#define DEFAULT_REP_BUFFERED 1
|
||||
#define DEFAULT_REP_COLUMNS_AS_ROWS 0
|
||||
#define DEFAULT_REP_HEADINGS 1
|
||||
#define DEFAULT_REP_PREFIXES 0
|
||||
#define DEFAULT_REP_QUOTED 1
|
||||
#define DEFAULT_REP_SEPARATOR " "
|
||||
|
||||
#define DEFAULT_LVS_COLS "lv_name,vg_name,lv_attr,lv_size,origin,snap_percent,move_pv,mirror_log,copy_percent"
|
||||
#define DEFAULT_LVS_COLS "lv_name,vg_name,lv_attr,lv_size,origin,snap_percent,move_pv,mirror_log,copy_percent,convert_lv"
|
||||
#define DEFAULT_VGS_COLS "vg_name,pv_count,lv_count,snap_count,vg_attr,vg_size,vg_free"
|
||||
#define DEFAULT_PVS_COLS "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free"
|
||||
#define DEFAULT_SEGS_COLS "lv_name,vg_name,lv_attr,stripes,segtype,seg_size"
|
||||
#define DEFAULT_PVSEGS_COLS "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,pvseg_start,pvseg_size"
|
||||
|
||||
#define DEFAULT_LVS_COLS_VERB "lv_name,vg_name,seg_count,lv_attr,lv_size,lv_major,lv_minor,lv_kernel_major,lv_kernel_minor,origin,snap_percent,move_pv,copy_percent,mirror_log,lv_uuid"
|
||||
#define DEFAULT_LVS_COLS_VERB "lv_name,vg_name,seg_count,lv_attr,lv_size,lv_major,lv_minor,lv_kernel_major,lv_kernel_minor,origin,snap_percent,move_pv,copy_percent,mirror_log,convert_lv,lv_uuid"
|
||||
#define DEFAULT_VGS_COLS_VERB "vg_name,vg_attr,vg_extent_size,pv_count,lv_count,snap_count,vg_size,vg_free,vg_uuid"
|
||||
#define DEFAULT_PVS_COLS_VERB "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,dev_size,pv_uuid"
|
||||
#define DEFAULT_SEGS_COLS_VERB "lv_name,vg_name,lv_attr,seg_start,seg_size,stripes,segtype,stripesize,chunksize"
|
||||
#define DEFAULT_PVSEGS_COLS_VERB "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,pvseg_start,pvseg_size"
|
||||
#define DEFAULT_PVSEGS_COLS_VERB "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"
|
||||
|
||||
#define DEFAULT_LVS_SORT "vg_name,lv_name"
|
||||
#define DEFAULT_VGS_SORT "vg_name"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
@@ -87,10 +87,8 @@ int btree_insert(struct btree *t, uint32_t k, void *data)
|
||||
struct node *p, **c = _lookup(&t->root, key, &p), *n;
|
||||
|
||||
if (!*c) {
|
||||
if (!(n = dm_pool_alloc(t->mem, sizeof(*n)))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(n = dm_pool_alloc(t->mem, sizeof(*n))))
|
||||
return_0;
|
||||
|
||||
n->key = key;
|
||||
n->data = data;
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* Initialise a list before use.
|
||||
* The list head's next and previous pointers point back to itself.
|
||||
*/
|
||||
void list_init(struct list *head)
|
||||
void dm_list_init(struct dm_list *head)
|
||||
{
|
||||
head->n = head->p = head;
|
||||
}
|
||||
@@ -28,7 +28,7 @@ void list_init(struct list *head)
|
||||
* Insert an element before 'head'.
|
||||
* If 'head' is the list head, this adds an element to the end of the list.
|
||||
*/
|
||||
void list_add(struct list *head, struct list *elem)
|
||||
void dm_list_add(struct dm_list *head, struct dm_list *elem)
|
||||
{
|
||||
assert(head->n);
|
||||
|
||||
@@ -43,7 +43,7 @@ void list_add(struct list *head, struct list *elem)
|
||||
* Insert an element after 'head'.
|
||||
* If 'head' is the list head, this adds an element to the front of the list.
|
||||
*/
|
||||
void list_add_h(struct list *head, struct list *elem)
|
||||
void dm_list_add_h(struct dm_list *head, struct dm_list *elem)
|
||||
{
|
||||
assert(head->n);
|
||||
|
||||
@@ -59,16 +59,25 @@ void list_add_h(struct list *head, struct list *elem)
|
||||
* Note that this doesn't change the element itself - it may still be safe
|
||||
* to follow its pointers.
|
||||
*/
|
||||
void list_del(struct list *elem)
|
||||
void dm_list_del(struct dm_list *elem)
|
||||
{
|
||||
elem->n->p = elem->p;
|
||||
elem->p->n = elem->n;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove an element from existing list and insert before 'head'.
|
||||
*/
|
||||
void dm_list_move(struct dm_list *head, struct dm_list *elem)
|
||||
{
|
||||
dm_list_del(elem);
|
||||
dm_list_add(head, elem);
|
||||
}
|
||||
|
||||
/*
|
||||
* Is the list empty?
|
||||
*/
|
||||
int list_empty(const struct list *head)
|
||||
int dm_list_empty(const struct dm_list *head)
|
||||
{
|
||||
return head->n == head;
|
||||
}
|
||||
@@ -76,7 +85,7 @@ int list_empty(const struct list *head)
|
||||
/*
|
||||
* Is this the first element of the list?
|
||||
*/
|
||||
int list_start(const struct list *head, const struct list *elem)
|
||||
int dm_list_start(const struct dm_list *head, const struct dm_list *elem)
|
||||
{
|
||||
return elem->p == head;
|
||||
}
|
||||
@@ -84,7 +93,7 @@ int list_start(const struct list *head, const struct list *elem)
|
||||
/*
|
||||
* Is this the last element of the list?
|
||||
*/
|
||||
int list_end(const struct list *head, const struct list *elem)
|
||||
int dm_list_end(const struct dm_list *head, const struct dm_list *elem)
|
||||
{
|
||||
return elem->n == head;
|
||||
}
|
||||
@@ -92,44 +101,44 @@ int list_end(const struct list *head, const struct list *elem)
|
||||
/*
|
||||
* Return first element of the list or NULL if empty
|
||||
*/
|
||||
struct list *list_first(const struct list *head)
|
||||
struct dm_list *dm_list_first(const struct dm_list *head)
|
||||
{
|
||||
return (list_empty(head) ? NULL : head->n);
|
||||
return (dm_list_empty(head) ? NULL : head->n);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return last element of the list or NULL if empty
|
||||
*/
|
||||
struct list *list_last(const struct list *head)
|
||||
struct dm_list *dm_list_last(const struct dm_list *head)
|
||||
{
|
||||
return (list_empty(head) ? NULL : head->p);
|
||||
return (dm_list_empty(head) ? NULL : head->p);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the previous element of the list, or NULL if we've reached the start.
|
||||
*/
|
||||
struct list *list_prev(const struct list *head, const struct list *elem)
|
||||
struct dm_list *dm_list_prev(const struct dm_list *head, const struct dm_list *elem)
|
||||
{
|
||||
return (list_start(head, elem) ? NULL : elem->p);
|
||||
return (dm_list_start(head, elem) ? NULL : elem->p);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the next element of the list, or NULL if we've reached the end.
|
||||
*/
|
||||
struct list *list_next(const struct list *head, const struct list *elem)
|
||||
struct dm_list *dm_list_next(const struct dm_list *head, const struct dm_list *elem)
|
||||
{
|
||||
return (list_end(head, elem) ? NULL : elem->n);
|
||||
return (dm_list_end(head, elem) ? NULL : elem->n);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the number of elements in a list by walking it.
|
||||
*/
|
||||
unsigned int list_size(const struct list *head)
|
||||
unsigned int dm_list_size(const struct dm_list *head)
|
||||
{
|
||||
unsigned int s = 0;
|
||||
const struct list *v;
|
||||
const struct dm_list *v;
|
||||
|
||||
list_iterate(v, head)
|
||||
dm_list_iterate(v, head)
|
||||
s++;
|
||||
|
||||
return s;
|
||||
|
||||
@@ -24,101 +24,106 @@
|
||||
* The list head's pointers point to the first and the last element.
|
||||
*/
|
||||
|
||||
struct list {
|
||||
struct list *n, *p;
|
||||
struct dm_list {
|
||||
struct dm_list *n, *p;
|
||||
};
|
||||
|
||||
/*
|
||||
* Initialise a list before use.
|
||||
* The list head's next and previous pointers point back to itself.
|
||||
*/
|
||||
#define LIST_INIT(name) struct list name = { &(name), &(name) }
|
||||
void list_init(struct list *head);
|
||||
#define DM_LIST_INIT(name) struct dm_list name = { &(name), &(name) }
|
||||
void dm_list_init(struct dm_list *head);
|
||||
|
||||
/*
|
||||
* Insert an element before 'head'.
|
||||
* If 'head' is the list head, this adds an element to the end of the list.
|
||||
*/
|
||||
void list_add(struct list *head, struct list *elem);
|
||||
void dm_list_add(struct dm_list *head, struct dm_list *elem);
|
||||
|
||||
/*
|
||||
* Insert an element after 'head'.
|
||||
* If 'head' is the list head, this adds an element to the front of the list.
|
||||
*/
|
||||
void list_add_h(struct list *head, struct list *elem);
|
||||
void dm_list_add_h(struct dm_list *head, struct dm_list *elem);
|
||||
|
||||
/*
|
||||
* Delete an element from its list.
|
||||
* Note that this doesn't change the element itself - it may still be safe
|
||||
* to follow its pointers.
|
||||
*/
|
||||
void list_del(struct list *elem);
|
||||
void dm_list_del(struct dm_list *elem);
|
||||
|
||||
/*
|
||||
* Remove an element from existing list and insert before 'head'.
|
||||
*/
|
||||
void dm_list_move(struct dm_list *head, struct dm_list *elem);
|
||||
|
||||
/*
|
||||
* Is the list empty?
|
||||
*/
|
||||
int list_empty(const struct list *head);
|
||||
int dm_list_empty(const struct dm_list *head);
|
||||
|
||||
/*
|
||||
* Is this the first element of the list?
|
||||
*/
|
||||
int list_start(const struct list *head, const struct list *elem);
|
||||
int dm_list_start(const struct dm_list *head, const struct dm_list *elem);
|
||||
|
||||
/*
|
||||
* Is this the last element of the list?
|
||||
*/
|
||||
int list_end(const struct list *head, const struct list *elem);
|
||||
int dm_list_end(const struct dm_list *head, const struct dm_list *elem);
|
||||
|
||||
/*
|
||||
* Return first element of the list or NULL if empty
|
||||
*/
|
||||
struct list *list_first(const struct list *head);
|
||||
struct dm_list *dm_list_first(const struct dm_list *head);
|
||||
|
||||
/*
|
||||
* Return last element of the list or NULL if empty
|
||||
*/
|
||||
struct list *list_last(const struct list *head);
|
||||
struct dm_list *dm_list_last(const struct dm_list *head);
|
||||
|
||||
/*
|
||||
* Return the previous element of the list, or NULL if we've reached the start.
|
||||
*/
|
||||
struct list *list_prev(const struct list *head, const struct list *elem);
|
||||
struct dm_list *dm_list_prev(const struct dm_list *head, const struct dm_list *elem);
|
||||
|
||||
/*
|
||||
* Return the next element of the list, or NULL if we've reached the end.
|
||||
*/
|
||||
struct list *list_next(const struct list *head, const struct list *elem);
|
||||
struct dm_list *dm_list_next(const struct dm_list *head, const struct dm_list *elem);
|
||||
|
||||
/*
|
||||
* Given the address v of an instance of 'struct list' called 'head'
|
||||
* Given the address v of an instance of 'struct dm_list' called 'head'
|
||||
* contained in a structure of type t, return the containing structure.
|
||||
*/
|
||||
#define list_struct_base(v, t, head) \
|
||||
#define dm_list_struct_base(v, t, head) \
|
||||
((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->head))
|
||||
|
||||
/*
|
||||
* Given the address v of an instance of 'struct list list' contained in
|
||||
* Given the address v of an instance of 'struct dm_list list' contained in
|
||||
* a structure of type t, return the containing structure.
|
||||
*/
|
||||
#define list_item(v, t) list_struct_base((v), t, list)
|
||||
#define dm_list_item(v, t) dm_list_struct_base((v), t, list)
|
||||
|
||||
/*
|
||||
* Given the address v of one known element e in a known structure of type t,
|
||||
* return another element f.
|
||||
*/
|
||||
#define struct_field(v, t, e, f) \
|
||||
#define dm_struct_field(v, t, e, f) \
|
||||
(((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->e))->f)
|
||||
|
||||
/*
|
||||
* Given the address v of a known element e in a known structure of type t,
|
||||
* return the list head 'list'
|
||||
*/
|
||||
#define list_head(v, t, e) struct_field(v, t, e, list)
|
||||
#define dm_list_head(v, t, e) dm_struct_field(v, t, e, list)
|
||||
|
||||
/*
|
||||
* Set v to each element of a list in turn.
|
||||
*/
|
||||
#define list_iterate(v, head) \
|
||||
#define dm_list_iterate(v, head) \
|
||||
for (v = (head)->n; v != head; v = v->n)
|
||||
|
||||
/*
|
||||
@@ -128,7 +133,7 @@ struct list *list_next(const struct list *head, const struct list *elem);
|
||||
* already-processed elements.
|
||||
* If 'start' is 'head' it walks the list backwards.
|
||||
*/
|
||||
#define list_uniterate(v, head, start) \
|
||||
#define dm_list_uniterate(v, head, start) \
|
||||
for (v = (start)->p; v != head; v = v->p)
|
||||
|
||||
/*
|
||||
@@ -136,68 +141,68 @@ struct list *list_next(const struct list *head, const struct list *elem);
|
||||
* the way.
|
||||
* t must be defined as a temporary variable of the same type as v.
|
||||
*/
|
||||
#define list_iterate_safe(v, t, head) \
|
||||
#define dm_list_iterate_safe(v, t, head) \
|
||||
for (v = (head)->n, t = v->n; v != head; v = t, t = v->n)
|
||||
|
||||
/*
|
||||
* Walk a list, setting 'v' in turn to the containing structure of each item.
|
||||
* The containing structure should be the same type as 'v'.
|
||||
* The 'struct list' variable within the containing structure is 'field'.
|
||||
* The 'struct dm_list' variable within the containing structure is 'field'.
|
||||
*/
|
||||
#define list_iterate_items_gen(v, head, field) \
|
||||
for (v = list_struct_base((head)->n, typeof(*v), field); \
|
||||
#define dm_list_iterate_items_gen(v, head, field) \
|
||||
for (v = dm_list_struct_base((head)->n, typeof(*v), field); \
|
||||
&v->field != (head); \
|
||||
v = list_struct_base(v->field.n, typeof(*v), field))
|
||||
v = dm_list_struct_base(v->field.n, typeof(*v), field))
|
||||
|
||||
/*
|
||||
* Walk a list, setting 'v' in turn to the containing structure of each item.
|
||||
* The containing structure should be the same type as 'v'.
|
||||
* The list should be 'struct list list' within the containing structure.
|
||||
* The list should be 'struct dm_list list' within the containing structure.
|
||||
*/
|
||||
#define list_iterate_items(v, head) list_iterate_items_gen(v, (head), list)
|
||||
#define dm_list_iterate_items(v, head) dm_list_iterate_items_gen(v, (head), list)
|
||||
|
||||
/*
|
||||
* Walk a list, setting 'v' in turn to the containing structure of each item.
|
||||
* The containing structure should be the same type as 'v'.
|
||||
* The 'struct list' variable within the containing structure is 'field'.
|
||||
* The 'struct dm_list' variable within the containing structure is 'field'.
|
||||
* t must be defined as a temporary variable of the same type as v.
|
||||
*/
|
||||
#define list_iterate_items_gen_safe(v, t, head, field) \
|
||||
for (v = list_struct_base((head)->n, typeof(*v), field), \
|
||||
t = list_struct_base(v->field.n, typeof(*v), field); \
|
||||
#define dm_list_iterate_items_gen_safe(v, t, head, field) \
|
||||
for (v = dm_list_struct_base((head)->n, typeof(*v), field), \
|
||||
t = dm_list_struct_base(v->field.n, typeof(*v), field); \
|
||||
&v->field != (head); \
|
||||
v = t, t = list_struct_base(v->field.n, typeof(*v), field))
|
||||
v = t, t = dm_list_struct_base(v->field.n, typeof(*v), field))
|
||||
/*
|
||||
* Walk a list, setting 'v' in turn to the containing structure of each item.
|
||||
* The containing structure should be the same type as 'v'.
|
||||
* The list should be 'struct list list' within the containing structure.
|
||||
* The list should be 'struct dm_list list' within the containing structure.
|
||||
* t must be defined as a temporary variable of the same type as v.
|
||||
*/
|
||||
#define list_iterate_items_safe(v, t, head) \
|
||||
list_iterate_items_gen_safe(v, t, (head), list)
|
||||
#define dm_list_iterate_items_safe(v, t, head) \
|
||||
dm_list_iterate_items_gen_safe(v, t, (head), list)
|
||||
|
||||
/*
|
||||
* Walk a list backwards, setting 'v' in turn to the containing structure
|
||||
* of each item.
|
||||
* The containing structure should be the same type as 'v'.
|
||||
* The 'struct list' variable within the containing structure is 'field'.
|
||||
* The 'struct dm_list' variable within the containing structure is 'field'.
|
||||
*/
|
||||
#define list_iterate_back_items_gen(v, head, field) \
|
||||
for (v = list_struct_base((head)->p, typeof(*v), field); \
|
||||
#define dm_list_iterate_back_items_gen(v, head, field) \
|
||||
for (v = dm_list_struct_base((head)->p, typeof(*v), field); \
|
||||
&v->field != (head); \
|
||||
v = list_struct_base(v->field.p, typeof(*v), field))
|
||||
v = dm_list_struct_base(v->field.p, typeof(*v), field))
|
||||
|
||||
/*
|
||||
* Walk a list backwards, setting 'v' in turn to the containing structure
|
||||
* of each item.
|
||||
* The containing structure should be the same type as 'v'.
|
||||
* The list should be 'struct list list' within the containing structure.
|
||||
* The list should be 'struct dm_list list' within the containing structure.
|
||||
*/
|
||||
#define list_iterate_back_items(v, head) list_iterate_back_items_gen(v, (head), list)
|
||||
#define dm_list_iterate_back_items(v, head) dm_list_iterate_back_items_gen(v, (head), list)
|
||||
|
||||
/*
|
||||
* Return the number of elements in a list by walking it.
|
||||
*/
|
||||
unsigned int list_size(const struct list *head);
|
||||
unsigned int dm_list_size(const struct dm_list *head);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -16,17 +16,16 @@
|
||||
#ifndef _LVM_TYPES_H
|
||||
#define _LVM_TYPES_H
|
||||
|
||||
#include "list.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
/* Define some portable printing types */
|
||||
#define PRIsize_t "zu"
|
||||
#define PRIptrdiff_t "td"
|
||||
#define PRIpid_t PRId32
|
||||
|
||||
struct str_list {
|
||||
struct list list;
|
||||
struct dm_list list;
|
||||
const char *str;
|
||||
};
|
||||
|
||||
|
||||
@@ -16,68 +16,60 @@
|
||||
#include "lib.h"
|
||||
#include "str_list.h"
|
||||
|
||||
struct list *str_list_create(struct dm_pool *mem)
|
||||
struct dm_list *str_list_create(struct dm_pool *mem)
|
||||
{
|
||||
struct list *sl;
|
||||
struct dm_list *sl;
|
||||
|
||||
if (!(sl = dm_pool_alloc(mem, sizeof(struct list)))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
if (!(sl = dm_pool_alloc(mem, sizeof(struct dm_list))))
|
||||
return_NULL;
|
||||
|
||||
list_init(sl);
|
||||
dm_list_init(sl);
|
||||
|
||||
return sl;
|
||||
}
|
||||
|
||||
int str_list_add(struct dm_pool *mem, struct list *sll, const char *str)
|
||||
int str_list_add(struct dm_pool *mem, struct dm_list *sll, const char *str)
|
||||
{
|
||||
struct str_list *sln;
|
||||
|
||||
if (!str) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!str)
|
||||
return_0;
|
||||
|
||||
/* Already in list? */
|
||||
if (str_list_match_item(sll, str))
|
||||
return 1;
|
||||
|
||||
if (!(sln = dm_pool_alloc(mem, sizeof(*sln)))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(sln = dm_pool_alloc(mem, sizeof(*sln))))
|
||||
return_0;
|
||||
|
||||
sln->str = str;
|
||||
list_add(sll, &sln->list);
|
||||
dm_list_add(sll, &sln->list);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int str_list_del(struct list *sll, const char *str)
|
||||
int str_list_del(struct dm_list *sll, const char *str)
|
||||
{
|
||||
struct list *slh, *slht;
|
||||
struct dm_list *slh, *slht;
|
||||
|
||||
list_iterate_safe(slh, slht, sll) {
|
||||
if (!strcmp(str, list_item(slh, struct str_list)->str))
|
||||
list_del(slh);
|
||||
dm_list_iterate_safe(slh, slht, sll) {
|
||||
if (!strcmp(str, dm_list_item(slh, struct str_list)->str))
|
||||
dm_list_del(slh);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int str_list_dup(struct dm_pool *mem, struct list *sllnew,
|
||||
const struct list *sllold)
|
||||
int str_list_dup(struct dm_pool *mem, struct dm_list *sllnew,
|
||||
const struct dm_list *sllold)
|
||||
{
|
||||
struct str_list *sl;
|
||||
|
||||
list_init(sllnew);
|
||||
dm_list_init(sllnew);
|
||||
|
||||
list_iterate_items(sl, sllold) {
|
||||
if (!str_list_add(mem, sllnew, dm_pool_strdup(mem, sl->str))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
dm_list_iterate_items(sl, sllold) {
|
||||
if (!str_list_add(mem, sllnew, dm_pool_strdup(mem, sl->str)))
|
||||
return_0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
@@ -86,11 +78,11 @@ int str_list_dup(struct dm_pool *mem, struct list *sllnew,
|
||||
/*
|
||||
* Is item on list?
|
||||
*/
|
||||
int str_list_match_item(const struct list *sll, const char *str)
|
||||
int str_list_match_item(const struct dm_list *sll, const char *str)
|
||||
{
|
||||
struct str_list *sl;
|
||||
|
||||
list_iterate_items(sl, sll)
|
||||
dm_list_iterate_items(sl, sll)
|
||||
if (!strcmp(str, sl->str))
|
||||
return 1;
|
||||
|
||||
@@ -100,11 +92,11 @@ int str_list_match_item(const struct list *sll, const char *str)
|
||||
/*
|
||||
* Is at least one item on both lists?
|
||||
*/
|
||||
int str_list_match_list(const struct list *sll, const struct list *sll2)
|
||||
int str_list_match_list(const struct dm_list *sll, const struct dm_list *sll2)
|
||||
{
|
||||
struct str_list *sl;
|
||||
|
||||
list_iterate_items(sl, sll)
|
||||
dm_list_iterate_items(sl, sll)
|
||||
if (str_list_match_item(sll2, sl->str))
|
||||
return 1;
|
||||
|
||||
@@ -114,14 +106,14 @@ int str_list_match_list(const struct list *sll, const struct list *sll2)
|
||||
/*
|
||||
* Do both lists contain the same set of items?
|
||||
*/
|
||||
int str_list_lists_equal(const struct list *sll, const struct list *sll2)
|
||||
int str_list_lists_equal(const struct dm_list *sll, const struct dm_list *sll2)
|
||||
{
|
||||
struct str_list *sl;
|
||||
|
||||
if (list_size(sll) != list_size(sll2))
|
||||
if (dm_list_size(sll) != dm_list_size(sll2))
|
||||
return 0;
|
||||
|
||||
list_iterate_items(sl, sll)
|
||||
dm_list_iterate_items(sl, sll)
|
||||
if (!str_list_match_item(sll2, sl->str))
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
#ifndef _LVM_STR_LIST_H
|
||||
#define _LVM_STR_LIST_H
|
||||
|
||||
struct list *str_list_create(struct dm_pool *mem);
|
||||
int str_list_add(struct dm_pool *mem, struct list *sll, const char *str);
|
||||
int str_list_del(struct list *sll, const char *str);
|
||||
int str_list_match_item(const struct list *sll, const char *str);
|
||||
int str_list_match_list(const struct list *sll, const struct list *sll2);
|
||||
int str_list_lists_equal(const struct list *sll, const struct list *sll2);
|
||||
int str_list_dup(struct dm_pool *mem, struct list *sllnew,
|
||||
const struct list *sllold);
|
||||
struct dm_list *str_list_create(struct dm_pool *mem);
|
||||
int str_list_add(struct dm_pool *mem, struct dm_list *sll, const char *str);
|
||||
int str_list_del(struct dm_list *sll, const char *str);
|
||||
int str_list_match_item(const struct dm_list *sll, const char *str);
|
||||
int str_list_match_list(const struct dm_list *sll, const struct dm_list *sll2);
|
||||
int str_list_lists_equal(const struct dm_list *sll, const struct dm_list *sll2);
|
||||
int str_list_dup(struct dm_pool *mem, struct dm_list *sllnew,
|
||||
const struct dm_list *sllold);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
@@ -31,7 +31,7 @@ struct dev_iter {
|
||||
};
|
||||
|
||||
struct dir_list {
|
||||
struct list list;
|
||||
struct dm_list list;
|
||||
char dir[0];
|
||||
};
|
||||
|
||||
@@ -42,8 +42,8 @@ static struct {
|
||||
struct dm_regex *preferred_names_matcher;
|
||||
|
||||
int has_scanned;
|
||||
struct list dirs;
|
||||
struct list files;
|
||||
struct dm_list dirs;
|
||||
struct dm_list files;
|
||||
|
||||
} _cache;
|
||||
|
||||
@@ -97,15 +97,15 @@ struct device *dev_create_file(const char *filename, struct device *dev,
|
||||
}
|
||||
|
||||
dev->flags |= DEV_REGULAR;
|
||||
list_init(&dev->aliases);
|
||||
list_add(&dev->aliases, &alias->list);
|
||||
dm_list_init(&dev->aliases);
|
||||
dm_list_add(&dev->aliases, &alias->list);
|
||||
dev->end = UINT64_C(0);
|
||||
dev->dev = 0;
|
||||
dev->fd = -1;
|
||||
dev->open_count = 0;
|
||||
dev->block_size = -1;
|
||||
memset(dev->pvid, 0, sizeof(dev->pvid));
|
||||
list_init(&dev->open_list);
|
||||
dm_list_init(&dev->open_list);
|
||||
|
||||
return dev;
|
||||
}
|
||||
@@ -119,14 +119,14 @@ static struct device *_dev_create(dev_t d)
|
||||
return NULL;
|
||||
}
|
||||
dev->flags = 0;
|
||||
list_init(&dev->aliases);
|
||||
dm_list_init(&dev->aliases);
|
||||
dev->dev = d;
|
||||
dev->fd = -1;
|
||||
dev->open_count = 0;
|
||||
dev->block_size = -1;
|
||||
dev->end = UINT64_C(0);
|
||||
memset(dev->pvid, 0, sizeof(dev->pvid));
|
||||
list_init(&dev->open_list);
|
||||
dm_list_init(&dev->open_list);
|
||||
|
||||
return dev;
|
||||
}
|
||||
@@ -140,8 +140,8 @@ void dev_set_preferred_name(struct str_list *sl, struct device *dev)
|
||||
return;
|
||||
|
||||
log_debug("%s: New preferred name", sl->str);
|
||||
list_del(&sl->list);
|
||||
list_add_h(&dev->aliases, &sl->list);
|
||||
dm_list_del(&sl->list);
|
||||
dm_list_add_h(&dev->aliases, &sl->list);
|
||||
}
|
||||
|
||||
/* Return 1 if we prefer path1 else return 0 */
|
||||
@@ -236,26 +236,22 @@ static int _add_alias(struct device *dev, const char *path)
|
||||
const char *oldpath;
|
||||
int prefer_old = 1;
|
||||
|
||||
if (!sl) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!sl)
|
||||
return_0;
|
||||
|
||||
/* Is name already there? */
|
||||
list_iterate_items(strl, &dev->aliases) {
|
||||
dm_list_iterate_items(strl, &dev->aliases) {
|
||||
if (!strcmp(strl->str, path)) {
|
||||
log_debug("%s: Already in device cache", path);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(sl->str = dm_pool_strdup(_cache.mem, path))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(sl->str = dm_pool_strdup(_cache.mem, path)))
|
||||
return_0;
|
||||
|
||||
if (!list_empty(&dev->aliases)) {
|
||||
oldpath = list_item(dev->aliases.n, struct str_list)->str;
|
||||
if (!dm_list_empty(&dev->aliases)) {
|
||||
oldpath = dm_list_item(dev->aliases.n, struct str_list)->str;
|
||||
prefer_old = _compare_paths(path, oldpath);
|
||||
log_debug("%s: Aliased to %s in device cache%s",
|
||||
path, oldpath, prefer_old ? "" : " (preferred name)");
|
||||
@@ -264,9 +260,9 @@ static int _add_alias(struct device *dev, const char *path)
|
||||
log_debug("%s: Added to device cache", path);
|
||||
|
||||
if (prefer_old)
|
||||
list_add(&dev->aliases, &sl->list);
|
||||
dm_list_add(&dev->aliases, &sl->list);
|
||||
else
|
||||
list_add_h(&dev->aliases, &sl->list);
|
||||
dm_list_add_h(&dev->aliases, &sl->list);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -294,14 +290,10 @@ static int _insert_dev(const char *path, dev_t d)
|
||||
(uint32_t) d))) {
|
||||
/* create new device */
|
||||
if (loopfile) {
|
||||
if (!(dev = dev_create_file(path, NULL, NULL, 0))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
} else if (!(dev = _dev_create(d))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(dev = dev_create_file(path, NULL, NULL, 0)))
|
||||
return_0;
|
||||
} else if (!(dev = _dev_create(d)))
|
||||
return_0;
|
||||
|
||||
if (!(btree_insert(_cache.devices, (uint32_t) d, dev))) {
|
||||
log_err("Couldn't insert device into binary tree.");
|
||||
@@ -369,10 +361,8 @@ static int _insert_dir(const char *dir)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(path = _join(dir, dirent[n]->d_name))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(path = _join(dir, dirent[n]->d_name)))
|
||||
return_0;
|
||||
|
||||
_collapse_slashes(path);
|
||||
r &= _insert(path, 1);
|
||||
@@ -400,10 +390,8 @@ static int _insert_file(const char *path)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!_insert_dev(path, 0)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!_insert_dev(path, 0))
|
||||
return_0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -439,10 +427,8 @@ static int _insert(const char *path, int rec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!_insert_dev(path, info.st_rdev)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!_insert_dev(path, info.st_rdev))
|
||||
return_0;
|
||||
|
||||
r = 1;
|
||||
}
|
||||
@@ -457,10 +443,10 @@ static void _full_scan(int dev_scan)
|
||||
if (_cache.has_scanned && !dev_scan)
|
||||
return;
|
||||
|
||||
list_iterate_items(dl, &_cache.dirs)
|
||||
dm_list_iterate_items(dl, &_cache.dirs)
|
||||
_insert_dir(dl->dir);
|
||||
|
||||
list_iterate_items(dl, &_cache.files)
|
||||
dm_list_iterate_items(dl, &_cache.files)
|
||||
_insert_file(dl->dir);
|
||||
|
||||
_cache.has_scanned = 1;
|
||||
@@ -502,7 +488,7 @@ static int _init_preferred_names(struct cmd_context *cmd)
|
||||
if (v->type != CFG_STRING) {
|
||||
log_error("preferred_names patterns must be enclosed in quotes");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
@@ -543,16 +529,13 @@ int dev_cache_init(struct cmd_context *cmd)
|
||||
_cache.names = NULL;
|
||||
_cache.has_scanned = 0;
|
||||
|
||||
if (!(_cache.mem = dm_pool_create("dev_cache", 10 * 1024))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(_cache.mem = dm_pool_create("dev_cache", 10 * 1024)))
|
||||
return_0;
|
||||
|
||||
if (!(_cache.names = dm_hash_create(128))) {
|
||||
stack;
|
||||
dm_pool_destroy(_cache.mem);
|
||||
_cache.mem = 0;
|
||||
return 0;
|
||||
return_0;
|
||||
}
|
||||
|
||||
if (!(_cache.devices = btree_create(_cache.mem))) {
|
||||
@@ -560,8 +543,8 @@ int dev_cache_init(struct cmd_context *cmd)
|
||||
goto bad;
|
||||
}
|
||||
|
||||
list_init(&_cache.dirs);
|
||||
list_init(&_cache.files);
|
||||
dm_list_init(&_cache.dirs);
|
||||
dm_list_init(&_cache.files);
|
||||
|
||||
if (!_init_preferred_names(cmd))
|
||||
goto_bad;
|
||||
@@ -604,8 +587,8 @@ void dev_cache_exit(void)
|
||||
|
||||
_cache.devices = NULL;
|
||||
_cache.has_scanned = 0;
|
||||
list_init(&_cache.dirs);
|
||||
list_init(&_cache.files);
|
||||
dm_list_init(&_cache.dirs);
|
||||
dm_list_init(&_cache.files);
|
||||
}
|
||||
|
||||
int dev_cache_add_dir(const char *path)
|
||||
@@ -630,7 +613,7 @@ int dev_cache_add_dir(const char *path)
|
||||
}
|
||||
|
||||
strcpy(dl->dir, path);
|
||||
list_add(&_cache.dirs, &dl->list);
|
||||
dm_list_add(&_cache.dirs, &dl->list);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -656,7 +639,7 @@ int dev_cache_add_loopfile(const char *path)
|
||||
}
|
||||
|
||||
strcpy(dl->dir, path);
|
||||
list_add(&_cache.files, &dl->list);
|
||||
dm_list_add(&_cache.files, &dl->list);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -673,7 +656,7 @@ const char *dev_name_confirmed(struct device *dev, int quiet)
|
||||
if ((dev->flags & DEV_REGULAR))
|
||||
return dev_name(dev);
|
||||
|
||||
while ((r = stat(name = list_item(dev->aliases.n,
|
||||
while ((r = stat(name = dm_list_item(dev->aliases.n,
|
||||
struct str_list)->str, &buf)) ||
|
||||
(buf.st_rdev != dev->dev)) {
|
||||
if (r < 0) {
|
||||
@@ -697,14 +680,15 @@ const char *dev_name_confirmed(struct device *dev, int quiet)
|
||||
/* Leave list alone if there isn't an alternative name */
|
||||
/* so dev_name will always find something to return. */
|
||||
/* Otherwise add the name to the correct device. */
|
||||
if (list_size(&dev->aliases) > 1) {
|
||||
list_del(dev->aliases.n);
|
||||
if (dm_list_size(&dev->aliases) > 1) {
|
||||
dm_list_del(dev->aliases.n);
|
||||
if (!r)
|
||||
_insert(name, 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
log_error("Aborting - please provide new pathname for what "
|
||||
/* Scanning issues this inappropriately sometimes. */
|
||||
log_debug("Aborting - please provide new pathname for what "
|
||||
"used to be %s", name);
|
||||
return NULL;
|
||||
}
|
||||
@@ -792,6 +776,6 @@ int dev_fd(struct device *dev)
|
||||
|
||||
const char *dev_name(const struct device *dev)
|
||||
{
|
||||
return (dev) ? list_item(dev->aliases.n, struct str_list)->str :
|
||||
return (dev) ? dm_list_item(dev->aliases.n, struct str_list)->str :
|
||||
"unknown device";
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static LIST_INIT(_open_devices);
|
||||
static DM_LIST_INIT(_open_devices);
|
||||
|
||||
/*-----------------------------------------------------------------
|
||||
* The standard io loop that keeps submitting an io until it's
|
||||
@@ -170,10 +170,8 @@ static int _aligned_io(struct device_area *where, void *buffer,
|
||||
struct device_area widened;
|
||||
|
||||
if (!(where->dev->flags & DEV_REGULAR) &&
|
||||
!_get_block_size(where->dev, &block_size)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
!_get_block_size(where->dev, &block_size))
|
||||
return_0;
|
||||
|
||||
if (!block_size)
|
||||
block_size = lvm_getpagesize();
|
||||
@@ -200,10 +198,8 @@ static int _aligned_io(struct device_area *where, void *buffer,
|
||||
|
||||
/* channel the io through the bounce buffer */
|
||||
if (!_io(&widened, bounce, 0)) {
|
||||
if (!should_write) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!should_write)
|
||||
return_0;
|
||||
/* FIXME pre-extend the file */
|
||||
memset(bounce, '\n', widened.size);
|
||||
}
|
||||
@@ -340,7 +336,7 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
|
||||
|
||||
if (dev->open_count && !need_excl) {
|
||||
/* FIXME Ensure we never get here */
|
||||
log_debug("WARNING: %s already opened read-only",
|
||||
log_debug("WARNING: %s already opened read-only",
|
||||
dev_name(dev));
|
||||
dev->open_count++;
|
||||
}
|
||||
@@ -354,10 +350,8 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
|
||||
|
||||
if (dev->flags & DEV_REGULAR)
|
||||
name = dev_name(dev);
|
||||
else if (!(name = dev_name_confirmed(dev, quiet))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
else if (!(name = dev_name_confirmed(dev, quiet)))
|
||||
return_0;
|
||||
|
||||
if (!(dev->flags & DEV_REGULAR)) {
|
||||
if (stat(name, &buf) < 0) {
|
||||
@@ -437,7 +431,7 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
|
||||
if ((flags & O_CREAT) && !(flags & O_TRUNC))
|
||||
dev->end = lseek(dev->fd, (off_t) 0, SEEK_END);
|
||||
|
||||
list_add(&_open_devices, &dev->open_list);
|
||||
dm_list_add(&_open_devices, &dev->open_list);
|
||||
|
||||
log_debug("Opened %s %s%s%s", dev_name(dev),
|
||||
dev->flags & DEV_OPENED_RW ? "RW" : "RO",
|
||||
@@ -486,12 +480,12 @@ static void _close(struct device *dev)
|
||||
log_sys_error("close", dev_name(dev));
|
||||
dev->fd = -1;
|
||||
dev->block_size = -1;
|
||||
list_del(&dev->open_list);
|
||||
dm_list_del(&dev->open_list);
|
||||
|
||||
log_debug("Closed %s", dev_name(dev));
|
||||
|
||||
if (dev->flags & DEV_ALLOCED) {
|
||||
dm_free((void *) list_item(dev->aliases.n, struct str_list)->
|
||||
dm_free((void *) dm_list_item(dev->aliases.n, struct str_list)->
|
||||
str);
|
||||
dm_free(dev->aliases.n);
|
||||
dm_free(dev);
|
||||
@@ -522,8 +516,8 @@ static int _dev_close(struct device *dev, int immediate)
|
||||
|
||||
/* Close unless device is known to belong to a locked VG */
|
||||
if (immediate ||
|
||||
(dev->open_count < 1 &&
|
||||
(!(info = info_from_pvid(dev->pvid)) ||
|
||||
(dev->open_count < 1 &&
|
||||
(!(info = info_from_pvid(dev->pvid, 0)) ||
|
||||
!info->vginfo ||
|
||||
!vgname_is_locked(info->vginfo->vgname))))
|
||||
_close(dev);
|
||||
@@ -543,11 +537,11 @@ int dev_close_immediate(struct device *dev)
|
||||
|
||||
void dev_close_all(void)
|
||||
{
|
||||
struct list *doh, *doht;
|
||||
struct dm_list *doh, *doht;
|
||||
struct device *dev;
|
||||
|
||||
list_iterate_safe(doh, doht, &_open_devices) {
|
||||
dev = list_struct_base(doh, struct device, open_list);
|
||||
dm_list_iterate_safe(doh, doht, &_open_devices) {
|
||||
dev = dm_list_struct_base(doh, struct device, open_list);
|
||||
if (dev->open_count < 1)
|
||||
_close(dev);
|
||||
}
|
||||
@@ -557,10 +551,8 @@ int dev_read(struct device *dev, uint64_t offset, size_t len, void *buffer)
|
||||
{
|
||||
struct device_area where;
|
||||
|
||||
if (!dev->open_count) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!dev->open_count)
|
||||
return_0;
|
||||
|
||||
where.dev = dev;
|
||||
where.start = offset;
|
||||
@@ -607,10 +599,8 @@ int dev_append(struct device *dev, size_t len, void *buffer)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (!dev->open_count) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!dev->open_count)
|
||||
return_0;
|
||||
|
||||
r = dev_write(dev, dev->end, len, buffer);
|
||||
dev->end += (uint64_t) len;
|
||||
@@ -625,10 +615,8 @@ int dev_write(struct device *dev, uint64_t offset, size_t len, void *buffer)
|
||||
{
|
||||
struct device_area where;
|
||||
|
||||
if (!dev->open_count) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!dev->open_count)
|
||||
return_0;
|
||||
|
||||
where.dev = dev;
|
||||
where.start = offset;
|
||||
@@ -644,10 +632,8 @@ int dev_set(struct device *dev, uint64_t offset, size_t len, int value)
|
||||
size_t s;
|
||||
char buffer[4096] __attribute((aligned(8)));
|
||||
|
||||
if (!dev_open(dev)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!dev_open(dev))
|
||||
return_0;
|
||||
|
||||
if ((offset % SECTOR_SIZE) || (len % SECTOR_SIZE))
|
||||
log_debug("Wiping %s at %" PRIu64 " length %" PRIsize_t,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2004 Luca Berra
|
||||
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
*
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "lib.h"
|
||||
#include "metadata.h"
|
||||
#include "xlate.h"
|
||||
#include "filter.h"
|
||||
|
||||
#ifdef linux
|
||||
|
||||
@@ -48,18 +49,26 @@ static int _dev_has_md_magic(struct device *dev, uint64_t sb_offset)
|
||||
* 1: At start of device
|
||||
* 2: 4K from start of device.
|
||||
*/
|
||||
static uint64_t _v1_sb_offset(uint64_t size, unsigned minor_version)
|
||||
typedef enum {
|
||||
MD_MINOR_VERSION_MIN,
|
||||
MD_MINOR_V0 = MD_MINOR_VERSION_MIN,
|
||||
MD_MINOR_V1,
|
||||
MD_MINOR_V2,
|
||||
MD_MINOR_VERSION_MAX = MD_MINOR_V2
|
||||
} md_minor_version_t;
|
||||
|
||||
static uint64_t _v1_sb_offset(uint64_t size, md_minor_version_t minor_version)
|
||||
{
|
||||
uint64_t sb_offset;
|
||||
uint64_t uninitialized_var(sb_offset);
|
||||
|
||||
switch(minor_version) {
|
||||
case 0:
|
||||
case MD_MINOR_V0:
|
||||
sb_offset = (size - 8 * 2) & ~(4 * 2 - 1ULL);
|
||||
break;
|
||||
case 1:
|
||||
case MD_MINOR_V1:
|
||||
sb_offset = 0;
|
||||
break;
|
||||
case 2:
|
||||
case MD_MINOR_V2:
|
||||
sb_offset = 4 * 2;
|
||||
break;
|
||||
}
|
||||
@@ -74,7 +83,7 @@ static uint64_t _v1_sb_offset(uint64_t size, unsigned minor_version)
|
||||
int dev_is_md(struct device *dev, uint64_t *sb)
|
||||
{
|
||||
int ret = 1;
|
||||
unsigned minor = 0;
|
||||
md_minor_version_t minor;
|
||||
uint64_t size, sb_offset;
|
||||
|
||||
if (!dev_get_size(dev, &size)) {
|
||||
@@ -96,12 +105,13 @@ int dev_is_md(struct device *dev, uint64_t *sb)
|
||||
if (_dev_has_md_magic(dev, sb_offset))
|
||||
goto out;
|
||||
|
||||
minor = MD_MINOR_VERSION_MIN;
|
||||
/* Version 1, try v1.0 -> v1.2 */
|
||||
do {
|
||||
sb_offset = _v1_sb_offset(size, minor);
|
||||
if (_dev_has_md_magic(dev, sb_offset))
|
||||
goto out;
|
||||
} while (++minor <= 2);
|
||||
} while (++minor <= MD_MINOR_VERSION_MAX);
|
||||
|
||||
ret = 0;
|
||||
|
||||
@@ -115,6 +125,62 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Retrieve chunk size from md device using sysfs.
|
||||
*/
|
||||
unsigned long dev_md_chunk_size(const char *sysfs_dir, struct device *dev)
|
||||
{
|
||||
char path[PATH_MAX+1], buffer[64];
|
||||
FILE *fp;
|
||||
struct stat info;
|
||||
unsigned long chunk_size_bytes = 0UL;
|
||||
|
||||
if (MAJOR(dev->dev) != md_major())
|
||||
return 0;
|
||||
|
||||
if (!sysfs_dir || !*sysfs_dir)
|
||||
return_0;
|
||||
|
||||
if (dm_snprintf(path, PATH_MAX, "%s/dev/block/%d:%d/md/chunk_size",
|
||||
sysfs_dir, MAJOR(dev->dev), MINOR(dev->dev)) < 0) {
|
||||
log_error("dm_snprintf md chunk_size failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* old sysfs structure */
|
||||
if (stat(path, &info) &&
|
||||
dm_snprintf(path, PATH_MAX, "%s/block/md%d/md/chunk_size",
|
||||
sysfs_dir, MINOR(dev->dev)) < 0) {
|
||||
log_error("dm_snprintf old md chunk size failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(fp = fopen(path, "r"))) {
|
||||
log_sys_error("fopen", path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!fgets(buffer, sizeof(buffer), fp)) {
|
||||
log_sys_error("fgets", path);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (sscanf(buffer, "%lu", &chunk_size_bytes) != 1) {
|
||||
log_error("sysfs file %s not in expected format: %s", path,
|
||||
buffer);
|
||||
goto out;
|
||||
}
|
||||
|
||||
log_very_verbose("Device %s md chunk size is %lu bytes.",
|
||||
dev_name(dev), chunk_size_bytes);
|
||||
|
||||
out:
|
||||
if (fclose(fp))
|
||||
log_sys_error("fclose", path);
|
||||
|
||||
return chunk_size_bytes >> SECTOR_SHIFT;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int dev_is_md(struct device *dev __attribute((unused)),
|
||||
@@ -123,4 +189,10 @@ int dev_is_md(struct device *dev __attribute((unused)),
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long dev_md_chunk_size(const char *sysfs_dir __attribute((unused)),
|
||||
struct device *dev __attribute((unused)))
|
||||
{
|
||||
return 0UL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -27,16 +27,16 @@
|
||||
#define PART_OFFSET UINT64_C(0x1BE)
|
||||
|
||||
struct partition {
|
||||
uint8_t boot_ind;
|
||||
uint8_t head;
|
||||
uint8_t sector;
|
||||
uint8_t cyl;
|
||||
uint8_t sys_ind; /* partition type */
|
||||
uint8_t end_head;
|
||||
uint8_t end_sector;
|
||||
uint8_t end_cyl;
|
||||
uint32_t start_sect;
|
||||
uint32_t nr_sects;
|
||||
uint8_t boot_ind;
|
||||
uint8_t head;
|
||||
uint8_t sector;
|
||||
uint8_t cyl;
|
||||
uint8_t sys_ind; /* partition type */
|
||||
uint8_t end_head;
|
||||
uint8_t end_sector;
|
||||
uint8_t end_cyl;
|
||||
uint32_t start_sect;
|
||||
uint32_t nr_sects;
|
||||
} __attribute__((packed));
|
||||
|
||||
static int _is_partitionable(struct device *dev)
|
||||
@@ -62,10 +62,8 @@ static int _has_partition_table(struct device *dev)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!dev_read(dev, UINT64_C(0), sizeof(buf), &buf)) {
|
||||
stack;
|
||||
goto out;
|
||||
}
|
||||
if (!dev_read(dev, UINT64_C(0), sizeof(buf), &buf))
|
||||
goto_out;
|
||||
|
||||
/* FIXME Check for other types of partition table too */
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
* pointer comparisons are valid.
|
||||
*/
|
||||
struct device {
|
||||
struct list aliases; /* struct str_list from lvm-types.h */
|
||||
struct dm_list aliases; /* struct str_list from lvm-types.h */
|
||||
dev_t dev;
|
||||
|
||||
/* private */
|
||||
@@ -42,14 +42,14 @@ struct device {
|
||||
int block_size;
|
||||
uint32_t flags;
|
||||
uint64_t end;
|
||||
struct list open_list;
|
||||
struct dm_list open_list;
|
||||
|
||||
char pvid[ID_LEN + 1];
|
||||
char _padding[7];
|
||||
};
|
||||
|
||||
struct device_list {
|
||||
struct list list;
|
||||
struct dm_list list;
|
||||
struct device *dev;
|
||||
};
|
||||
|
||||
@@ -93,11 +93,7 @@ const char *dev_name_confirmed(struct device *dev, int quiet);
|
||||
|
||||
/* Does device contain md superblock? If so, where? */
|
||||
int dev_is_md(struct device *dev, uint64_t *sb);
|
||||
|
||||
/* FIXME Check partition type if appropriate */
|
||||
|
||||
#define is_lvm_partition(a) 1
|
||||
/* int is_lvm_partition(const char *name); */
|
||||
unsigned long dev_md_chunk_size(const char *sysfs_dir, struct device *dev);
|
||||
|
||||
int is_partitioned_dev(struct device *dev);
|
||||
|
||||
|
||||
@@ -24,9 +24,9 @@
|
||||
|
||||
typedef enum { SIZE_LONG = 0, SIZE_SHORT = 1, SIZE_UNIT = 2 } size_len_t;
|
||||
|
||||
static struct {
|
||||
static const struct {
|
||||
alloc_policy_t alloc;
|
||||
const char *str;
|
||||
const char str[12]; /* must be changed when size extends 11 chars */
|
||||
} _policies[] = {
|
||||
{
|
||||
ALLOC_CONTIGUOUS, "contiguous"}, {
|
||||
@@ -36,7 +36,7 @@ static struct {
|
||||
ALLOC_INHERIT, "inherit"}
|
||||
};
|
||||
|
||||
static int _num_policies = sizeof(_policies) / sizeof(*_policies);
|
||||
static const int _num_policies = sizeof(_policies) / sizeof(*_policies);
|
||||
|
||||
uint64_t units_to_bytes(const char *units, char *unit_type)
|
||||
{
|
||||
@@ -155,7 +155,7 @@ static const char *_display_size(const struct cmd_context *cmd,
|
||||
uint64_t byte = UINT64_C(0);
|
||||
uint64_t units = UINT64_C(1024);
|
||||
char *size_buf = NULL;
|
||||
const char *size_str[][3] = {
|
||||
const char * const size_str[][3] = {
|
||||
{" Exabyte", " EB", "E"},
|
||||
{" Petabyte", " PB", "P"},
|
||||
{" Terabyte", " TB", "T"},
|
||||
@@ -266,11 +266,11 @@ void pvdisplay_segments(const struct physical_volume *pv)
|
||||
if (pv->pe_size)
|
||||
log_print("--- Physical Segments ---");
|
||||
|
||||
list_iterate_items(pvseg, &pv->segments) {
|
||||
dm_list_iterate_items(pvseg, &pv->segments) {
|
||||
log_print("Physical extent %u to %u:",
|
||||
pvseg->pe, pvseg->pe + pvseg->len - 1);
|
||||
|
||||
if (pvseg->lvseg) {
|
||||
if (pvseg_is_allocated(pvseg)) {
|
||||
log_print(" Logical volume\t%s%s/%s",
|
||||
pvseg->lvseg->lv->vg->cmd->dev_dir,
|
||||
pvseg->lvseg->lv->vg->name,
|
||||
@@ -307,7 +307,8 @@ void pvdisplay_full(const struct cmd_context *cmd,
|
||||
|
||||
log_print("--- %sPhysical volume ---", pv->pe_size ? "" : "NEW ");
|
||||
log_print("PV Name %s", pv_dev_name(pv));
|
||||
log_print("VG Name %s%s", pv->vg_name,
|
||||
log_print("VG Name %s%s",
|
||||
is_orphan(pv) ? "" : pv->vg_name,
|
||||
pv->status & EXPORTED_VG ? " (exported)" : "");
|
||||
|
||||
data_size = (uint64_t) pv->pe_count * pv->pe_size;
|
||||
@@ -360,10 +361,8 @@ int pvdisplay_short(const struct cmd_context *cmd __attribute((unused)),
|
||||
if (!pv)
|
||||
return 0;
|
||||
|
||||
if (!id_write_format(&pv->id, uuid, sizeof(uuid))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!id_write_format(&pv->id, uuid, sizeof(uuid)))
|
||||
return_0;
|
||||
|
||||
log_print("PV Name %s ", pv_dev_name(pv));
|
||||
/* FIXME pv->pv_number); */
|
||||
@@ -407,10 +406,8 @@ int lvdisplay_full(struct cmd_context *cmd,
|
||||
struct lv_segment *snap_seg = NULL;
|
||||
float snap_percent; /* fused, fsize; */
|
||||
|
||||
if (!id_write_format(&lv->lvid.id[1], uuid, sizeof(uuid))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!id_write_format(&lv->lvid.id[1], uuid, sizeof(uuid)))
|
||||
return_0;
|
||||
|
||||
inkernel = lv_info(cmd, lv, &info, 1, 1) && info.exists;
|
||||
|
||||
@@ -428,7 +425,7 @@ int lvdisplay_full(struct cmd_context *cmd,
|
||||
if (lv_is_origin(lv)) {
|
||||
log_print("LV snapshot status source of");
|
||||
|
||||
list_iterate_items_gen(snap_seg, &lv->snapshot_segs,
|
||||
dm_list_iterate_items_gen(snap_seg, &lv->snapshot_segs,
|
||||
origin_list) {
|
||||
if (inkernel &&
|
||||
(snap_active = lv_snapshot_percent(snap_seg->cow,
|
||||
@@ -486,7 +483,7 @@ int lvdisplay_full(struct cmd_context *cmd,
|
||||
display_size(cmd, (uint64_t) snap_seg->chunk_size));
|
||||
}
|
||||
|
||||
log_print("Segments %u", list_size(&lv->segments));
|
||||
log_print("Segments %u", dm_list_size(&lv->segments));
|
||||
|
||||
/********* FIXME Stripes & stripesize for each segment
|
||||
log_print("Stripe size (KByte) %u", lv->stripesize / 2);
|
||||
@@ -554,7 +551,7 @@ int lvdisplay_segments(const struct logical_volume *lv)
|
||||
|
||||
log_print("--- Segments ---");
|
||||
|
||||
list_iterate_items(seg, &lv->segments) {
|
||||
dm_list_iterate_items(seg, &lv->segments) {
|
||||
log_print("Logical extent %u to %u:",
|
||||
seg->le, seg->le + seg->len - 1);
|
||||
|
||||
@@ -575,14 +572,13 @@ void vgdisplay_extents(const struct volume_group *vg __attribute((unused)))
|
||||
|
||||
void vgdisplay_full(const struct volume_group *vg)
|
||||
{
|
||||
uint32_t access;
|
||||
uint32_t access_str;
|
||||
uint32_t active_pvs;
|
||||
uint32_t lv_count = 0;
|
||||
struct lv_list *lvl;
|
||||
char uuid[64] __attribute((aligned(8)));
|
||||
|
||||
if (vg->status & PARTIAL_VG)
|
||||
active_pvs = list_size(&vg->pvs);
|
||||
else
|
||||
active_pvs = vg->pv_count;
|
||||
active_pvs = vg->pv_count - vg_missing_pv_count(vg);
|
||||
|
||||
log_print("--- Volume group ---");
|
||||
log_print("VG Name %s", vg->name);
|
||||
@@ -590,28 +586,33 @@ void vgdisplay_full(const struct volume_group *vg)
|
||||
log_print("Format %s", vg->fid->fmt->name);
|
||||
if (vg->fid->fmt->features & FMT_MDAS) {
|
||||
log_print("Metadata Areas %d",
|
||||
list_size(&vg->fid->metadata_areas));
|
||||
dm_list_size(&vg->fid->metadata_areas));
|
||||
log_print("Metadata Sequence No %d", vg->seqno);
|
||||
}
|
||||
access = vg->status & (LVM_READ | LVM_WRITE);
|
||||
access_str = vg->status & (LVM_READ | LVM_WRITE);
|
||||
log_print("VG Access %s%s%s%s",
|
||||
access == (LVM_READ | LVM_WRITE) ? "read/write" : "",
|
||||
access == LVM_READ ? "read" : "",
|
||||
access == LVM_WRITE ? "write" : "",
|
||||
access == 0 ? "error" : "");
|
||||
access_str == (LVM_READ | LVM_WRITE) ? "read/write" : "",
|
||||
access_str == LVM_READ ? "read" : "",
|
||||
access_str == LVM_WRITE ? "write" : "",
|
||||
access_str == 0 ? "error" : "");
|
||||
log_print("VG Status %s%sresizable",
|
||||
vg->status & EXPORTED_VG ? "exported/" : "",
|
||||
vg->status & RESIZEABLE_VG ? "" : "NOT ");
|
||||
/* vg number not part of LVM2 design
|
||||
log_print ("VG # %u\n", vg->vg_number);
|
||||
*/
|
||||
if (vg->status & CLUSTERED) {
|
||||
if (vg_is_clustered(vg)) {
|
||||
log_print("Clustered yes");
|
||||
log_print("Shared %s",
|
||||
vg->status & SHARED ? "yes" : "no");
|
||||
}
|
||||
|
||||
dm_list_iterate_items(lvl, &vg->lvs)
|
||||
if (lv_is_visible(lvl->lv) && !(lvl->lv->status & SNAPSHOT))
|
||||
lv_count++;
|
||||
|
||||
log_print("MAX LV %u", vg->max_lv);
|
||||
log_print("Cur LV %u", vg->lv_count + vg->snapshot_count);
|
||||
log_print("Cur LV %u", lv_count);
|
||||
log_print("Open LV %u", lvs_in_vg_opened(vg));
|
||||
/****** FIXME Max LV Size
|
||||
log_print ( "MAX LV Size %s",
|
||||
@@ -655,26 +656,29 @@ void vgdisplay_full(const struct volume_group *vg)
|
||||
void vgdisplay_colons(const struct volume_group *vg)
|
||||
{
|
||||
uint32_t active_pvs;
|
||||
const char *access;
|
||||
uint32_t lv_count;
|
||||
struct lv_list *lvl;
|
||||
const char *access_str;
|
||||
char uuid[64] __attribute((aligned(8)));
|
||||
|
||||
if (vg->status & PARTIAL_VG)
|
||||
active_pvs = list_size(&vg->pvs);
|
||||
else
|
||||
active_pvs = vg->pv_count;
|
||||
active_pvs = vg->pv_count - vg_missing_pv_count(vg);
|
||||
|
||||
dm_list_iterate_items(lvl, &vg->lvs)
|
||||
if (lv_is_visible(lvl->lv) && !(lvl->lv->status & SNAPSHOT))
|
||||
lv_count++;
|
||||
|
||||
switch (vg->status & (LVM_READ | LVM_WRITE)) {
|
||||
case LVM_READ | LVM_WRITE:
|
||||
access = "r/w";
|
||||
access_str = "r/w";
|
||||
break;
|
||||
case LVM_READ:
|
||||
access = "r";
|
||||
access_str = "r";
|
||||
break;
|
||||
case LVM_WRITE:
|
||||
access = "w";
|
||||
access_str = "w";
|
||||
break;
|
||||
default:
|
||||
access = "";
|
||||
access_str = "";
|
||||
}
|
||||
|
||||
if (!id_write_format(&vg->id, uuid, sizeof(uuid))) {
|
||||
@@ -685,7 +689,7 @@ void vgdisplay_colons(const struct volume_group *vg)
|
||||
log_print("%s:%s:%d:-1:%u:%u:%u:-1:%u:%u:%u:%" PRIu64 ":%" PRIu32
|
||||
":%u:%u:%u:%s",
|
||||
vg->name,
|
||||
access,
|
||||
access_str,
|
||||
vg->status,
|
||||
/* internal volume group number; obsolete */
|
||||
vg->max_lv,
|
||||
@@ -698,7 +702,7 @@ void vgdisplay_colons(const struct volume_group *vg)
|
||||
(uint64_t) vg->extent_count * (vg->extent_size / 2),
|
||||
vg->extent_size / 2,
|
||||
vg->extent_count,
|
||||
vg->extent_count - vg->free_count,
|
||||
vg->extent_count - vg->free_count,
|
||||
vg->free_count,
|
||||
uuid[0] ? uuid : "none");
|
||||
return;
|
||||
@@ -722,7 +726,7 @@ void display_formats(const struct cmd_context *cmd)
|
||||
{
|
||||
const struct format_type *fmt;
|
||||
|
||||
list_iterate_items(fmt, &cmd->formats) {
|
||||
dm_list_iterate_items(fmt, &cmd->formats) {
|
||||
log_print("%s", fmt->name);
|
||||
}
|
||||
}
|
||||
@@ -731,7 +735,7 @@ void display_segtypes(const struct cmd_context *cmd)
|
||||
{
|
||||
const struct segment_type *segtype;
|
||||
|
||||
list_iterate_items(segtype, &cmd->segtypes) {
|
||||
dm_list_iterate_items(segtype, &cmd->segtypes) {
|
||||
log_print("%s", segtype->name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,8 @@ static int _errseg_add_target_line(struct dev_manager *dm __attribute((unused)),
|
||||
return dm_tree_node_add_error_target(node, len);
|
||||
}
|
||||
|
||||
static int _errseg_target_present(const struct lv_segment *seg __attribute((unused)))
|
||||
static int _errseg_target_present(const struct lv_segment *seg __attribute((unused)),
|
||||
unsigned *attributes __attribute((unused)))
|
||||
{
|
||||
static int _errseg_checked = 0;
|
||||
static int _errseg_present = 0;
|
||||
@@ -68,7 +69,7 @@ static int _errseg_target_present(const struct lv_segment *seg __attribute((unus
|
||||
|
||||
static int _errseg_modules_needed(struct dm_pool *mem,
|
||||
const struct lv_segment *seg __attribute((unused)),
|
||||
struct list *modules)
|
||||
struct dm_list *modules)
|
||||
{
|
||||
if (!str_list_add(mem, modules, "error")) {
|
||||
log_error("error module string list allocation failed");
|
||||
@@ -77,7 +78,7 @@ static int _errseg_modules_needed(struct dm_pool *mem,
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void _errseg_destroy(const struct segment_type *segtype)
|
||||
{
|
||||
dm_free((void *)segtype);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
@@ -50,10 +50,8 @@ struct dev_filter *composite_filter_create(int n, struct dev_filter **filters)
|
||||
{
|
||||
struct dev_filter **filters_copy, *cft;
|
||||
|
||||
if (!filters) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
if (!filters)
|
||||
return_NULL;
|
||||
|
||||
if (!(filters_copy = dm_malloc(sizeof(*filters) * (n + 1)))) {
|
||||
log_error("composite filters allocation failed");
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
|
||||
#ifdef linux
|
||||
|
||||
static int _ignore_md(struct dev_filter *f, struct device *dev)
|
||||
static int _ignore_md(struct dev_filter *f __attribute((unused)),
|
||||
struct device *dev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "dev-cache.h"
|
||||
#include "filter-persistent.h"
|
||||
#include "lvm-file.h"
|
||||
#include "lvm-string.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
@@ -42,10 +43,8 @@ static int _init_hash(struct pfilter *pf)
|
||||
if (pf->devices)
|
||||
dm_hash_destroy(pf->devices);
|
||||
|
||||
if (!(pf->devices = dm_hash_create(128))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(pf->devices = dm_hash_create(128)))
|
||||
return_0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -99,13 +98,13 @@ int persistent_filter_load(struct dev_filter *f, struct config_tree **cft_out)
|
||||
{
|
||||
struct pfilter *pf = (struct pfilter *) f->private;
|
||||
struct config_tree *cft;
|
||||
struct stat info;
|
||||
struct stat info;
|
||||
int r = 0;
|
||||
|
||||
if (!stat(pf->file, &info))
|
||||
if (!stat(pf->file, &info))
|
||||
pf->ctime = info.st_ctime;
|
||||
else {
|
||||
log_very_verbose("%s: stat failed: %s", pf->file,
|
||||
log_very_verbose("%s: stat failed: %s", pf->file,
|
||||
strerror(errno));
|
||||
return_0;
|
||||
}
|
||||
@@ -144,6 +143,7 @@ static void _write_array(struct pfilter *pf, FILE *fp, const char *path,
|
||||
{
|
||||
void *d;
|
||||
int first = 1;
|
||||
char *buf, *str;
|
||||
struct dm_hash_node *n;
|
||||
|
||||
for (n = dm_hash_get_first(pf->devices); n;
|
||||
@@ -160,7 +160,13 @@ static void _write_array(struct pfilter *pf, FILE *fp, const char *path,
|
||||
first = 0;
|
||||
}
|
||||
|
||||
fprintf(fp, "\t\t\"%s\"", dm_hash_get_key(pf->devices, n));
|
||||
str = dm_hash_get_key(pf->devices, n);
|
||||
if (!(buf = alloca(escaped_len(str)))) {
|
||||
log_error("persistent filter device path stack "
|
||||
"allocation failed");
|
||||
return;
|
||||
}
|
||||
fprintf(fp, "\t\t\"%s\"", escape_double_quotes(buf, str));
|
||||
}
|
||||
|
||||
if (!first)
|
||||
@@ -267,7 +273,7 @@ static int _lookup_p(struct dev_filter *f, struct device *dev)
|
||||
l = pf->real->passes_filter(pf->real, dev) ?
|
||||
PF_GOOD_DEVICE : PF_BAD_DEVICE;
|
||||
|
||||
list_iterate_items(sl, &dev->aliases)
|
||||
dm_list_iterate_items(sl, &dev->aliases)
|
||||
dm_hash_insert(pf->devices, sl->str, l);
|
||||
|
||||
} else if (l == PF_BAD_DEVICE)
|
||||
@@ -293,10 +299,8 @@ struct dev_filter *persistent_filter_create(struct dev_filter *real,
|
||||
struct pfilter *pf;
|
||||
struct dev_filter *f = NULL;
|
||||
|
||||
if (!(pf = dm_malloc(sizeof(*pf)))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
if (!(pf = dm_malloc(sizeof(*pf))))
|
||||
return_NULL;
|
||||
memset(pf, 0, sizeof(*pf));
|
||||
|
||||
if (!(pf->file = dm_malloc(strlen(file) + 1)))
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
@@ -70,10 +70,8 @@ static int _extract_pattern(struct dm_pool *mem, const char *pat,
|
||||
/*
|
||||
* copy the regex
|
||||
*/
|
||||
if (!(r = dm_pool_strdup(mem, pat))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(r = dm_pool_strdup(mem, pat)))
|
||||
return_0;
|
||||
|
||||
/*
|
||||
* trim the trailing character, having checked it's sep.
|
||||
@@ -153,7 +151,7 @@ static int _accept_p(struct dev_filter *f, struct device *dev)
|
||||
struct rfilter *rf = (struct rfilter *) f->private;
|
||||
struct str_list *sl;
|
||||
|
||||
list_iterate_items(sl, &dev->aliases) {
|
||||
dm_list_iterate_items(sl, &dev->aliases) {
|
||||
m = dm_regex_match(rf->engine, sl->str);
|
||||
|
||||
if (m >= 0) {
|
||||
@@ -192,10 +190,8 @@ struct dev_filter *regex_filter_create(struct config_value *patterns)
|
||||
struct rfilter *rf;
|
||||
struct dev_filter *f;
|
||||
|
||||
if (!mem) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
if (!mem)
|
||||
return_NULL;
|
||||
|
||||
if (!(rf = dm_pool_alloc(mem, sizeof(*rf))))
|
||||
goto_bad;
|
||||
|
||||
@@ -20,47 +20,11 @@
|
||||
|
||||
#include <dirent.h>
|
||||
|
||||
static int _locate_sysfs_blocks(const char *proc, char *path, size_t len,
|
||||
static int _locate_sysfs_blocks(const char *sysfs_dir, char *path, size_t len,
|
||||
unsigned *sysfs_depth)
|
||||
{
|
||||
char proc_mounts[PATH_MAX];
|
||||
FILE *fp;
|
||||
char *split[4], buffer[PATH_MAX + 16];
|
||||
const char *sys_mnt = NULL;
|
||||
struct stat info;
|
||||
|
||||
if (!*proc) {
|
||||
log_verbose("No proc filesystem found: skipping sysfs filter");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (dm_snprintf(proc_mounts, sizeof(proc_mounts),
|
||||
"%s/mounts", proc) < 0) {
|
||||
log_error("Failed to create /proc/mounts string");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(fp = fopen(proc_mounts, "r"))) {
|
||||
log_sys_error("fopen %s", proc_mounts);
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (fgets(buffer, sizeof(buffer), fp)) {
|
||||
if (dm_split_words(buffer, 4, 0, split) == 4 &&
|
||||
!strcmp(split[2], "sysfs")) {
|
||||
sys_mnt = split[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (fclose(fp))
|
||||
log_sys_error("fclose", proc_mounts);
|
||||
|
||||
if (!sys_mnt) {
|
||||
log_error("Failed to find sysfs mount point");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* unified classification directory for all kernel subsystems
|
||||
*
|
||||
@@ -70,7 +34,7 @@ static int _locate_sysfs_blocks(const char *proc, char *path, size_t len,
|
||||
* `-- sr0 -> ../../../devices/pci0000:00/0000:00:1f.2/host1/target1:0:0/1:0:0:0/block/sr0
|
||||
*
|
||||
*/
|
||||
if (dm_snprintf(path, len, "%s/%s", sys_mnt,
|
||||
if (dm_snprintf(path, len, "%s/%s", sysfs_dir,
|
||||
"subsystem/block/devices") >= 0) {
|
||||
if (!stat(path, &info)) {
|
||||
*sysfs_depth = 0;
|
||||
@@ -87,7 +51,7 @@ static int _locate_sysfs_blocks(const char *proc, char *path, size_t len,
|
||||
* `-- sr0 -> ../../devices/pci0000:00/0000:00:1f.2/host1/target1:0:0/1:0:0:0/block/sr0
|
||||
*
|
||||
*/
|
||||
if (dm_snprintf(path, len, "%s/%s", sys_mnt, "class/block") >= 0) {
|
||||
if (dm_snprintf(path, len, "%s/%s", sysfs_dir, "class/block") >= 0) {
|
||||
if (!stat(path, &info)) {
|
||||
*sysfs_depth = 0;
|
||||
return 1;
|
||||
@@ -112,7 +76,7 @@ static int _locate_sysfs_blocks(const char *proc, char *path, size_t len,
|
||||
* ...
|
||||
*
|
||||
*/
|
||||
if (dm_snprintf(path, len, "%s/%s", sys_mnt, "block") >= 0) {
|
||||
if (dm_snprintf(path, len, "%s/%s", sysfs_dir, "block") >= 0) {
|
||||
if (!stat(path, &info)) {
|
||||
*sysfs_depth = 1;
|
||||
return 1;
|
||||
@@ -236,21 +200,21 @@ static int _read_dev(const char *file, dev_t *result)
|
||||
*/
|
||||
static int _read_devs(struct dev_set *ds, const char *dir, unsigned sysfs_depth)
|
||||
{
|
||||
struct dirent *d;
|
||||
DIR *dr;
|
||||
struct dirent *d;
|
||||
DIR *dr;
|
||||
struct stat info;
|
||||
char path[PATH_MAX];
|
||||
char file[PATH_MAX];
|
||||
dev_t dev = { 0 };
|
||||
int r = 1;
|
||||
|
||||
if (!(dr = opendir(dir))) {
|
||||
log_sys_error("opendir", dir);
|
||||
return 0;
|
||||
}
|
||||
if (!(dr = opendir(dir))) {
|
||||
log_sys_error("opendir", dir);
|
||||
return 0;
|
||||
}
|
||||
|
||||
while ((d = readdir(dr))) {
|
||||
if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
|
||||
while ((d = readdir(dr))) {
|
||||
if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
|
||||
continue;
|
||||
|
||||
if (dm_snprintf(path, sizeof(path), "%s/%s", dir,
|
||||
@@ -278,8 +242,8 @@ static int _read_devs(struct dev_set *ds, const char *dir, unsigned sysfs_depth)
|
||||
}
|
||||
}
|
||||
|
||||
if (closedir(dr))
|
||||
log_sys_error("closedir", dir);
|
||||
if (closedir(dr))
|
||||
log_sys_error("closedir", dir);
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -321,7 +285,7 @@ static void _destroy(struct dev_filter *f)
|
||||
dm_pool_destroy(ds->mem);
|
||||
}
|
||||
|
||||
struct dev_filter *sysfs_filter_create(const char *proc)
|
||||
struct dev_filter *sysfs_filter_create(const char *sysfs_dir)
|
||||
{
|
||||
char sys_block[PATH_MAX];
|
||||
unsigned sysfs_depth;
|
||||
@@ -329,7 +293,12 @@ struct dev_filter *sysfs_filter_create(const char *proc)
|
||||
struct dev_set *ds;
|
||||
struct dev_filter *f;
|
||||
|
||||
if (!_locate_sysfs_blocks(proc, sys_block, sizeof(sys_block), &sysfs_depth))
|
||||
if (!*sysfs_dir) {
|
||||
log_verbose("No proc filesystem found: skipping sysfs filter");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!_locate_sysfs_blocks(sysfs_dir, sys_block, sizeof(sys_block), &sysfs_depth))
|
||||
return NULL;
|
||||
|
||||
if (!(mem = dm_pool_create("sysfs", 256))) {
|
||||
@@ -357,7 +326,7 @@ struct dev_filter *sysfs_filter_create(const char *proc)
|
||||
|
||||
#else
|
||||
|
||||
struct dev_filter *sysfs_filter_create(const char *proc __attribute((unused)))
|
||||
struct dev_filter *sysfs_filter_create(const char *sysfs_dir __attribute((unused)))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,6 @@
|
||||
#include "config.h"
|
||||
#include "dev-cache.h"
|
||||
|
||||
struct dev_filter *sysfs_filter_create(const char *proc);
|
||||
struct dev_filter *sysfs_filter_create(const char *sysfs_dir);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -77,6 +77,7 @@ static const device_info_t device_info[] = {
|
||||
{"xvd", 16}, /* Xen virtual block device */
|
||||
{"vdisk", 8}, /* SUN's LDOM virtual block device */
|
||||
{"ps3disk", 16}, /* PlayStation 3 internal disk */
|
||||
{"virtblk", 8}, /* VirtIO disk */
|
||||
{NULL, 0}
|
||||
};
|
||||
|
||||
@@ -277,9 +278,8 @@ struct dev_filter *lvm_type_filter_create(const char *proc,
|
||||
f->private = NULL;
|
||||
|
||||
if (!_scan_proc_dev(proc, cn)) {
|
||||
stack;
|
||||
dm_free(f);
|
||||
return NULL;
|
||||
return_NULL;
|
||||
}
|
||||
|
||||
return f;
|
||||
|
||||
@@ -26,6 +26,7 @@ SOURCES =\
|
||||
vg_number.c
|
||||
|
||||
LIB_SHARED = liblvm2format1.so
|
||||
LIB_VERSION = $(LIB_VERSION_LVM)
|
||||
|
||||
include $(top_srcdir)/make.tmpl
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
@@ -21,7 +21,6 @@
|
||||
|
||||
#include <fcntl.h>
|
||||
|
||||
#define fail do {stack; return 0;} while(0)
|
||||
#define xx16(v) disk->v = xlate16(disk->v)
|
||||
#define xx32(v) disk->v = xlate32(disk->v)
|
||||
#define xx64(v) disk->v = xlate64(disk->v)
|
||||
@@ -134,15 +133,15 @@ static int _munge_formats(struct pv_disk *pvd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* UUID too long? */
|
||||
if (pvd->pv_uuid[ID_LEN]) {
|
||||
/* UUID too long? */
|
||||
if (pvd->pv_uuid[ID_LEN]) {
|
||||
/* Retain ID_LEN chars from end */
|
||||
for (e = ID_LEN; e < sizeof(pvd->pv_uuid); e++) {
|
||||
if (!pvd->pv_uuid[e]) {
|
||||
e--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (e = ID_LEN; e < sizeof(pvd->pv_uuid); e++) {
|
||||
if (!pvd->pv_uuid[e]) {
|
||||
e--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (b = 0; b < ID_LEN; b++) {
|
||||
pvd->pv_uuid[b] = pvd->pv_uuid[++e - ID_LEN];
|
||||
/* FIXME Remove all invalid chars */
|
||||
@@ -150,7 +149,7 @@ static int _munge_formats(struct pv_disk *pvd)
|
||||
pvd->pv_uuid[b] = '#';
|
||||
}
|
||||
memset(&pvd->pv_uuid[ID_LEN], 0, sizeof(pvd->pv_uuid) - ID_LEN);
|
||||
}
|
||||
}
|
||||
|
||||
/* If UUID is missing, create one */
|
||||
if (pvd->pv_uuid[0] == '\0') {
|
||||
@@ -161,8 +160,8 @@ static int _munge_formats(struct pv_disk *pvd)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* If exported, remove "PV_EXP" from end of VG name
|
||||
/*
|
||||
* If exported, remove "PV_EXP" from end of VG name
|
||||
*/
|
||||
static void _munge_exported_vg(struct pv_disk *pvd)
|
||||
{
|
||||
@@ -178,8 +177,8 @@ static void _munge_exported_vg(struct pv_disk *pvd)
|
||||
s = sizeof(EXPORTED_TAG);
|
||||
if (!strncmp((char *)pvd->vg_name + l - s + 1, EXPORTED_TAG, s)) {
|
||||
pvd->vg_name[l - s + 1] = '\0';
|
||||
pvd->pv_status |= VG_EXPORTED;
|
||||
}
|
||||
pvd->pv_status |= VG_EXPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
int munge_pvd(struct device *dev, struct pv_disk *pvd)
|
||||
@@ -218,7 +217,7 @@ static int _read_pvd(struct device *dev, struct pv_disk *pvd)
|
||||
static int _read_lvd(struct device *dev, uint64_t pos, struct lv_disk *disk)
|
||||
{
|
||||
if (!dev_read(dev, pos, sizeof(*disk), disk))
|
||||
fail;
|
||||
return_0;
|
||||
|
||||
_xlate_lvd(disk);
|
||||
|
||||
@@ -230,12 +229,12 @@ int read_vgd(struct device *dev, struct vg_disk *vgd, struct pv_disk *pvd)
|
||||
uint64_t pos = pvd->vg_on_disk.base;
|
||||
|
||||
if (!dev_read(dev, pos, sizeof(*vgd), vgd))
|
||||
fail;
|
||||
return_0;
|
||||
|
||||
_xlate_vgd(vgd);
|
||||
|
||||
if ((vgd->lv_max > MAX_LV) || (vgd->pv_max > MAX_PV))
|
||||
fail;
|
||||
return_0;
|
||||
|
||||
/* If UUID is missing, create one */
|
||||
if (vgd->vg_uuid[0] == '\0')
|
||||
@@ -254,15 +253,15 @@ static int _read_uuids(struct disk_list *data)
|
||||
|
||||
while (pos < end && num_read < data->vgd.pv_cur) {
|
||||
if (!dev_read(data->dev, pos, sizeof(buffer), buffer))
|
||||
fail;
|
||||
return_0;
|
||||
|
||||
if (!(ul = dm_pool_alloc(data->mem, sizeof(*ul))))
|
||||
fail;
|
||||
return_0;
|
||||
|
||||
memcpy(ul->uuid, buffer, NAME_LEN);
|
||||
ul->uuid[NAME_LEN - 1] = '\0';
|
||||
|
||||
list_add(&data->uuids, &ul->list);
|
||||
dm_list_add(&data->uuids, &ul->list);
|
||||
|
||||
pos += NAME_LEN;
|
||||
num_read++;
|
||||
@@ -278,26 +277,26 @@ static int _check_lvd(struct lv_disk *lvd)
|
||||
|
||||
static int _read_lvs(struct disk_list *data)
|
||||
{
|
||||
unsigned int i, read = 0;
|
||||
unsigned int i, lvs_read = 0;
|
||||
uint64_t pos;
|
||||
struct lvd_list *ll;
|
||||
struct vg_disk *vgd = &data->vgd;
|
||||
|
||||
for (i = 0; (i < vgd->lv_max) && (read < vgd->lv_cur); i++) {
|
||||
for (i = 0; (i < vgd->lv_max) && (lvs_read < vgd->lv_cur); i++) {
|
||||
pos = data->pvd.lv_on_disk.base + (i * sizeof(struct lv_disk));
|
||||
ll = dm_pool_alloc(data->mem, sizeof(*ll));
|
||||
|
||||
if (!ll)
|
||||
fail;
|
||||
return_0;
|
||||
|
||||
if (!_read_lvd(data->dev, pos, &ll->lvd))
|
||||
fail;
|
||||
return_0;
|
||||
|
||||
if (!_check_lvd(&ll->lvd))
|
||||
continue;
|
||||
|
||||
read++;
|
||||
list_add(&data->lvds, &ll->list);
|
||||
lvs_read++;
|
||||
dm_list_add(&data->lvds, &ll->list);
|
||||
}
|
||||
|
||||
return 1;
|
||||
@@ -310,10 +309,10 @@ static int _read_extents(struct disk_list *data)
|
||||
uint64_t pos = data->pvd.pe_on_disk.base;
|
||||
|
||||
if (!extents)
|
||||
fail;
|
||||
return_0;
|
||||
|
||||
if (!dev_read(data->dev, pos, len, extents))
|
||||
fail;
|
||||
return_0;
|
||||
|
||||
_xlate_extents(extents, data->pvd.pe_total);
|
||||
data->extents = extents;
|
||||
@@ -327,16 +326,17 @@ static void __update_lvmcache(const struct format_type *fmt,
|
||||
unsigned exported)
|
||||
{
|
||||
struct lvmcache_info *info;
|
||||
const char *vgname = *((char *)dl->pvd.vg_name) ?
|
||||
(char *)dl->pvd.vg_name : fmt->orphan_vg_name;
|
||||
|
||||
if (!(info = lvmcache_add(fmt->labeller, (char *)dl->pvd.pv_uuid, dev,
|
||||
(char *)dl->pvd.vg_name, vgid,
|
||||
exported ? EXPORTED_VG : 0))) {
|
||||
vgname, vgid, exported ? EXPORTED_VG : 0))) {
|
||||
stack;
|
||||
return;
|
||||
}
|
||||
|
||||
info->device_size = xlate32(dl->pvd.pv_size) << SECTOR_SHIFT;
|
||||
list_init(&info->mdas);
|
||||
dm_list_init(&info->mdas);
|
||||
info->status &= ~CACHE_INVALID;
|
||||
}
|
||||
|
||||
@@ -347,15 +347,13 @@ static struct disk_list *__read_disk(const struct format_type *fmt,
|
||||
struct disk_list *dl = dm_pool_zalloc(mem, sizeof(*dl));
|
||||
const char *name = dev_name(dev);
|
||||
|
||||
if (!dl) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
if (!dl)
|
||||
return_NULL;
|
||||
|
||||
dl->dev = dev;
|
||||
dl->mem = mem;
|
||||
list_init(&dl->uuids);
|
||||
list_init(&dl->lvds);
|
||||
dm_list_init(&dl->uuids);
|
||||
dm_list_init(&dl->lvds);
|
||||
|
||||
if (!_read_pvd(dev, &dl->pvd))
|
||||
goto_bad;
|
||||
@@ -366,20 +364,20 @@ static struct disk_list *__read_disk(const struct format_type *fmt,
|
||||
if (!*dl->pvd.vg_name) {
|
||||
log_very_verbose("%s is not a member of any format1 VG", name);
|
||||
|
||||
__update_lvmcache(fmt, dl, dev, NULL, 0);
|
||||
__update_lvmcache(fmt, dl, dev, fmt->orphan_vg_name, 0);
|
||||
return (vg_name) ? NULL : dl;
|
||||
}
|
||||
|
||||
if (!read_vgd(dl->dev, &dl->vgd, &dl->pvd)) {
|
||||
log_error("Failed to read VG data from PV (%s)", name);
|
||||
__update_lvmcache(fmt, dl, dev, NULL, 0);
|
||||
__update_lvmcache(fmt, dl, dev, fmt->orphan_vg_name, 0);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (vg_name && strcmp(vg_name, (char *)dl->pvd.vg_name)) {
|
||||
log_very_verbose("%s is not a member of the VG %s",
|
||||
name, vg_name);
|
||||
__update_lvmcache(fmt, dl, dev, NULL, 0);
|
||||
__update_lvmcache(fmt, dl, dev, fmt->orphan_vg_name, 0);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
@@ -417,10 +415,8 @@ struct disk_list *read_disk(const struct format_type *fmt, struct device *dev,
|
||||
{
|
||||
struct disk_list *dl;
|
||||
|
||||
if (!dev_open(dev)) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
if (!dev_open(dev))
|
||||
return_NULL;
|
||||
|
||||
dl = __read_disk(fmt, dev, mem, vg_name);
|
||||
|
||||
@@ -430,12 +426,12 @@ struct disk_list *read_disk(const struct format_type *fmt, struct device *dev,
|
||||
return dl;
|
||||
}
|
||||
|
||||
static void _add_pv_to_list(struct list *head, struct disk_list *data)
|
||||
static void _add_pv_to_list(struct dm_list *head, struct disk_list *data)
|
||||
{
|
||||
struct pv_disk *pvd;
|
||||
struct disk_list *diskl;
|
||||
|
||||
list_iterate_items(diskl, head) {
|
||||
dm_list_iterate_items(diskl, head) {
|
||||
pvd = &diskl->pvd;
|
||||
if (!strncmp((char *)data->pvd.pv_uuid, (char *)pvd->pv_uuid,
|
||||
sizeof(pvd->pv_uuid))) {
|
||||
@@ -447,11 +443,11 @@ static void _add_pv_to_list(struct list *head, struct disk_list *data)
|
||||
}
|
||||
log_very_verbose("Duplicate PV %s - using md %s",
|
||||
pvd->pv_uuid, dev_name(data->dev));
|
||||
list_del(&diskl->list);
|
||||
dm_list_del(&diskl->list);
|
||||
break;
|
||||
}
|
||||
}
|
||||
list_add(head, &data->list);
|
||||
dm_list_add(head, &data->list);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -461,7 +457,7 @@ static void _add_pv_to_list(struct list *head, struct disk_list *data)
|
||||
*/
|
||||
int read_pvs_in_vg(const struct format_type *fmt, const char *vg_name,
|
||||
struct dev_filter *filter, struct dm_pool *mem,
|
||||
struct list *head)
|
||||
struct dm_list *head)
|
||||
{
|
||||
struct dev_iter *iter;
|
||||
struct device *dev;
|
||||
@@ -472,7 +468,7 @@ int read_pvs_in_vg(const struct format_type *fmt, const char *vg_name,
|
||||
/* Fast path if we already saw this VG and cached the list of PVs */
|
||||
if (vg_name && (vginfo = vginfo_from_vgname(vg_name, NULL)) &&
|
||||
vginfo->infos.n) {
|
||||
list_iterate_items(info, &vginfo->infos) {
|
||||
dm_list_iterate_items(info, &vginfo->infos) {
|
||||
dev = info->dev;
|
||||
if (dev && !(data = read_disk(fmt, dev, mem, vg_name)))
|
||||
break;
|
||||
@@ -482,11 +478,11 @@ int read_pvs_in_vg(const struct format_type *fmt, const char *vg_name,
|
||||
/* Did we find the whole VG? */
|
||||
if (!vg_name || is_orphan_vg(vg_name) ||
|
||||
(data && *data->pvd.vg_name &&
|
||||
list_size(head) == data->vgd.pv_cur))
|
||||
dm_list_size(head) == data->vgd.pv_cur))
|
||||
return 1;
|
||||
|
||||
/* Failed */
|
||||
list_init(head);
|
||||
dm_list_init(head);
|
||||
/* vgcache_del(vg_name); */
|
||||
}
|
||||
|
||||
@@ -503,7 +499,7 @@ int read_pvs_in_vg(const struct format_type *fmt, const char *vg_name,
|
||||
}
|
||||
dev_iter_destroy(iter);
|
||||
|
||||
if (list_empty(head))
|
||||
if (dm_list_empty(head))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
@@ -519,7 +515,7 @@ static int _write_vgd(struct disk_list *data)
|
||||
|
||||
_xlate_vgd(vgd);
|
||||
if (!dev_write(data->dev, pos, sizeof(*vgd), vgd))
|
||||
fail;
|
||||
return_0;
|
||||
|
||||
_xlate_vgd(vgd);
|
||||
|
||||
@@ -532,7 +528,7 @@ static int _write_uuids(struct disk_list *data)
|
||||
uint64_t pos = data->pvd.pv_uuidlist_on_disk.base;
|
||||
uint64_t end = pos + data->pvd.pv_uuidlist_on_disk.size;
|
||||
|
||||
list_iterate_items(ul, &data->uuids) {
|
||||
dm_list_iterate_items(ul, &data->uuids) {
|
||||
if (pos >= end) {
|
||||
log_error("Too many uuids to fit on %s",
|
||||
dev_name(data->dev));
|
||||
@@ -544,7 +540,7 @@ static int _write_uuids(struct disk_list *data)
|
||||
pos, NAME_LEN);
|
||||
|
||||
if (!dev_write(data->dev, pos, NAME_LEN, ul->uuid))
|
||||
fail;
|
||||
return_0;
|
||||
|
||||
pos += NAME_LEN;
|
||||
}
|
||||
@@ -560,7 +556,7 @@ static int _write_lvd(struct device *dev, uint64_t pos, struct lv_disk *disk)
|
||||
|
||||
_xlate_lvd(disk);
|
||||
if (!dev_write(dev, pos, sizeof(*disk), disk))
|
||||
fail;
|
||||
return_0;
|
||||
|
||||
_xlate_lvd(disk);
|
||||
|
||||
@@ -580,7 +576,7 @@ static int _write_lvs(struct disk_list *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
list_iterate_items(ll, &data->lvds) {
|
||||
dm_list_iterate_items(ll, &data->lvds) {
|
||||
offset = sizeof(struct lv_disk) * ll->lvd.lv_number;
|
||||
if (offset + sizeof(struct lv_disk) > data->pvd.lv_on_disk.size) {
|
||||
log_error("lv_number %d too large", ll->lvd.lv_number);
|
||||
@@ -588,7 +584,7 @@ static int _write_lvs(struct disk_list *data)
|
||||
}
|
||||
|
||||
if (!_write_lvd(data->dev, pos + offset, &ll->lvd))
|
||||
fail;
|
||||
return_0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
@@ -606,7 +602,7 @@ static int _write_extents(struct disk_list *data)
|
||||
|
||||
_xlate_extents(extents, data->pvd.pe_total);
|
||||
if (!dev_write(data->dev, pos, len, extents))
|
||||
fail;
|
||||
return_0;
|
||||
|
||||
_xlate_extents(extents, data->pvd.pe_total);
|
||||
|
||||
@@ -643,7 +639,7 @@ static int _write_pvd(struct disk_list *data)
|
||||
_xlate_pvd((struct pv_disk *) buf);
|
||||
if (!dev_write(data->dev, pos, size, buf)) {
|
||||
dm_free(buf);
|
||||
fail;
|
||||
return_0;
|
||||
}
|
||||
|
||||
dm_free(buf);
|
||||
@@ -707,10 +703,8 @@ static int _write_all_pvd(const struct format_type *fmt, struct disk_list *data)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (!dev_open(data->dev)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!dev_open(data->dev))
|
||||
return_0;
|
||||
|
||||
r = __write_all_pvd(fmt, data);
|
||||
|
||||
@@ -725,13 +719,13 @@ static int _write_all_pvd(const struct format_type *fmt, struct disk_list *data)
|
||||
* little sanity checking, so make sure correct
|
||||
* data is passed to here.
|
||||
*/
|
||||
int write_disks(const struct format_type *fmt, struct list *pvs)
|
||||
int write_disks(const struct format_type *fmt, struct dm_list *pvs)
|
||||
{
|
||||
struct disk_list *dl;
|
||||
|
||||
list_iterate_items(dl, pvs) {
|
||||
dm_list_iterate_items(dl, pvs) {
|
||||
if (!(_write_all_pvd(fmt, dl)))
|
||||
fail;
|
||||
return_0;
|
||||
|
||||
log_very_verbose("Successfully wrote data to %s",
|
||||
dev_name(dl->dev));
|
||||
|
||||
@@ -147,24 +147,24 @@ struct pe_disk {
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct uuid_list {
|
||||
struct list list;
|
||||
struct dm_list list;
|
||||
char uuid[NAME_LEN] __attribute((aligned(8)));
|
||||
};
|
||||
|
||||
struct lvd_list {
|
||||
struct list list;
|
||||
struct dm_list list;
|
||||
struct lv_disk lvd;
|
||||
};
|
||||
|
||||
struct disk_list {
|
||||
struct list list;
|
||||
struct dm_list list;
|
||||
struct dm_pool *mem;
|
||||
struct device *dev;
|
||||
|
||||
struct pv_disk pvd __attribute((aligned(8)));
|
||||
struct vg_disk vgd __attribute((aligned(8)));
|
||||
struct list uuids __attribute((aligned(8)));
|
||||
struct list lvds __attribute((aligned(8)));
|
||||
struct dm_list uuids __attribute((aligned(8)));
|
||||
struct dm_list lvds __attribute((aligned(8)));
|
||||
struct pe_disk *extents __attribute((aligned(8)));
|
||||
};
|
||||
|
||||
@@ -195,9 +195,9 @@ struct disk_list *read_disk(const struct format_type *fmt, struct device *dev,
|
||||
|
||||
int read_pvs_in_vg(const struct format_type *fmt, const char *vg_name,
|
||||
struct dev_filter *filter,
|
||||
struct dm_pool *mem, struct list *results);
|
||||
struct dm_pool *mem, struct dm_list *results);
|
||||
|
||||
int write_disks(const struct format_type *fmt, struct list *pvds);
|
||||
int write_disks(const struct format_type *fmt, struct dm_list *pvds);
|
||||
|
||||
/*
|
||||
* Functions to translate to between disk and in
|
||||
@@ -212,39 +212,39 @@ int export_pv(struct cmd_context *cmd, struct dm_pool *mem,
|
||||
struct pv_disk *pvd, struct physical_volume *pv);
|
||||
|
||||
int import_vg(struct dm_pool *mem,
|
||||
struct volume_group *vg, struct disk_list *dl, int partial);
|
||||
struct volume_group *vg, struct disk_list *dl);
|
||||
int export_vg(struct vg_disk *vgd, struct volume_group *vg);
|
||||
|
||||
int import_lv(struct dm_pool *mem, struct logical_volume *lv, struct lv_disk *lvd);
|
||||
|
||||
int import_extents(struct cmd_context *cmd, struct volume_group *vg,
|
||||
struct list *pvds);
|
||||
struct dm_list *pvds);
|
||||
int export_extents(struct disk_list *dl, uint32_t lv_num,
|
||||
struct logical_volume *lv, struct physical_volume *pv);
|
||||
|
||||
int import_pvs(const struct format_type *fmt, struct dm_pool *mem,
|
||||
struct volume_group *vg,
|
||||
struct list *pvds, struct list *results, uint32_t *count);
|
||||
struct dm_list *pvds, struct dm_list *results, uint32_t *count);
|
||||
|
||||
int import_lvs(struct dm_pool *mem, struct volume_group *vg, struct list *pvds);
|
||||
int import_lvs(struct dm_pool *mem, struct volume_group *vg, struct dm_list *pvds);
|
||||
int export_lvs(struct disk_list *dl, struct volume_group *vg,
|
||||
struct physical_volume *pv, const char *dev_dir);
|
||||
|
||||
int import_snapshots(struct dm_pool *mem, struct volume_group *vg,
|
||||
struct list *pvds);
|
||||
struct dm_list *pvds);
|
||||
|
||||
int export_uuids(struct disk_list *dl, struct volume_group *vg);
|
||||
|
||||
void export_numbers(struct list *pvds, struct volume_group *vg);
|
||||
void export_numbers(struct dm_list *pvds, struct volume_group *vg);
|
||||
|
||||
void export_pv_act(struct list *pvds);
|
||||
void export_pv_act(struct dm_list *pvds);
|
||||
int munge_pvd(struct device *dev, struct pv_disk *pvd);
|
||||
int read_vgd(struct device *dev, struct vg_disk *vgd, struct pv_disk *pvd);
|
||||
|
||||
/* blech */
|
||||
int get_free_vg_number(struct format_instance *fid, struct dev_filter *filter,
|
||||
const char *candidate_vg, int *result);
|
||||
int export_vg_number(struct format_instance *fid, struct list *pvds,
|
||||
int export_vg_number(struct format_instance *fid, struct dm_list *pvds,
|
||||
const char *vg_name, struct dev_filter *filter);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
@@ -18,17 +18,14 @@
|
||||
#include "limits.h"
|
||||
#include "display.h"
|
||||
#include "toolcontext.h"
|
||||
#include "lvmcache.h"
|
||||
#include "lvm1-label.h"
|
||||
#include "format1.h"
|
||||
#include "segtype.h"
|
||||
|
||||
#define FMT_LVM1_NAME "lvm1"
|
||||
|
||||
/* VG consistency checks */
|
||||
static int _check_vgs(struct list *pvs, int *partial)
|
||||
static int _check_vgs(struct dm_list *pvs)
|
||||
{
|
||||
struct list *pvh, *t;
|
||||
struct dm_list *pvh, *t;
|
||||
struct disk_list *dl = NULL;
|
||||
struct disk_list *first = NULL;
|
||||
|
||||
@@ -36,14 +33,12 @@ static int _check_vgs(struct list *pvs, int *partial)
|
||||
uint32_t exported = 0;
|
||||
int first_time = 1;
|
||||
|
||||
*partial = 0;
|
||||
|
||||
/*
|
||||
* If there are exported and unexported PVs, ignore exported ones.
|
||||
* This means an active VG won't be affected if disks are inserted
|
||||
* bearing an exported VG with the same name.
|
||||
*/
|
||||
list_iterate_items(dl, pvs) {
|
||||
dm_list_iterate_items(dl, pvs) {
|
||||
if (first_time) {
|
||||
exported = dl->pvd.pv_status & VG_EXPORTED;
|
||||
first_time = 0;
|
||||
@@ -52,18 +47,18 @@ static int _check_vgs(struct list *pvs, int *partial)
|
||||
|
||||
if (exported != (dl->pvd.pv_status & VG_EXPORTED)) {
|
||||
/* Remove exported PVs */
|
||||
list_iterate_safe(pvh, t, pvs) {
|
||||
dl = list_item(pvh, struct disk_list);
|
||||
dm_list_iterate_safe(pvh, t, pvs) {
|
||||
dl = dm_list_item(pvh, struct disk_list);
|
||||
if (dl->pvd.pv_status & VG_EXPORTED)
|
||||
list_del(pvh);
|
||||
dm_list_del(pvh);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove any PVs with VG structs that differ from the first */
|
||||
list_iterate_safe(pvh, t, pvs) {
|
||||
dl = list_item(pvh, struct disk_list);
|
||||
dm_list_iterate_safe(pvh, t, pvs) {
|
||||
dl = dm_list_item(pvh, struct disk_list);
|
||||
|
||||
if (!first)
|
||||
first = dl;
|
||||
@@ -100,11 +95,7 @@ static int _check_vgs(struct list *pvs, int *partial)
|
||||
dl->vgd.vgda, dl->vgd.pe_size,
|
||||
dl->vgd.pe_total, dl->vgd.pe_allocated,
|
||||
dl->vgd.pvg_total);
|
||||
list_del(pvh);
|
||||
if (partial_mode()) {
|
||||
*partial = 1;
|
||||
continue;
|
||||
}
|
||||
dm_list_del(pvh);
|
||||
return 0;
|
||||
}
|
||||
pv_count++;
|
||||
@@ -114,26 +105,22 @@ static int _check_vgs(struct list *pvs, int *partial)
|
||||
if (pv_count != first->vgd.pv_cur) {
|
||||
log_error("%d PV(s) found for VG %s: expected %d",
|
||||
pv_count, first->pvd.vg_name, first->vgd.pv_cur);
|
||||
if (!partial_mode())
|
||||
return 0;
|
||||
*partial = 1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct volume_group *_build_vg(struct format_instance *fid,
|
||||
struct list *pvs)
|
||||
struct dm_list *pvs)
|
||||
{
|
||||
struct dm_pool *mem = fid->fmt->cmd->mem;
|
||||
struct volume_group *vg = dm_pool_alloc(mem, sizeof(*vg));
|
||||
struct disk_list *dl;
|
||||
int partial;
|
||||
|
||||
if (!vg)
|
||||
goto_bad;
|
||||
|
||||
if (list_empty(pvs))
|
||||
if (dm_list_empty(pvs))
|
||||
goto_bad;
|
||||
|
||||
memset(vg, 0, sizeof(*vg));
|
||||
@@ -141,16 +128,16 @@ static struct volume_group *_build_vg(struct format_instance *fid,
|
||||
vg->cmd = fid->fmt->cmd;
|
||||
vg->fid = fid;
|
||||
vg->seqno = 0;
|
||||
list_init(&vg->pvs);
|
||||
list_init(&vg->lvs);
|
||||
list_init(&vg->tags);
|
||||
dm_list_init(&vg->pvs);
|
||||
dm_list_init(&vg->lvs);
|
||||
dm_list_init(&vg->tags);
|
||||
|
||||
if (!_check_vgs(pvs, &partial))
|
||||
if (!_check_vgs(pvs))
|
||||
goto_bad;
|
||||
|
||||
dl = list_item(pvs->n, struct disk_list);
|
||||
dl = dm_list_item(pvs->n, struct disk_list);
|
||||
|
||||
if (!import_vg(mem, vg, dl, partial))
|
||||
if (!import_vg(mem, vg, dl))
|
||||
goto_bad;
|
||||
|
||||
if (!import_pvs(fid->fmt, mem, vg, pvs, &vg->pvs, &vg->pv_count))
|
||||
@@ -168,7 +155,6 @@ static struct volume_group *_build_vg(struct format_instance *fid,
|
||||
return vg;
|
||||
|
||||
bad:
|
||||
stack;
|
||||
dm_pool_free(mem, vg);
|
||||
return NULL;
|
||||
}
|
||||
@@ -178,14 +164,12 @@ static struct volume_group *_format1_vg_read(struct format_instance *fid,
|
||||
struct metadata_area *mda __attribute((unused)))
|
||||
{
|
||||
struct dm_pool *mem = dm_pool_create("lvm1 vg_read", 1024 * 10);
|
||||
struct list pvs;
|
||||
struct dm_list pvs;
|
||||
struct volume_group *vg = NULL;
|
||||
list_init(&pvs);
|
||||
dm_list_init(&pvs);
|
||||
|
||||
if (!mem) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
if (!mem)
|
||||
return_NULL;
|
||||
|
||||
/* Strip dev_dir if present */
|
||||
vg_name = strip_dir(vg_name, fid->fmt->cmd->dev_dir);
|
||||
@@ -209,24 +193,21 @@ static struct disk_list *_flatten_pv(struct format_instance *fid,
|
||||
{
|
||||
struct disk_list *dl = dm_pool_alloc(mem, sizeof(*dl));
|
||||
|
||||
if (!dl) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
if (!dl)
|
||||
return_NULL;
|
||||
|
||||
dl->mem = mem;
|
||||
dl->dev = pv->dev;
|
||||
|
||||
list_init(&dl->uuids);
|
||||
list_init(&dl->lvds);
|
||||
dm_list_init(&dl->uuids);
|
||||
dm_list_init(&dl->lvds);
|
||||
|
||||
if (!export_pv(fid->fmt->cmd, mem, vg, &dl->pvd, pv) ||
|
||||
!export_vg(&dl->vgd, vg) ||
|
||||
!export_uuids(dl, vg) ||
|
||||
!export_lvs(dl, vg, pv, dev_dir) || !calculate_layout(dl)) {
|
||||
stack;
|
||||
dm_pool_free(mem, dl);
|
||||
return NULL;
|
||||
return_NULL;
|
||||
}
|
||||
|
||||
return dl;
|
||||
@@ -234,28 +215,24 @@ static struct disk_list *_flatten_pv(struct format_instance *fid,
|
||||
|
||||
static int _flatten_vg(struct format_instance *fid, struct dm_pool *mem,
|
||||
struct volume_group *vg,
|
||||
struct list *pvds, const char *dev_dir,
|
||||
struct dm_list *pvds, const char *dev_dir,
|
||||
struct dev_filter *filter)
|
||||
{
|
||||
struct pv_list *pvl;
|
||||
struct disk_list *data;
|
||||
|
||||
list_iterate_items(pvl, &vg->pvs) {
|
||||
if (!(data = _flatten_pv(fid, mem, vg, pvl->pv, dev_dir))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
dm_list_iterate_items(pvl, &vg->pvs) {
|
||||
if (!(data = _flatten_pv(fid, mem, vg, pvl->pv, dev_dir)))
|
||||
return_0;
|
||||
|
||||
list_add(pvds, &data->list);
|
||||
dm_list_add(pvds, &data->list);
|
||||
}
|
||||
|
||||
export_numbers(pvds, vg);
|
||||
export_pv_act(pvds);
|
||||
|
||||
if (!export_vg_number(fid, pvds, vg->name, filter)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!export_vg_number(fid, pvds, vg->name, filter))
|
||||
return_0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -264,27 +241,25 @@ static int _format1_vg_write(struct format_instance *fid, struct volume_group *v
|
||||
struct metadata_area *mda __attribute((unused)))
|
||||
{
|
||||
struct dm_pool *mem = dm_pool_create("lvm1 vg_write", 1024 * 10);
|
||||
struct list pvds;
|
||||
struct dm_list pvds;
|
||||
int r = 0;
|
||||
|
||||
if (!mem) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!mem)
|
||||
return_0;
|
||||
|
||||
list_init(&pvds);
|
||||
dm_list_init(&pvds);
|
||||
|
||||
r = (_flatten_vg(fid, mem, vg, &pvds, fid->fmt->cmd->dev_dir,
|
||||
fid->fmt->cmd->filter) &&
|
||||
write_disks(fid->fmt, &pvds));
|
||||
|
||||
lvmcache_update_vg(vg);
|
||||
lvmcache_update_vg(vg, 0);
|
||||
dm_pool_destroy(mem);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int _format1_pv_read(const struct format_type *fmt, const char *pv_name,
|
||||
struct physical_volume *pv, struct list *mdas __attribute((unused)))
|
||||
struct physical_volume *pv, struct dm_list *mdas __attribute((unused)))
|
||||
{
|
||||
struct dm_pool *mem = dm_pool_create("lvm1 pv_read", 1024);
|
||||
struct disk_list *dl;
|
||||
@@ -293,25 +268,17 @@ static int _format1_pv_read(const struct format_type *fmt, const char *pv_name,
|
||||
|
||||
log_very_verbose("Reading physical volume data %s from disk", pv_name);
|
||||
|
||||
if (!mem) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!mem)
|
||||
return_0;
|
||||
|
||||
if (!(dev = dev_cache_get(pv_name, fmt->cmd->filter))) {
|
||||
stack;
|
||||
goto out;
|
||||
}
|
||||
if (!(dev = dev_cache_get(pv_name, fmt->cmd->filter)))
|
||||
goto_out;
|
||||
|
||||
if (!(dl = read_disk(fmt, dev, mem, NULL))) {
|
||||
stack;
|
||||
goto out;
|
||||
}
|
||||
if (!(dl = read_disk(fmt, dev, mem, NULL)))
|
||||
goto_out;
|
||||
|
||||
if (!import_pv(fmt, fmt->cmd->mem, dl->dev, NULL, pv, &dl->pvd, &dl->vgd)) {
|
||||
stack;
|
||||
goto out;
|
||||
}
|
||||
if (!import_pv(fmt, fmt->cmd->mem, dl->dev, NULL, pv, &dl->pvd, &dl->vgd))
|
||||
goto_out;
|
||||
|
||||
pv->fmt = fmt;
|
||||
|
||||
@@ -326,7 +293,7 @@ static int _format1_pv_setup(const struct format_type *fmt,
|
||||
uint64_t pe_start, uint32_t extent_count,
|
||||
uint32_t extent_size,
|
||||
int pvmetadatacopies __attribute((unused)),
|
||||
uint64_t pvmetadatasize __attribute((unused)), struct list *mdas __attribute((unused)),
|
||||
uint64_t pvmetadatasize __attribute((unused)), struct dm_list *mdas __attribute((unused)),
|
||||
struct physical_volume *pv, struct volume_group *vg __attribute((unused)))
|
||||
{
|
||||
if (pv->size > MAX_PV_SIZE)
|
||||
@@ -344,10 +311,8 @@ static int _format1_pv_setup(const struct format_type *fmt,
|
||||
/*
|
||||
* This works out pe_start and pe_count.
|
||||
*/
|
||||
if (!calculate_extent_count(pv, extent_size, extent_count, pe_start)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!calculate_extent_count(pv, extent_size, extent_count, pe_start))
|
||||
return_0;
|
||||
|
||||
/* Retain existing extent locations exactly */
|
||||
if (((pe_start || extent_count) && (pe_start != pv->pe_start)) ||
|
||||
@@ -381,35 +346,31 @@ static int _format1_lv_setup(struct format_instance *fid, struct logical_volume
|
||||
}
|
||||
|
||||
static int _format1_pv_write(const struct format_type *fmt, struct physical_volume *pv,
|
||||
struct list *mdas __attribute((unused)), int64_t sector __attribute((unused)))
|
||||
struct dm_list *mdas __attribute((unused)), int64_t sector __attribute((unused)))
|
||||
{
|
||||
struct dm_pool *mem;
|
||||
struct disk_list *dl;
|
||||
struct list pvs;
|
||||
struct dm_list pvs;
|
||||
struct label *label;
|
||||
struct lvmcache_info *info;
|
||||
|
||||
if (!(info = lvmcache_add(fmt->labeller, (char *) &pv->id, pv->dev,
|
||||
pv->vg_name, NULL, 0))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
pv->vg_name, NULL, 0)))
|
||||
return_0;
|
||||
label = info->label;
|
||||
info->device_size = pv->size << SECTOR_SHIFT;
|
||||
info->fmt = fmt;
|
||||
|
||||
list_init(&info->mdas);
|
||||
dm_list_init(&info->mdas);
|
||||
|
||||
list_init(&pvs);
|
||||
dm_list_init(&pvs);
|
||||
|
||||
/* Ensure any residual PE structure is gone */
|
||||
pv->pe_size = pv->pe_count = 0;
|
||||
pv->pe_start = LVM1_PE_ALIGN;
|
||||
|
||||
if (!(mem = dm_pool_create("lvm1 pv_write", 1024))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(mem = dm_pool_create("lvm1 pv_write", 1024)))
|
||||
return_0;
|
||||
|
||||
if (!(dl = dm_pool_alloc(mem, sizeof(*dl))))
|
||||
goto_bad;
|
||||
@@ -426,7 +387,7 @@ static int _format1_pv_write(const struct format_type *fmt, struct physical_volu
|
||||
dl->pvd.pv_on_disk.size = PV_SIZE;
|
||||
dl->pvd.pe_on_disk.base = LVM1_PE_ALIGN << SECTOR_SHIFT;
|
||||
|
||||
list_add(&pvs, &dl->list);
|
||||
dm_list_add(&pvs, &dl->list);
|
||||
if (!write_disks(fmt, &pvs))
|
||||
goto_bad;
|
||||
|
||||
@@ -470,13 +431,11 @@ static int _format1_vg_setup(struct format_instance *fid, struct volume_group *v
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _format1_segtype_supported(struct format_instance *fid __attribute((unused)),
|
||||
static int _format1_segtype_supported(struct format_instance *fid __attribute((unused)),
|
||||
const struct segment_type *segtype)
|
||||
{
|
||||
if (!(segtype->flags & SEG_FORMAT1_SUPPORT)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(segtype->flags & SEG_FORMAT1_SUPPORT))
|
||||
return_0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -494,24 +453,21 @@ static struct format_instance *_format1_create_instance(const struct format_type
|
||||
struct format_instance *fid;
|
||||
struct metadata_area *mda;
|
||||
|
||||
if (!(fid = dm_pool_alloc(fmt->cmd->mem, sizeof(*fid)))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
if (!(fid = dm_pool_alloc(fmt->cmd->mem, sizeof(*fid))))
|
||||
return_NULL;
|
||||
|
||||
fid->fmt = fmt;
|
||||
list_init(&fid->metadata_areas);
|
||||
dm_list_init(&fid->metadata_areas);
|
||||
|
||||
/* Define a NULL metadata area */
|
||||
if (!(mda = dm_pool_alloc(fmt->cmd->mem, sizeof(*mda)))) {
|
||||
stack;
|
||||
dm_pool_free(fmt->cmd->mem, fid);
|
||||
return NULL;
|
||||
return_NULL;
|
||||
}
|
||||
|
||||
mda->ops = &_metadata_format1_ops;
|
||||
mda->metadata_locn = NULL;
|
||||
list_add(&fid->metadata_areas, &mda->list);
|
||||
dm_list_add(&fid->metadata_areas, &mda->list);
|
||||
|
||||
return fid;
|
||||
}
|
||||
@@ -547,15 +503,14 @@ struct format_type *init_format(struct cmd_context *cmd)
|
||||
{
|
||||
struct format_type *fmt = dm_malloc(sizeof(*fmt));
|
||||
|
||||
if (!fmt) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
if (!fmt)
|
||||
return_NULL;
|
||||
|
||||
fmt->cmd = cmd;
|
||||
fmt->ops = &_format1_ops;
|
||||
fmt->name = FMT_LVM1_NAME;
|
||||
fmt->alias = NULL;
|
||||
fmt->orphan_vg_name = FMT_LVM1_ORPHAN_VG_NAME;
|
||||
fmt->features = FMT_RESTRICTED_LVIDS | FMT_ORPHAN_ALLOCATABLE |
|
||||
FMT_RESTRICTED_READAHEAD;
|
||||
fmt->private = NULL;
|
||||
|
||||
@@ -17,6 +17,10 @@
|
||||
#define _LVM_FORMAT1_H
|
||||
|
||||
#include "metadata.h"
|
||||
#include "lvmcache.h"
|
||||
|
||||
#define FMT_LVM1_NAME "lvm1"
|
||||
#define FMT_LVM1_ORPHAN_VG_NAME ORPHAN_VG_NAME(FMT_LVM1_NAME)
|
||||
|
||||
#ifdef LVM1_INTERNAL
|
||||
struct format_type *init_lvm1_format(struct cmd_context *cmd);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "pv_alloc.h"
|
||||
#include "display.h"
|
||||
#include "lvmcache.h"
|
||||
#include "metadata.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
@@ -61,7 +62,7 @@ int import_pv(const struct format_type *fmt, struct dm_pool *mem,
|
||||
|
||||
pv->dev = dev;
|
||||
if (!*pvd->vg_name)
|
||||
pv->vg_name = ORPHAN;
|
||||
pv->vg_name = fmt->orphan_vg_name;
|
||||
else if (!(pv->vg_name = dm_pool_strdup(mem, (char *)pvd->vg_name))) {
|
||||
log_error("Volume Group name allocation failed.");
|
||||
return 0;
|
||||
@@ -94,6 +95,7 @@ int import_pv(const struct format_type *fmt, struct dm_pool *mem,
|
||||
pv->pe_start = pvd->pe_start;
|
||||
pv->pe_count = pvd->pe_total;
|
||||
pv->pe_alloc_count = 0;
|
||||
pv->pe_align = 0;
|
||||
|
||||
/* Fix up pv size if missing or impossibly large */
|
||||
if (!pv->size || pv->size > (1ULL << 62)) {
|
||||
@@ -114,13 +116,11 @@ int import_pv(const struct format_type *fmt, struct dm_pool *mem,
|
||||
}
|
||||
}
|
||||
|
||||
list_init(&pv->tags);
|
||||
list_init(&pv->segments);
|
||||
dm_list_init(&pv->tags);
|
||||
dm_list_init(&pv->segments);
|
||||
|
||||
if (!alloc_pv_segment_whole_pv(mem, pv)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!alloc_pv_segment_whole_pv(mem, pv))
|
||||
return_0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -149,11 +149,9 @@ int export_pv(struct cmd_context *cmd, struct dm_pool *mem __attribute((unused))
|
||||
|
||||
memcpy(pvd->pv_uuid, pv->id.uuid, ID_LEN);
|
||||
|
||||
if (pv->vg_name) {
|
||||
if (!_check_vg_name(pv->vg_name)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (pv->vg_name && !is_orphan(pv)) {
|
||||
if (!_check_vg_name(pv->vg_name))
|
||||
return_0;
|
||||
strncpy((char *)pvd->vg_name, pv->vg_name, sizeof(pvd->vg_name));
|
||||
}
|
||||
|
||||
@@ -167,10 +165,8 @@ int export_pv(struct cmd_context *cmd, struct dm_pool *mem __attribute((unused))
|
||||
if (!*vg->system_id ||
|
||||
strncmp(vg->system_id, EXPORTED_TAG,
|
||||
sizeof(EXPORTED_TAG) - 1)) {
|
||||
if (!_system_id(cmd, (char *)pvd->system_id, EXPORTED_TAG)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!_system_id(cmd, (char *)pvd->system_id, EXPORTED_TAG))
|
||||
return_0;
|
||||
}
|
||||
if (strlen((char *)pvd->vg_name) + sizeof(EXPORTED_TAG) >
|
||||
sizeof(pvd->vg_name)) {
|
||||
@@ -184,18 +180,14 @@ int export_pv(struct cmd_context *cmd, struct dm_pool *mem __attribute((unused))
|
||||
/* Is VG being imported? */
|
||||
if (vg && !(vg->status & EXPORTED_VG) && *vg->system_id &&
|
||||
!strncmp(vg->system_id, EXPORTED_TAG, sizeof(EXPORTED_TAG) - 1)) {
|
||||
if (!_system_id(cmd, (char *)pvd->system_id, IMPORTED_TAG)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!_system_id(cmd, (char *)pvd->system_id, IMPORTED_TAG))
|
||||
return_0;
|
||||
}
|
||||
|
||||
/* Generate system_id if PV is in VG */
|
||||
if (!pvd->system_id || !*pvd->system_id)
|
||||
if (!_system_id(cmd, (char *)pvd->system_id, "")) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!_system_id(cmd, (char *)pvd->system_id, ""))
|
||||
return_0;
|
||||
|
||||
/* Update internal system_id if we changed it */
|
||||
if (vg &&
|
||||
@@ -222,25 +214,19 @@ int export_pv(struct cmd_context *cmd, struct dm_pool *mem __attribute((unused))
|
||||
}
|
||||
|
||||
int import_vg(struct dm_pool *mem,
|
||||
struct volume_group *vg, struct disk_list *dl, int partial)
|
||||
struct volume_group *vg, struct disk_list *dl)
|
||||
{
|
||||
struct vg_disk *vgd = &dl->vgd;
|
||||
memcpy(vg->id.uuid, vgd->vg_uuid, ID_LEN);
|
||||
|
||||
if (!_check_vg_name((char *)dl->pvd.vg_name)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!_check_vg_name((char *)dl->pvd.vg_name))
|
||||
return_0;
|
||||
|
||||
if (!(vg->name = dm_pool_strdup(mem, (char *)dl->pvd.vg_name))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(vg->name = dm_pool_strdup(mem, (char *)dl->pvd.vg_name)))
|
||||
return_0;
|
||||
|
||||
if (!(vg->system_id = dm_pool_alloc(mem, NAME_LEN))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(vg->system_id = dm_pool_alloc(mem, NAME_LEN)))
|
||||
return_0;
|
||||
|
||||
*vg->system_id = '\0';
|
||||
|
||||
@@ -250,10 +236,10 @@ int import_vg(struct dm_pool *mem,
|
||||
if (vgd->vg_status & VG_EXTENDABLE)
|
||||
vg->status |= RESIZEABLE_VG;
|
||||
|
||||
if (partial || (vgd->vg_access & VG_READ))
|
||||
if (vgd->vg_access & VG_READ)
|
||||
vg->status |= LVM_READ;
|
||||
|
||||
if (!partial && (vgd->vg_access & VG_WRITE))
|
||||
if (vgd->vg_access & VG_WRITE)
|
||||
vg->status |= LVM_WRITE;
|
||||
|
||||
if (vgd->vg_access & VG_CLUSTERED)
|
||||
@@ -269,9 +255,6 @@ int import_vg(struct dm_pool *mem,
|
||||
vg->max_pv = vgd->pv_max;
|
||||
vg->alloc = ALLOC_NORMAL;
|
||||
|
||||
if (partial)
|
||||
vg->status |= PARTIAL_VG;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -286,7 +269,7 @@ int export_vg(struct vg_disk *vgd, struct volume_group *vg)
|
||||
if (vg->status & LVM_WRITE)
|
||||
vgd->vg_access |= VG_WRITE;
|
||||
|
||||
if (vg->status & CLUSTERED)
|
||||
if (vg_is_clustered(vg))
|
||||
vgd->vg_access |= VG_CLUSTERED;
|
||||
|
||||
if (vg->status & SHARED)
|
||||
@@ -299,7 +282,7 @@ int export_vg(struct vg_disk *vgd, struct volume_group *vg)
|
||||
vgd->vg_status |= VG_EXTENDABLE;
|
||||
|
||||
vgd->lv_max = vg->max_lv;
|
||||
vgd->lv_cur = vg->lv_count;
|
||||
vgd->lv_cur = vg->lv_count + vg->snapshot_count;
|
||||
|
||||
vgd->pv_max = vg->max_pv;
|
||||
vgd->pv_cur = vg->pv_count;
|
||||
@@ -315,10 +298,8 @@ int import_lv(struct dm_pool *mem, struct logical_volume *lv, struct lv_disk *lv
|
||||
{
|
||||
lvid_from_lvnum(&lv->lvid, &lv->vg->id, lvd->lv_number);
|
||||
|
||||
if (!(lv->name = _create_lv_name(mem, (char *)lvd->lv_name))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(lv->name = _create_lv_name(mem, (char *)lvd->lv_name)))
|
||||
return_0;
|
||||
|
||||
lv->status |= VISIBLE_LV;
|
||||
|
||||
@@ -358,9 +339,10 @@ int import_lv(struct dm_pool *mem, struct logical_volume *lv, struct lv_disk *lv
|
||||
lv->le_count = lvd->lv_allocated_le;
|
||||
|
||||
lv->snapshot = NULL;
|
||||
list_init(&lv->snapshot_segs);
|
||||
list_init(&lv->segments);
|
||||
list_init(&lv->tags);
|
||||
dm_list_init(&lv->snapshot_segs);
|
||||
dm_list_init(&lv->segments);
|
||||
dm_list_init(&lv->tags);
|
||||
dm_list_init(&lv->segs_using_this_lv);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -397,9 +379,9 @@ static void _export_lv(struct lv_disk *lvd, struct volume_group *vg,
|
||||
lvd->lv_read_ahead = lv->read_ahead;
|
||||
|
||||
lvd->lv_stripes =
|
||||
list_item(lv->segments.n, struct lv_segment)->area_count;
|
||||
dm_list_item(lv->segments.n, struct lv_segment)->area_count;
|
||||
lvd->lv_stripesize =
|
||||
list_item(lv->segments.n, struct lv_segment)->stripe_size;
|
||||
dm_list_item(lv->segments.n, struct lv_segment)->stripe_size;
|
||||
|
||||
lvd->lv_size = lv->size;
|
||||
lvd->lv_allocated_le = lv->le_count;
|
||||
@@ -418,7 +400,7 @@ int export_extents(struct disk_list *dl, uint32_t lv_num,
|
||||
struct lv_segment *seg;
|
||||
uint32_t pe, s;
|
||||
|
||||
list_iterate_items(seg, &lv->segments) {
|
||||
dm_list_iterate_items(seg, &lv->segments) {
|
||||
for (s = 0; s < seg->area_count; s++) {
|
||||
if (!(seg->segtype->flags & SEG_FORMAT1_SUPPORT)) {
|
||||
log_error("Segment type %s in LV %s: "
|
||||
@@ -448,26 +430,22 @@ int export_extents(struct disk_list *dl, uint32_t lv_num,
|
||||
|
||||
int import_pvs(const struct format_type *fmt, struct dm_pool *mem,
|
||||
struct volume_group *vg,
|
||||
struct list *pvds, struct list *results, uint32_t *count)
|
||||
struct dm_list *pvds, struct dm_list *results, uint32_t *count)
|
||||
{
|
||||
struct disk_list *dl;
|
||||
struct pv_list *pvl;
|
||||
|
||||
*count = 0;
|
||||
list_iterate_items(dl, pvds) {
|
||||
dm_list_iterate_items(dl, pvds) {
|
||||
if (!(pvl = dm_pool_zalloc(mem, sizeof(*pvl))) ||
|
||||
!(pvl->pv = dm_pool_alloc(mem, sizeof(*pvl->pv)))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
!(pvl->pv = dm_pool_alloc(mem, sizeof(*pvl->pv))))
|
||||
return_0;
|
||||
|
||||
if (!import_pv(fmt, mem, dl->dev, vg, pvl->pv, &dl->pvd, &dl->vgd)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!import_pv(fmt, mem, dl->dev, vg, pvl->pv, &dl->pvd, &dl->vgd))
|
||||
return_0;
|
||||
|
||||
pvl->pv->fmt = fmt;
|
||||
list_add(results, &pvl->list);
|
||||
dm_list_add(results, &pvl->list);
|
||||
(*count)++;
|
||||
}
|
||||
|
||||
@@ -482,39 +460,33 @@ static struct logical_volume *_add_lv(struct dm_pool *mem,
|
||||
struct logical_volume *lv;
|
||||
|
||||
if (!(ll = dm_pool_zalloc(mem, sizeof(*ll))) ||
|
||||
!(ll->lv = dm_pool_zalloc(mem, sizeof(*ll->lv)))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
!(ll->lv = dm_pool_zalloc(mem, sizeof(*ll->lv))))
|
||||
return_NULL;
|
||||
lv = ll->lv;
|
||||
lv->vg = vg;
|
||||
|
||||
if (!import_lv(mem, lv, lvd)) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
if (!import_lv(mem, lv, lvd))
|
||||
return_NULL;
|
||||
|
||||
list_add(&vg->lvs, &ll->list);
|
||||
dm_list_add(&vg->lvs, &ll->list);
|
||||
vg->lv_count++;
|
||||
|
||||
return lv;
|
||||
}
|
||||
|
||||
int import_lvs(struct dm_pool *mem, struct volume_group *vg, struct list *pvds)
|
||||
int import_lvs(struct dm_pool *mem, struct volume_group *vg, struct dm_list *pvds)
|
||||
{
|
||||
struct disk_list *dl;
|
||||
struct lvd_list *ll;
|
||||
struct lv_disk *lvd;
|
||||
|
||||
list_iterate_items(dl, pvds) {
|
||||
list_iterate_items(ll, &dl->lvds) {
|
||||
dm_list_iterate_items(dl, pvds) {
|
||||
dm_list_iterate_items(ll, &dl->lvds) {
|
||||
lvd = &ll->lvd;
|
||||
|
||||
if (!find_lv(vg, (char *)lvd->lv_name) &&
|
||||
!_add_lv(mem, vg, lvd)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
!_add_lv(mem, vg, lvd))
|
||||
return_0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -532,49 +504,37 @@ int export_lvs(struct disk_list *dl, struct volume_group *vg,
|
||||
uint32_t lv_num;
|
||||
struct dm_hash_table *lvd_hash;
|
||||
|
||||
if (!_check_vg_name(vg->name)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!_check_vg_name(vg->name))
|
||||
return_0;
|
||||
|
||||
if (!(lvd_hash = dm_hash_create(32))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(lvd_hash = dm_hash_create(32)))
|
||||
return_0;
|
||||
|
||||
/*
|
||||
* setup the pv's extents array
|
||||
*/
|
||||
len = sizeof(struct pe_disk) * dl->pvd.pe_total;
|
||||
if (!(dl->extents = dm_pool_alloc(dl->mem, len))) {
|
||||
stack;
|
||||
goto out;
|
||||
}
|
||||
if (!(dl->extents = dm_pool_alloc(dl->mem, len)))
|
||||
goto_out;
|
||||
memset(dl->extents, 0, len);
|
||||
|
||||
list_iterate_items(ll, &vg->lvs) {
|
||||
dm_list_iterate_items(ll, &vg->lvs) {
|
||||
if (ll->lv->status & SNAPSHOT)
|
||||
continue;
|
||||
|
||||
if (!(lvdl = dm_pool_alloc(dl->mem, sizeof(*lvdl)))) {
|
||||
stack;
|
||||
goto out;
|
||||
}
|
||||
if (!(lvdl = dm_pool_alloc(dl->mem, sizeof(*lvdl))))
|
||||
goto_out;
|
||||
|
||||
_export_lv(&lvdl->lvd, vg, ll->lv, dev_dir);
|
||||
|
||||
lv_num = lvnum_from_lvid(&ll->lv->lvid);
|
||||
lvdl->lvd.lv_number = lv_num;
|
||||
|
||||
if (!dm_hash_insert(lvd_hash, ll->lv->name, &lvdl->lvd)) {
|
||||
stack;
|
||||
goto out;
|
||||
}
|
||||
if (!dm_hash_insert(lvd_hash, ll->lv->name, &lvdl->lvd))
|
||||
goto_out;
|
||||
|
||||
if (!export_extents(dl, lv_num + 1, ll->lv, pv)) {
|
||||
stack;
|
||||
goto out;
|
||||
}
|
||||
if (!export_extents(dl, lv_num + 1, ll->lv, pv))
|
||||
goto_out;
|
||||
|
||||
if (lv_is_origin(ll->lv))
|
||||
lvdl->lvd.lv_access |= LV_SNAPSHOT_ORG;
|
||||
@@ -586,7 +546,7 @@ int export_lvs(struct disk_list *dl, struct volume_group *vg,
|
||||
lvnum_from_lvid(&ll->lv->snapshot->origin->lvid);
|
||||
}
|
||||
|
||||
list_add(&dl->lvds, &lvdl->list);
|
||||
dm_list_add(&dl->lvds, &lvdl->list);
|
||||
dl->pvd.lv_cur++;
|
||||
}
|
||||
|
||||
@@ -601,7 +561,7 @@ int export_lvs(struct disk_list *dl, struct volume_group *vg,
|
||||
* FIXME: More inefficient code.
|
||||
*/
|
||||
int import_snapshots(struct dm_pool *mem __attribute((unused)), struct volume_group *vg,
|
||||
struct list *pvds)
|
||||
struct dm_list *pvds)
|
||||
{
|
||||
struct logical_volume *lvs[MAX_LV];
|
||||
struct disk_list *dl;
|
||||
@@ -612,8 +572,8 @@ int import_snapshots(struct dm_pool *mem __attribute((unused)), struct volume_gr
|
||||
|
||||
/* build an index of lv numbers */
|
||||
memset(lvs, 0, sizeof(lvs));
|
||||
list_iterate_items(dl, pvds) {
|
||||
list_iterate_items(ll, &dl->lvds) {
|
||||
dm_list_iterate_items(dl, pvds) {
|
||||
dm_list_iterate_items(ll, &dl->lvds) {
|
||||
lvd = &ll->lvd;
|
||||
|
||||
lvnum = lvd->lv_number;
|
||||
@@ -636,8 +596,8 @@ int import_snapshots(struct dm_pool *mem __attribute((unused)), struct volume_gr
|
||||
/*
|
||||
* Now iterate through yet again adding the snapshots.
|
||||
*/
|
||||
list_iterate_items(dl, pvds) {
|
||||
list_iterate_items(ll, &dl->lvds) {
|
||||
dm_list_iterate_items(dl, pvds) {
|
||||
dm_list_iterate_items(ll, &dl->lvds) {
|
||||
lvd = &ll->lvd;
|
||||
|
||||
if (!(lvd->lv_access & LV_SNAPSHOT))
|
||||
@@ -657,7 +617,7 @@ int import_snapshots(struct dm_pool *mem __attribute((unused)), struct volume_gr
|
||||
|
||||
/* insert the snapshot */
|
||||
if (!vg_add_snapshot(NULL, org, cow, NULL,
|
||||
org->le_count,
|
||||
org->le_count,
|
||||
lvd->lv_chunk_size)) {
|
||||
log_err("Couldn't add snapshot.");
|
||||
return 0;
|
||||
@@ -673,16 +633,14 @@ int export_uuids(struct disk_list *dl, struct volume_group *vg)
|
||||
struct uuid_list *ul;
|
||||
struct pv_list *pvl;
|
||||
|
||||
list_iterate_items(pvl, &vg->pvs) {
|
||||
if (!(ul = dm_pool_alloc(dl->mem, sizeof(*ul)))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
dm_list_iterate_items(pvl, &vg->pvs) {
|
||||
if (!(ul = dm_pool_alloc(dl->mem, sizeof(*ul))))
|
||||
return_0;
|
||||
|
||||
memset(ul->uuid, 0, sizeof(ul->uuid));
|
||||
memcpy(ul->uuid, pvl->pv->id.uuid, ID_LEN);
|
||||
|
||||
list_add(&dl->uuids, &ul->list);
|
||||
dm_list_add(&dl->uuids, &ul->list);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -691,43 +649,41 @@ int export_uuids(struct disk_list *dl, struct volume_group *vg)
|
||||
* This calculates the nasty pv_number field
|
||||
* used by LVM1.
|
||||
*/
|
||||
void export_numbers(struct list *pvds, struct volume_group *vg __attribute((unused)))
|
||||
void export_numbers(struct dm_list *pvds, struct volume_group *vg __attribute((unused)))
|
||||
{
|
||||
struct disk_list *dl;
|
||||
int pv_num = 1;
|
||||
|
||||
list_iterate_items(dl, pvds)
|
||||
dm_list_iterate_items(dl, pvds)
|
||||
dl->pvd.pv_number = pv_num++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate vg_disk->pv_act.
|
||||
*/
|
||||
void export_pv_act(struct list *pvds)
|
||||
void export_pv_act(struct dm_list *pvds)
|
||||
{
|
||||
struct disk_list *dl;
|
||||
int act = 0;
|
||||
|
||||
list_iterate_items(dl, pvds)
|
||||
dm_list_iterate_items(dl, pvds)
|
||||
if (dl->pvd.pv_status & PV_ACTIVE)
|
||||
act++;
|
||||
|
||||
list_iterate_items(dl, pvds)
|
||||
dm_list_iterate_items(dl, pvds)
|
||||
dl->vgd.pv_act = act;
|
||||
}
|
||||
|
||||
int export_vg_number(struct format_instance *fid, struct list *pvds,
|
||||
int export_vg_number(struct format_instance *fid, struct dm_list *pvds,
|
||||
const char *vg_name, struct dev_filter *filter)
|
||||
{
|
||||
struct disk_list *dl;
|
||||
int vg_num;
|
||||
|
||||
if (!get_free_vg_number(fid, filter, vg_name, &vg_num)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!get_free_vg_number(fid, filter, vg_name, &vg_num))
|
||||
return_0;
|
||||
|
||||
list_iterate_items(dl, pvds)
|
||||
dm_list_iterate_items(dl, pvds)
|
||||
dl->vgd.vg_number = vg_num;
|
||||
|
||||
return 1;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
@@ -55,7 +55,7 @@ static struct dm_hash_table *_create_lv_maps(struct dm_pool *mem,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list_iterate_items(ll, &vg->lvs) {
|
||||
dm_list_iterate_items(ll, &vg->lvs) {
|
||||
if (ll->lv->status & SNAPSHOT)
|
||||
continue;
|
||||
|
||||
@@ -86,7 +86,7 @@ static int _fill_lv_array(struct lv_map **lvs,
|
||||
|
||||
memset(lvs, 0, sizeof(*lvs) * MAX_LV);
|
||||
|
||||
list_iterate_items(ll, &dl->lvds) {
|
||||
dm_list_iterate_items(ll, &dl->lvds) {
|
||||
if (!(lvm = dm_hash_lookup(maps, strrchr((char *)ll->lvd.lv_name, '/')
|
||||
+ 1))) {
|
||||
log_err("Physical volume (%s) contains an "
|
||||
@@ -105,7 +105,7 @@ static int _fill_lv_array(struct lv_map **lvs,
|
||||
}
|
||||
|
||||
static int _fill_maps(struct dm_hash_table *maps, struct volume_group *vg,
|
||||
struct list *pvds)
|
||||
struct dm_list *pvds)
|
||||
{
|
||||
struct disk_list *dl;
|
||||
struct physical_volume *pv;
|
||||
@@ -113,15 +113,13 @@ static int _fill_maps(struct dm_hash_table *maps, struct volume_group *vg,
|
||||
struct pe_disk *e;
|
||||
uint32_t i, lv_num, le;
|
||||
|
||||
list_iterate_items(dl, pvds) {
|
||||
dm_list_iterate_items(dl, pvds) {
|
||||
pv = find_pv(vg, dl->dev);
|
||||
e = dl->extents;
|
||||
|
||||
/* build an array of lv's for this pv */
|
||||
if (!_fill_lv_array(lvms, maps, dl)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!_fill_lv_array(lvms, maps, dl))
|
||||
return_0;
|
||||
|
||||
for (i = 0; i < dl->pvd.pe_total; i++) {
|
||||
lv_num = e[i].lv_num;
|
||||
@@ -189,10 +187,8 @@ static int _check_maps_are_complete(struct dm_hash_table *maps)
|
||||
for (n = dm_hash_get_first(maps); n; n = dm_hash_get_next(maps, n)) {
|
||||
lvm = (struct lv_map *) dm_hash_get_data(maps, n);
|
||||
|
||||
if (!_check_single_map(lvm)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!_check_single_map(lvm))
|
||||
return_0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -216,10 +212,8 @@ static int _read_linear(struct cmd_context *cmd, struct lv_map *lvm)
|
||||
struct lv_segment *seg;
|
||||
struct segment_type *segtype;
|
||||
|
||||
if (!(segtype = get_segtype_from_string(cmd, "striped"))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(segtype = get_segtype_from_string(cmd, "striped")))
|
||||
return_0;
|
||||
|
||||
while (le < lvm->lv->le_count) {
|
||||
len = _area_length(lvm, le);
|
||||
@@ -234,7 +228,7 @@ static int _read_linear(struct cmd_context *cmd, struct lv_map *lvm)
|
||||
lvm->map[le].pe))
|
||||
return_0;
|
||||
|
||||
list_add(&lvm->lv->segments, &seg->list);
|
||||
dm_list_add(&lvm->lv->segments, &seg->list);
|
||||
|
||||
le += seg->len;
|
||||
}
|
||||
@@ -286,7 +280,7 @@ static int _read_stripes(struct cmd_context *cmd, struct lv_map *lvm)
|
||||
while (first_area_le < total_area_len) {
|
||||
area_len = 1;
|
||||
|
||||
/*
|
||||
/*
|
||||
* Find how many extents are contiguous in all stripes
|
||||
* and so can form part of this segment
|
||||
*/
|
||||
@@ -313,7 +307,7 @@ static int _read_stripes(struct cmd_context *cmd, struct lv_map *lvm)
|
||||
lvm->map[first_area_le + st * total_area_len].pe))
|
||||
return_0;
|
||||
|
||||
list_add(&lvm->lv->segments, &seg->list);
|
||||
dm_list_add(&lvm->lv->segments, &seg->list);
|
||||
|
||||
first_area_le += area_len;
|
||||
}
|
||||
@@ -334,26 +328,22 @@ static int _build_all_segments(struct cmd_context *cmd, struct dm_hash_table *ma
|
||||
|
||||
for (n = dm_hash_get_first(maps); n; n = dm_hash_get_next(maps, n)) {
|
||||
lvm = (struct lv_map *) dm_hash_get_data(maps, n);
|
||||
if (!_build_segments(cmd, lvm)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!_build_segments(cmd, lvm))
|
||||
return_0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int import_extents(struct cmd_context *cmd, struct volume_group *vg,
|
||||
struct list *pvds)
|
||||
struct dm_list *pvds)
|
||||
{
|
||||
int r = 0;
|
||||
struct dm_pool *scratch = dm_pool_create("lvm1 import_extents", 10 * 1024);
|
||||
struct dm_hash_table *maps;
|
||||
|
||||
if (!scratch) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!scratch)
|
||||
return_0;
|
||||
|
||||
if (!(maps = _create_lv_maps(scratch, vg))) {
|
||||
log_err("Couldn't allocate logical volume maps.");
|
||||
@@ -365,10 +355,8 @@ int import_extents(struct cmd_context *cmd, struct volume_group *vg,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!_check_maps_are_complete(maps) && !(vg->status & PARTIAL_VG)) {
|
||||
stack;
|
||||
goto out;
|
||||
}
|
||||
if (!_check_maps_are_complete(maps) && !(vg->status & PARTIAL_VG))
|
||||
goto_out;
|
||||
|
||||
if (!_build_all_segments(cmd, maps)) {
|
||||
log_err("Couldn't build extent segments.");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
@@ -122,10 +122,8 @@ int calculate_extent_count(struct physical_volume *pv, uint32_t extent_size,
|
||||
struct pv_disk *pvd = dm_malloc(sizeof(*pvd));
|
||||
uint32_t end;
|
||||
|
||||
if (!pvd) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!pvd)
|
||||
return_0;
|
||||
|
||||
/*
|
||||
* Guess how many extents will fit, bearing in mind that
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
@@ -19,7 +19,7 @@
|
||||
#include "label.h"
|
||||
#include "metadata.h"
|
||||
#include "xlate.h"
|
||||
#include "lvmcache.h"
|
||||
#include "format1.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
@@ -60,25 +60,27 @@ static int _lvm1_read(struct labeller *l, struct device *dev, void *buf,
|
||||
struct pv_disk *pvd = (struct pv_disk *) buf;
|
||||
struct vg_disk vgd;
|
||||
struct lvmcache_info *info;
|
||||
const char *vgid = NULL;
|
||||
const char *vgid = FMT_LVM1_ORPHAN_VG_NAME;
|
||||
const char *vgname = FMT_LVM1_ORPHAN_VG_NAME;
|
||||
unsigned exported = 0;
|
||||
|
||||
munge_pvd(dev, pvd);
|
||||
|
||||
if (*pvd->vg_name && read_vgd(dev, &vgd, pvd)) {
|
||||
if (*pvd->vg_name) {
|
||||
if (!read_vgd(dev, &vgd, pvd))
|
||||
return_0;
|
||||
vgid = (char *) vgd.vg_uuid;
|
||||
vgname = (char *) pvd->vg_name;
|
||||
exported = pvd->pv_status & VG_EXPORTED;
|
||||
}
|
||||
|
||||
if (!(info = lvmcache_add(l, (char *)pvd->pv_uuid, dev, (char *)pvd->vg_name, vgid,
|
||||
exported))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(info = lvmcache_add(l, (char *)pvd->pv_uuid, dev, vgname, vgid,
|
||||
exported)))
|
||||
return_0;
|
||||
*label = info->label;
|
||||
|
||||
info->device_size = xlate32(pvd->pv_size) << SECTOR_SHIFT;
|
||||
list_init(&info->mdas);
|
||||
dm_list_init(&info->mdas);
|
||||
|
||||
info->status &= ~CACHE_INVALID;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
@@ -26,26 +26,22 @@
|
||||
int get_free_vg_number(struct format_instance *fid, struct dev_filter *filter,
|
||||
const char *candidate_vg, int *result)
|
||||
{
|
||||
struct list all_pvs;
|
||||
struct dm_list all_pvs;
|
||||
struct disk_list *dl;
|
||||
struct dm_pool *mem = dm_pool_create("lvm1 vg_number", 10 * 1024);
|
||||
int numbers[MAX_VG], i, r = 0;
|
||||
|
||||
list_init(&all_pvs);
|
||||
dm_list_init(&all_pvs);
|
||||
|
||||
if (!mem) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!mem)
|
||||
return_0;
|
||||
|
||||
if (!read_pvs_in_vg(fid->fmt, NULL, filter, mem, &all_pvs)) {
|
||||
stack;
|
||||
goto out;
|
||||
}
|
||||
if (!read_pvs_in_vg(fid->fmt, NULL, filter, mem, &all_pvs))
|
||||
goto_out;
|
||||
|
||||
memset(numbers, 0, sizeof(numbers));
|
||||
|
||||
list_iterate_items(dl, &all_pvs) {
|
||||
dm_list_iterate_items(dl, &all_pvs) {
|
||||
if (!*dl->pvd.vg_name || !strcmp((char *)dl->pvd.vg_name, candidate_vg))
|
||||
continue;
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ SOURCES =\
|
||||
pool_label.c
|
||||
|
||||
LIB_SHARED = liblvm2formatpool.so
|
||||
LIB_VERSION = $(LIB_VERSION_LVM)
|
||||
|
||||
include $(top_srcdir)/make.tmpl
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
@@ -19,9 +19,10 @@
|
||||
#include "lvmcache.h"
|
||||
#include "filter.h"
|
||||
#include "xlate.h"
|
||||
|
||||
#include "disk_rep.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
/* FIXME: memcpy might not be portable */
|
||||
#define CPIN_8(x, y, z) {memcpy((x), (y), (z));}
|
||||
#define CPOUT_8(x, y, z) {memcpy((y), (x), (z));}
|
||||
@@ -45,19 +46,17 @@ static int __read_pool_disk(const struct format_type *fmt, struct device *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!read_pool_label(pl, fmt->labeller, dev, buf, NULL)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!read_pool_label(pl, fmt->labeller, dev, buf, NULL))
|
||||
return_0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void _add_pl_to_list(struct list *head, struct pool_list *data)
|
||||
static void _add_pl_to_list(struct dm_list *head, struct pool_list *data)
|
||||
{
|
||||
struct pool_list *pl;
|
||||
|
||||
list_iterate_items(pl, head) {
|
||||
dm_list_iterate_items(pl, head) {
|
||||
if (id_equal(&data->pv_uuid, &pl->pv_uuid)) {
|
||||
char uuid[ID_LEN + 7] __attribute((aligned(8)));
|
||||
|
||||
@@ -71,11 +70,11 @@ static void _add_pl_to_list(struct list *head, struct pool_list *data)
|
||||
}
|
||||
log_very_verbose("Duplicate PV %s - using md %s",
|
||||
uuid, dev_name(data->dev));
|
||||
list_del(&pl->list);
|
||||
dm_list_del(&pl->list);
|
||||
break;
|
||||
}
|
||||
}
|
||||
list_add(head, &data->list);
|
||||
dm_list_add(head, &data->list);
|
||||
}
|
||||
|
||||
int read_pool_label(struct pool_list *pl, struct labeller *l,
|
||||
@@ -98,15 +97,13 @@ int read_pool_label(struct pool_list *pl, struct labeller *l,
|
||||
log_debug("Calculated uuid %s for %s", uuid, pd->pl_pool_name);
|
||||
|
||||
if (!(info = lvmcache_add(l, (char *) &pvid, dev, pd->pl_pool_name,
|
||||
(char *) &vgid, 0))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
(char *) &vgid, 0)))
|
||||
return_0;
|
||||
if (label)
|
||||
*label = info->label;
|
||||
|
||||
info->device_size = xlate32_be(pd->pl_blocks) << SECTOR_SHIFT;
|
||||
list_init(&info->mdas);
|
||||
dm_list_init(&info->mdas);
|
||||
|
||||
info->status &= ~CACHE_INVALID;
|
||||
|
||||
@@ -239,7 +236,7 @@ void get_pool_uuid(char *uuid, uint64_t poolid, uint32_t spid, uint32_t devid)
|
||||
}
|
||||
|
||||
static int _read_vg_pds(const struct format_type *fmt, struct dm_pool *mem,
|
||||
struct lvmcache_vginfo *vginfo, struct list *head,
|
||||
struct lvmcache_vginfo *vginfo, struct dm_list *head,
|
||||
uint32_t *devcount)
|
||||
{
|
||||
struct lvmcache_info *info;
|
||||
@@ -252,12 +249,10 @@ static int _read_vg_pds(const struct format_type *fmt, struct dm_pool *mem,
|
||||
|
||||
/* FIXME: maybe should return a different error in memory
|
||||
* allocation failure */
|
||||
if (!(tmpmem = dm_pool_create("pool read_vg", 512))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(tmpmem = dm_pool_create("pool read_vg", 512)))
|
||||
return_0;
|
||||
|
||||
list_iterate_items(info, &vginfo->infos) {
|
||||
dm_list_iterate_items(info, &vginfo->infos) {
|
||||
if (info->dev &&
|
||||
!(pl = read_pool_disk(fmt, info->dev, mem, vginfo->vgname)))
|
||||
break;
|
||||
@@ -304,7 +299,7 @@ static int _read_vg_pds(const struct format_type *fmt, struct dm_pool *mem,
|
||||
}
|
||||
|
||||
int read_pool_pds(const struct format_type *fmt, const char *vg_name,
|
||||
struct dm_pool *mem, struct list *pdhead)
|
||||
struct dm_pool *mem, struct dm_list *pdhead)
|
||||
{
|
||||
struct lvmcache_vginfo *vginfo;
|
||||
uint32_t totaldevs;
|
||||
@@ -322,7 +317,7 @@ int read_pool_pds(const struct format_type *fmt, const char *vg_name,
|
||||
* If we found all the devices we were
|
||||
* expecting, return success
|
||||
*/
|
||||
if (list_size(pdhead) == totaldevs)
|
||||
if (dm_list_size(pdhead) == totaldevs)
|
||||
return 1;
|
||||
|
||||
/*
|
||||
@@ -334,7 +329,7 @@ int read_pool_pds(const struct format_type *fmt, const char *vg_name,
|
||||
}
|
||||
}
|
||||
/* Failed */
|
||||
list_init(pdhead);
|
||||
dm_list_init(pdhead);
|
||||
|
||||
full_scan++;
|
||||
if (full_scan > 1) {
|
||||
@@ -354,20 +349,16 @@ struct pool_list *read_pool_disk(const struct format_type *fmt,
|
||||
{
|
||||
struct pool_list *pl;
|
||||
|
||||
if (!dev_open(dev)) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
if (!dev_open(dev))
|
||||
return_NULL;
|
||||
|
||||
if (!(pl = dm_pool_zalloc(mem, sizeof(*pl)))) {
|
||||
log_error("Unable to allocate pool list structure");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!__read_pool_disk(fmt, dev, mem, pl, vg_name)) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
if (!__read_pool_disk(fmt, dev, mem, pl, vg_name))
|
||||
return_NULL;
|
||||
|
||||
if (!dev_close(dev))
|
||||
stack;
|
||||
|
||||
@@ -106,7 +106,7 @@ struct pool_disk {
|
||||
};
|
||||
|
||||
struct pool_list {
|
||||
struct list list;
|
||||
struct dm_list list;
|
||||
struct pool_disk pd;
|
||||
struct physical_volume *pv;
|
||||
struct id pv_uuid;
|
||||
@@ -137,18 +137,18 @@ int read_pool_label(struct pool_list *pl, struct labeller *l,
|
||||
void pool_label_out(struct pool_disk *pl, void *buf);
|
||||
void pool_label_in(struct pool_disk *pl, void *buf);
|
||||
void get_pool_uuid(char *uuid, uint64_t poolid, uint32_t spid, uint32_t devid);
|
||||
int import_pool_vg(struct volume_group *vg, struct dm_pool *mem, struct list *pls);
|
||||
int import_pool_vg(struct volume_group *vg, struct dm_pool *mem, struct dm_list *pls);
|
||||
int import_pool_lvs(struct volume_group *vg, struct dm_pool *mem,
|
||||
struct list *pls);
|
||||
struct dm_list *pls);
|
||||
int import_pool_pvs(const struct format_type *fmt, struct volume_group *vg,
|
||||
struct list *pvs, struct dm_pool *mem, struct list *pls);
|
||||
struct dm_list *pvs, struct dm_pool *mem, struct dm_list *pls);
|
||||
int import_pool_pv(const struct format_type *fmt, struct dm_pool *mem,
|
||||
struct volume_group *vg, struct physical_volume *pv,
|
||||
struct pool_list *pl);
|
||||
int import_pool_segments(struct list *lvs, struct dm_pool *mem,
|
||||
int import_pool_segments(struct dm_list *lvs, struct dm_pool *mem,
|
||||
struct user_subpool *usp, int sp_count);
|
||||
int read_pool_pds(const struct format_type *fmt, const char *vgname,
|
||||
struct dm_pool *mem, struct list *head);
|
||||
struct dm_pool *mem, struct dm_list *head);
|
||||
struct pool_list *read_pool_disk(const struct format_type *fmt,
|
||||
struct device *dev, struct dm_pool *mem,
|
||||
const char *vg_name);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
@@ -24,10 +24,8 @@
|
||||
#include "format_pool.h"
|
||||
#include "pool_label.h"
|
||||
|
||||
#define FMT_POOL_NAME "pool"
|
||||
|
||||
/* Must be called after pvs are imported */
|
||||
static struct user_subpool *_build_usp(struct list *pls, struct dm_pool *mem,
|
||||
static struct user_subpool *_build_usp(struct dm_list *pls, struct dm_pool *mem,
|
||||
int *sps)
|
||||
{
|
||||
struct pool_list *pl;
|
||||
@@ -38,7 +36,7 @@ static struct user_subpool *_build_usp(struct list *pls, struct dm_pool *mem,
|
||||
* FIXME: Need to do some checks here - I'm tempted to add a
|
||||
* user_pool structure and build the entire thing to check against.
|
||||
*/
|
||||
list_iterate_items(pl, pls) {
|
||||
dm_list_iterate_items(pl, pls) {
|
||||
*sps = pl->pd.pl_subpools;
|
||||
if (!usp && (!(usp = dm_pool_zalloc(mem, sizeof(*usp) * (*sps))))) {
|
||||
log_error("Unable to allocate %d subpool structures",
|
||||
@@ -102,7 +100,7 @@ static int _check_usp(char *vgname, struct user_subpool *usp, int sp_count)
|
||||
|
||||
static struct volume_group *_build_vg_from_pds(struct format_instance
|
||||
*fid, struct dm_pool *mem,
|
||||
struct list *pds)
|
||||
struct dm_list *pds)
|
||||
{
|
||||
struct dm_pool *smem = fid->fmt->cmd->mem;
|
||||
struct volume_group *vg = NULL;
|
||||
@@ -124,48 +122,36 @@ static struct volume_group *_build_vg_from_pds(struct format_instance
|
||||
vg->snapshot_count = 0;
|
||||
vg->seqno = 1;
|
||||
vg->system_id = NULL;
|
||||
list_init(&vg->pvs);
|
||||
list_init(&vg->lvs);
|
||||
list_init(&vg->tags);
|
||||
dm_list_init(&vg->pvs);
|
||||
dm_list_init(&vg->lvs);
|
||||
dm_list_init(&vg->tags);
|
||||
|
||||
if (!import_pool_vg(vg, smem, pds)) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
if (!import_pool_vg(vg, smem, pds))
|
||||
return_NULL;
|
||||
|
||||
if (!import_pool_pvs(fid->fmt, vg, &vg->pvs, smem, pds)) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
if (!import_pool_pvs(fid->fmt, vg, &vg->pvs, smem, pds))
|
||||
return_NULL;
|
||||
|
||||
if (!import_pool_lvs(vg, smem, pds)) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
if (!import_pool_lvs(vg, smem, pds))
|
||||
return_NULL;
|
||||
|
||||
/*
|
||||
* I need an intermediate subpool structure that contains all the
|
||||
* relevant info for this. Then i can iterate through the subpool
|
||||
* structures for checking, and create the segments
|
||||
*/
|
||||
if (!(usp = _build_usp(pds, mem, &sp_count))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
if (!(usp = _build_usp(pds, mem, &sp_count)))
|
||||
return_NULL;
|
||||
|
||||
/*
|
||||
* check the subpool structures - we can't handle partial VGs in
|
||||
* the pool format, so this will error out if we're missing PVs
|
||||
*/
|
||||
if (!_check_usp(vg->name, usp, sp_count)) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
if (!_check_usp(vg->name, usp, sp_count))
|
||||
return_NULL;
|
||||
|
||||
if (!import_pool_segments(&vg->lvs, smem, usp, sp_count)) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
if (!import_pool_segments(&vg->lvs, smem, usp, sp_count))
|
||||
return_NULL;
|
||||
|
||||
return vg;
|
||||
}
|
||||
@@ -175,32 +161,26 @@ static struct volume_group *_pool_vg_read(struct format_instance *fid,
|
||||
struct metadata_area *mda __attribute((unused)))
|
||||
{
|
||||
struct dm_pool *mem = dm_pool_create("pool vg_read", 1024);
|
||||
struct list pds;
|
||||
struct dm_list pds;
|
||||
struct volume_group *vg = NULL;
|
||||
|
||||
list_init(&pds);
|
||||
dm_list_init(&pds);
|
||||
|
||||
/* We can safely ignore the mda passed in */
|
||||
|
||||
if (!mem) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
if (!mem)
|
||||
return_NULL;
|
||||
|
||||
/* Strip dev_dir if present */
|
||||
vg_name = strip_dir(vg_name, fid->fmt->cmd->dev_dir);
|
||||
|
||||
/* Read all the pvs in the vg */
|
||||
if (!read_pool_pds(fid->fmt, vg_name, mem, &pds)) {
|
||||
stack;
|
||||
goto out;
|
||||
}
|
||||
if (!read_pool_pds(fid->fmt, vg_name, mem, &pds))
|
||||
goto_out;
|
||||
|
||||
/* Do the rest of the vg stuff */
|
||||
if (!(vg = _build_vg_from_pds(fid, mem, &pds))) {
|
||||
stack;
|
||||
goto out;
|
||||
}
|
||||
if (!(vg = _build_vg_from_pds(fid, mem, &pds)))
|
||||
goto_out;
|
||||
|
||||
out:
|
||||
dm_pool_destroy(mem);
|
||||
@@ -213,7 +193,7 @@ static int _pool_pv_setup(const struct format_type *fmt __attribute((unused)),
|
||||
uint32_t extent_size __attribute((unused)),
|
||||
int pvmetadatacopies __attribute((unused)),
|
||||
uint64_t pvmetadatasize __attribute((unused)),
|
||||
struct list *mdas __attribute((unused)),
|
||||
struct dm_list *mdas __attribute((unused)),
|
||||
struct physical_volume *pv __attribute((unused)),
|
||||
struct volume_group *vg __attribute((unused)))
|
||||
{
|
||||
@@ -222,7 +202,7 @@ static int _pool_pv_setup(const struct format_type *fmt __attribute((unused)),
|
||||
|
||||
static int _pool_pv_read(const struct format_type *fmt, const char *pv_name,
|
||||
struct physical_volume *pv,
|
||||
struct list *mdas __attribute((unused)))
|
||||
struct dm_list *mdas __attribute((unused)))
|
||||
{
|
||||
struct dm_pool *mem = dm_pool_create("pool pv_read", 1024);
|
||||
struct pool_list *pl;
|
||||
@@ -231,30 +211,22 @@ static int _pool_pv_read(const struct format_type *fmt, const char *pv_name,
|
||||
|
||||
log_very_verbose("Reading physical volume data %s from disk", pv_name);
|
||||
|
||||
if (!mem) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!mem)
|
||||
return_0;
|
||||
|
||||
if (!(dev = dev_cache_get(pv_name, fmt->cmd->filter))) {
|
||||
stack;
|
||||
goto out;
|
||||
}
|
||||
if (!(dev = dev_cache_get(pv_name, fmt->cmd->filter)))
|
||||
goto_out;
|
||||
|
||||
/*
|
||||
* I need to read the disk and populate a pv structure here
|
||||
* I'll probably need to abstract some of this later for the
|
||||
* vg_read code
|
||||
*/
|
||||
if (!(pl = read_pool_disk(fmt, dev, mem, NULL))) {
|
||||
stack;
|
||||
goto out;
|
||||
}
|
||||
if (!(pl = read_pool_disk(fmt, dev, mem, NULL)))
|
||||
goto_out;
|
||||
|
||||
if (!import_pool_pv(fmt, fmt->cmd->mem, NULL, pv, pl)) {
|
||||
stack;
|
||||
goto out;
|
||||
}
|
||||
if (!import_pool_pv(fmt, fmt->cmd->mem, NULL, pv, pl))
|
||||
goto_out;
|
||||
|
||||
pv->fmt = fmt;
|
||||
|
||||
@@ -286,7 +258,7 @@ static struct format_instance *_pool_create_instance(const struct format_type *f
|
||||
}
|
||||
|
||||
fid->fmt = fmt;
|
||||
list_init(&fid->metadata_areas);
|
||||
dm_list_init(&fid->metadata_areas);
|
||||
|
||||
/* Define a NULL metadata area */
|
||||
if (!(mda = dm_pool_zalloc(fmt->cmd->mem, sizeof(*mda)))) {
|
||||
@@ -298,7 +270,7 @@ static struct format_instance *_pool_create_instance(const struct format_type *f
|
||||
|
||||
mda->ops = &_metadata_format_pool_ops;
|
||||
mda->metadata_locn = NULL;
|
||||
list_add(&fid->metadata_areas, &mda->list);
|
||||
dm_list_add(&fid->metadata_areas, &mda->list);
|
||||
|
||||
return fid;
|
||||
}
|
||||
@@ -342,6 +314,7 @@ struct format_type *init_format(struct cmd_context *cmd)
|
||||
fmt->ops = &_format_pool_ops;
|
||||
fmt->name = FMT_POOL_NAME;
|
||||
fmt->alias = NULL;
|
||||
fmt->orphan_vg_name = FMT_POOL_ORPHAN_VG_NAME;
|
||||
fmt->features = 0;
|
||||
fmt->private = NULL;
|
||||
|
||||
|
||||
@@ -18,6 +18,9 @@
|
||||
|
||||
#include "metadata.h"
|
||||
|
||||
#define FMT_POOL_NAME "pool"
|
||||
#define FMT_POOL_ORPHAN_VG_NAME ORPHAN_VG_NAME(FMT_POOL_NAME)
|
||||
|
||||
#ifdef POOL_INTERNAL
|
||||
struct format_type *init_pool_format(struct cmd_context *cmd);
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
@@ -28,14 +28,15 @@
|
||||
|
||||
/* This file contains only imports at the moment... */
|
||||
|
||||
int import_pool_vg(struct volume_group *vg, struct dm_pool *mem, struct list *pls)
|
||||
int import_pool_vg(struct volume_group *vg, struct dm_pool *mem, struct dm_list *pls)
|
||||
{
|
||||
struct pool_list *pl;
|
||||
|
||||
list_iterate_items(pl, pls) {
|
||||
dm_list_iterate_items(pl, pls) {
|
||||
vg->extent_count +=
|
||||
((pl->pd.pl_blocks) / POOL_PE_SIZE);
|
||||
|
||||
vg->free_count = vg->extent_count;
|
||||
vg->pv_count++;
|
||||
|
||||
if (vg->name)
|
||||
@@ -45,7 +46,6 @@ int import_pool_vg(struct volume_group *vg, struct dm_pool *mem, struct list *pl
|
||||
get_pool_vg_uuid(&vg->id, &pl->pd);
|
||||
vg->extent_size = POOL_PE_SIZE;
|
||||
vg->status |= LVM_READ | LVM_WRITE | CLUSTERED | SHARED;
|
||||
vg->free_count = vg->extent_count;
|
||||
vg->max_lv = 1;
|
||||
vg->max_pv = POOL_MAX_DEVICES;
|
||||
vg->alloc = ALLOC_NORMAL;
|
||||
@@ -55,7 +55,7 @@ int import_pool_vg(struct volume_group *vg, struct dm_pool *mem, struct list *pl
|
||||
return 1;
|
||||
}
|
||||
|
||||
int import_pool_lvs(struct volume_group *vg, struct dm_pool *mem, struct list *pls)
|
||||
int import_pool_lvs(struct volume_group *vg, struct dm_pool *mem, struct dm_list *pls)
|
||||
{
|
||||
struct pool_list *pl;
|
||||
struct lv_list *lvl = dm_pool_zalloc(mem, sizeof(*lvl));
|
||||
@@ -80,20 +80,19 @@ int import_pool_lvs(struct volume_group *vg, struct dm_pool *mem, struct list *p
|
||||
lv->le_count = 0;
|
||||
lv->read_ahead = vg->cmd->default_settings.read_ahead;
|
||||
lv->snapshot = NULL;
|
||||
list_init(&lv->snapshot_segs);
|
||||
list_init(&lv->segments);
|
||||
list_init(&lv->tags);
|
||||
dm_list_init(&lv->snapshot_segs);
|
||||
dm_list_init(&lv->segments);
|
||||
dm_list_init(&lv->tags);
|
||||
dm_list_init(&lv->segs_using_this_lv);
|
||||
|
||||
list_iterate_items(pl, pls) {
|
||||
dm_list_iterate_items(pl, pls) {
|
||||
lv->size += pl->pd.pl_blocks;
|
||||
|
||||
if (lv->name)
|
||||
continue;
|
||||
|
||||
if (!(lv->name = dm_pool_strdup(mem, pl->pd.pl_pool_name))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(lv->name = dm_pool_strdup(mem, pl->pd.pl_pool_name)))
|
||||
return_0;
|
||||
|
||||
get_pool_lv_uuid(lv->lvid.id, &pl->pd);
|
||||
log_debug("Calculated lv uuid for lv %s: %s", lv->name,
|
||||
@@ -110,26 +109,26 @@ int import_pool_lvs(struct volume_group *vg, struct dm_pool *mem, struct list *p
|
||||
lv->minor = -1;
|
||||
}
|
||||
lv->snapshot = NULL;
|
||||
list_init(&lv->snapshot_segs);
|
||||
list_init(&lv->segments);
|
||||
list_init(&lv->tags);
|
||||
dm_list_init(&lv->snapshot_segs);
|
||||
dm_list_init(&lv->segments);
|
||||
dm_list_init(&lv->tags);
|
||||
}
|
||||
|
||||
lv->le_count = lv->size / POOL_PE_SIZE;
|
||||
lvl->lv = lv;
|
||||
list_add(&vg->lvs, &lvl->list);
|
||||
dm_list_add(&vg->lvs, &lvl->list);
|
||||
vg->lv_count++;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int import_pool_pvs(const struct format_type *fmt, struct volume_group *vg,
|
||||
struct list *pvs, struct dm_pool *mem, struct list *pls)
|
||||
struct dm_list *pvs, struct dm_pool *mem, struct dm_list *pls)
|
||||
{
|
||||
struct pv_list *pvl;
|
||||
struct pool_list *pl;
|
||||
|
||||
list_iterate_items(pl, pls) {
|
||||
dm_list_iterate_items(pl, pls) {
|
||||
if (!(pvl = dm_pool_zalloc(mem, sizeof(*pvl)))) {
|
||||
log_error("Unable to allocate pv list structure");
|
||||
return 0;
|
||||
@@ -144,7 +143,7 @@ int import_pool_pvs(const struct format_type *fmt, struct volume_group *vg,
|
||||
pl->pv = pvl->pv;
|
||||
pvl->mdas = NULL;
|
||||
pvl->pe_ranges = NULL;
|
||||
list_add(pvs, &pvl->list);
|
||||
dm_list_add(pvs, &pvl->list);
|
||||
}
|
||||
|
||||
return 1;
|
||||
@@ -166,21 +165,21 @@ int import_pool_pv(const struct format_type *fmt, struct dm_pool *mem,
|
||||
log_error("Unable to duplicate vg_name string");
|
||||
return 0;
|
||||
}
|
||||
memcpy(&pv->vgid, &vg->id, sizeof(vg->id));
|
||||
if (vg != NULL)
|
||||
memcpy(&pv->vgid, &vg->id, sizeof(vg->id));
|
||||
pv->status = 0;
|
||||
pv->size = pd->pl_blocks;
|
||||
pv->pe_size = POOL_PE_SIZE;
|
||||
pv->pe_start = POOL_PE_START;
|
||||
pv->pe_count = pv->size / POOL_PE_SIZE;
|
||||
pv->pe_alloc_count = 0;
|
||||
pv->pe_align = 0;
|
||||
|
||||
list_init(&pv->tags);
|
||||
list_init(&pv->segments);
|
||||
dm_list_init(&pv->tags);
|
||||
dm_list_init(&pv->segments);
|
||||
|
||||
if (!alloc_pv_segment_whole_pv(mem, pv)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!alloc_pv_segment_whole_pv(mem, pv))
|
||||
return_0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -215,12 +214,10 @@ static int _add_stripe_seg(struct dm_pool *mem,
|
||||
area_len = (usp->devs[0].blocks) / POOL_PE_SIZE;
|
||||
|
||||
if (!(segtype = get_segtype_from_string(lv->vg->cmd,
|
||||
"striped"))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
"striped")))
|
||||
return_0;
|
||||
|
||||
if (!(seg = alloc_lv_segment(mem, segtype, lv, *le_cur,
|
||||
if (!(seg = alloc_lv_segment(mem, segtype, lv, *le_cur,
|
||||
area_len * usp->num_devs, 0,
|
||||
usp->striping, NULL, usp->num_devs,
|
||||
area_len, 0, 0, 0))) {
|
||||
@@ -229,15 +226,13 @@ static int _add_stripe_seg(struct dm_pool *mem,
|
||||
}
|
||||
|
||||
for (j = 0; j < usp->num_devs; j++)
|
||||
if (!set_lv_segment_area_pv(seg, j, usp->devs[j].pv, 0)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!set_lv_segment_area_pv(seg, j, usp->devs[j].pv, 0))
|
||||
return_0;
|
||||
|
||||
/* add the subpool type to the segment tag list */
|
||||
str_list_add(mem, &seg->tags, _cvt_sptype(usp->type));
|
||||
|
||||
list_add(&lv->segments, &seg->list);
|
||||
dm_list_add(&lv->segments, &seg->list);
|
||||
|
||||
*le_cur += seg->len;
|
||||
|
||||
@@ -253,10 +248,8 @@ static int _add_linear_seg(struct dm_pool *mem,
|
||||
unsigned j;
|
||||
uint32_t area_len;
|
||||
|
||||
if (!(segtype = get_segtype_from_string(lv->vg->cmd, "striped"))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(segtype = get_segtype_from_string(lv->vg->cmd, "striped")))
|
||||
return_0;
|
||||
|
||||
for (j = 0; j < usp->num_devs; j++) {
|
||||
area_len = (usp->devs[j].blocks) / POOL_PE_SIZE;
|
||||
@@ -273,11 +266,9 @@ static int _add_linear_seg(struct dm_pool *mem,
|
||||
/* add the subpool type to the segment tag list */
|
||||
str_list_add(mem, &seg->tags, _cvt_sptype(usp->type));
|
||||
|
||||
if (!set_lv_segment_area_pv(seg, 0, usp->devs[j].pv, 0)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
list_add(&lv->segments, &seg->list);
|
||||
if (!set_lv_segment_area_pv(seg, 0, usp->devs[j].pv, 0))
|
||||
return_0;
|
||||
dm_list_add(&lv->segments, &seg->list);
|
||||
|
||||
*le_cur += seg->len;
|
||||
}
|
||||
@@ -285,7 +276,7 @@ static int _add_linear_seg(struct dm_pool *mem,
|
||||
return 1;
|
||||
}
|
||||
|
||||
int import_pool_segments(struct list *lvs, struct dm_pool *mem,
|
||||
int import_pool_segments(struct dm_list *lvs, struct dm_pool *mem,
|
||||
struct user_subpool *usp, int subpools)
|
||||
{
|
||||
struct lv_list *lvl;
|
||||
@@ -293,7 +284,7 @@ int import_pool_segments(struct list *lvs, struct dm_pool *mem,
|
||||
uint32_t le_cur = 0;
|
||||
int i;
|
||||
|
||||
list_iterate_items(lvl, lvs) {
|
||||
dm_list_iterate_items(lvl, lvs) {
|
||||
lv = lvl->lv;
|
||||
|
||||
if (lv->status & SNAPSHOT)
|
||||
@@ -301,15 +292,11 @@ int import_pool_segments(struct list *lvs, struct dm_pool *mem,
|
||||
|
||||
for (i = 0; i < subpools; i++) {
|
||||
if (usp[i].striping) {
|
||||
if (!_add_stripe_seg(mem, &usp[i], lv, &le_cur)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!_add_stripe_seg(mem, &usp[i], lv, &le_cur))
|
||||
return_0;
|
||||
} else {
|
||||
if (!_add_linear_seg(mem, &usp[i], lv, &le_cur)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!_add_linear_seg(mem, &usp[i], lv, &le_cur))
|
||||
return_0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
@@ -48,7 +48,7 @@
|
||||
* with the least recent at the head.
|
||||
*/
|
||||
struct archive_file {
|
||||
struct list list;
|
||||
struct dm_list list;
|
||||
|
||||
char *path;
|
||||
uint32_t index;
|
||||
@@ -87,24 +87,24 @@ static int _split_vg(const char *filename, char *vgname, size_t vg_size,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void _insert_archive_file(struct list *head, struct archive_file *b)
|
||||
static void _insert_archive_file(struct dm_list *head, struct archive_file *b)
|
||||
{
|
||||
struct archive_file *bf = NULL;
|
||||
|
||||
if (list_empty(head)) {
|
||||
list_add(head, &b->list);
|
||||
if (dm_list_empty(head)) {
|
||||
dm_list_add(head, &b->list);
|
||||
return;
|
||||
}
|
||||
|
||||
/* index reduces through list */
|
||||
list_iterate_items(bf, head) {
|
||||
dm_list_iterate_items(bf, head) {
|
||||
if (b->index > bf->index) {
|
||||
list_add(&bf->list, &b->list);
|
||||
dm_list_add(&bf->list, &b->list);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
list_add_h(&bf->list, &b->list);
|
||||
dm_list_add_h(&bf->list, &b->list);
|
||||
}
|
||||
|
||||
static char *_join_file_to_dir(struct dm_pool *mem, const char *dir, const char *name)
|
||||
@@ -113,10 +113,8 @@ static char *_join_file_to_dir(struct dm_pool *mem, const char *dir, const char
|
||||
!dm_pool_grow_object(mem, dir, strlen(dir)) ||
|
||||
!dm_pool_grow_object(mem, "/", 1) ||
|
||||
!dm_pool_grow_object(mem, name, strlen(name)) ||
|
||||
!dm_pool_grow_object(mem, "\0", 1)) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
!dm_pool_grow_object(mem, "\0", 1))
|
||||
return_NULL;
|
||||
|
||||
return dm_pool_end_object(mem);
|
||||
}
|
||||
@@ -124,7 +122,7 @@ static char *_join_file_to_dir(struct dm_pool *mem, const char *dir, const char
|
||||
/*
|
||||
* Returns a list of archive_files.
|
||||
*/
|
||||
static struct list *_scan_archive(struct dm_pool *mem,
|
||||
static struct dm_list *_scan_archive(struct dm_pool *mem,
|
||||
const char *vgname, const char *dir)
|
||||
{
|
||||
int i, count;
|
||||
@@ -132,14 +130,12 @@ static struct list *_scan_archive(struct dm_pool *mem,
|
||||
char vgname_found[64], *path;
|
||||
struct dirent **dirent;
|
||||
struct archive_file *af;
|
||||
struct list *results;
|
||||
struct dm_list *results;
|
||||
|
||||
if (!(results = dm_pool_alloc(mem, sizeof(*results)))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
if (!(results = dm_pool_alloc(mem, sizeof(*results))))
|
||||
return_NULL;
|
||||
|
||||
list_init(results);
|
||||
dm_list_init(results);
|
||||
|
||||
/* Sort fails beyond 5-digit indexes */
|
||||
if ((count = scandir(dir, &dirent, NULL, alphasort)) < 0) {
|
||||
@@ -161,10 +157,8 @@ static struct list *_scan_archive(struct dm_pool *mem,
|
||||
if (strcmp(vgname, vgname_found))
|
||||
continue;
|
||||
|
||||
if (!(path = _join_file_to_dir(mem, dir, dirent[i]->d_name))) {
|
||||
stack;
|
||||
goto out;
|
||||
}
|
||||
if (!(path = _join_file_to_dir(mem, dir, dirent[i]->d_name)))
|
||||
goto_out;
|
||||
|
||||
/*
|
||||
* Create a new archive_file.
|
||||
@@ -192,7 +186,7 @@ static struct list *_scan_archive(struct dm_pool *mem,
|
||||
return results;
|
||||
}
|
||||
|
||||
static void _remove_expired(struct list *archives, uint32_t archives_size,
|
||||
static void _remove_expired(struct dm_list *archives, uint32_t archives_size,
|
||||
uint32_t retain_days, uint32_t min_archive)
|
||||
{
|
||||
struct archive_file *bf;
|
||||
@@ -208,7 +202,7 @@ static void _remove_expired(struct list *archives, uint32_t archives_size,
|
||||
retain_time = time(NULL) - (time_t) retain_days *SECS_PER_DAY;
|
||||
|
||||
/* Assume list is ordered newest first (by index) */
|
||||
list_iterate_back_items(bf, archives) {
|
||||
dm_list_iterate_back_items(bf, archives) {
|
||||
/* Get the mtime of the file and unlink if too old */
|
||||
if (stat(bf->path, &sb)) {
|
||||
log_sys_error("stat", bf->path);
|
||||
@@ -237,7 +231,7 @@ int archive_vg(struct volume_group *vg,
|
||||
struct archive_file *last;
|
||||
FILE *fp = NULL;
|
||||
char temp_file[PATH_MAX], archive_name[PATH_MAX];
|
||||
struct list *archives;
|
||||
struct dm_list *archives;
|
||||
|
||||
/*
|
||||
* Write the vg out to a temporary file.
|
||||
@@ -255,10 +249,9 @@ int archive_vg(struct volume_group *vg,
|
||||
}
|
||||
|
||||
if (!text_vg_export_file(vg, desc, fp)) {
|
||||
stack;
|
||||
if (fclose(fp))
|
||||
log_sys_error("fclose", temp_file);
|
||||
return 0;
|
||||
return_0;
|
||||
}
|
||||
|
||||
if (lvm_fclose(fp, temp_file))
|
||||
@@ -267,15 +260,13 @@ int archive_vg(struct volume_group *vg,
|
||||
/*
|
||||
* Now we want to rename this file to <vg>_index.vg.
|
||||
*/
|
||||
if (!(archives = _scan_archive(vg->cmd->mem, vg->name, dir))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(archives = _scan_archive(vg->cmd->mem, vg->name, dir)))
|
||||
return_0;
|
||||
|
||||
if (list_empty(archives))
|
||||
if (dm_list_empty(archives))
|
||||
ix = 0;
|
||||
else {
|
||||
last = list_item(list_first(archives), struct archive_file);
|
||||
last = dm_list_item(dm_list_first(archives), struct archive_file);
|
||||
ix = last->index + 1;
|
||||
}
|
||||
|
||||
@@ -295,7 +286,7 @@ int archive_vg(struct volume_group *vg,
|
||||
if (!renamed)
|
||||
log_error("Archive rename failed for %s", temp_file);
|
||||
|
||||
_remove_expired(archives, list_size(archives) + renamed, retain_days,
|
||||
_remove_expired(archives, dm_list_size(archives) + renamed, retain_days,
|
||||
min_archive);
|
||||
|
||||
return 1;
|
||||
@@ -340,18 +331,16 @@ static void _display_archive(struct cmd_context *cmd, struct archive_file *af)
|
||||
|
||||
int archive_list(struct cmd_context *cmd, const char *dir, const char *vgname)
|
||||
{
|
||||
struct list *archives;
|
||||
struct dm_list *archives;
|
||||
struct archive_file *af;
|
||||
|
||||
if (!(archives = _scan_archive(cmd->mem, vgname, dir))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(archives = _scan_archive(cmd->mem, vgname, dir)))
|
||||
return_0;
|
||||
|
||||
if (list_empty(archives))
|
||||
if (dm_list_empty(archives))
|
||||
log_print("No archives found in %s.", dir);
|
||||
|
||||
list_iterate_back_items(af, archives)
|
||||
dm_list_iterate_back_items(af, archives)
|
||||
_display_archive(cmd, af);
|
||||
|
||||
dm_pool_free(cmd->mem, archives);
|
||||
@@ -379,10 +368,8 @@ int backup_list(struct cmd_context *cmd, const char *dir, const char *vgname)
|
||||
{
|
||||
struct archive_file af;
|
||||
|
||||
if (!(af.path = _join_file_to_dir(cmd->mem, dir, vgname))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(af.path = _join_file_to_dir(cmd->mem, dir, vgname)))
|
||||
return_0;
|
||||
|
||||
if (path_exists(af.path))
|
||||
_display_archive(cmd, &af);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
@@ -78,17 +78,13 @@ static char *_build_desc(struct dm_pool *mem, const char *line, int before)
|
||||
size_t len = strlen(line) + 32;
|
||||
char *buffer;
|
||||
|
||||
if (!(buffer = dm_pool_zalloc(mem, strlen(line) + 32))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
if (!(buffer = dm_pool_zalloc(mem, strlen(line) + 32)))
|
||||
return_NULL;
|
||||
|
||||
if (snprintf(buffer, len,
|
||||
"Created %s executing '%s'",
|
||||
before ? "*before*" : "*after*", line) < 0) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
before ? "*before*" : "*after*", line) < 0)
|
||||
return_NULL;
|
||||
|
||||
return buffer;
|
||||
}
|
||||
@@ -97,10 +93,8 @@ static int __archive(struct volume_group *vg)
|
||||
{
|
||||
char *desc;
|
||||
|
||||
if (!(desc = _build_desc(vg->cmd->mem, vg->cmd->cmd_line, 1))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(desc = _build_desc(vg->cmd->mem, vg->cmd->cmd_line, 1)))
|
||||
return_0;
|
||||
|
||||
return archive_vg(vg, vg->cmd->archive_params->dir, desc,
|
||||
vg->cmd->archive_params->keep_days,
|
||||
@@ -121,9 +115,9 @@ int archive(struct volume_group *vg)
|
||||
return 0;
|
||||
|
||||
/* Trap a read-only file system */
|
||||
if ((access(vg->cmd->archive_params->dir, R_OK | W_OK | X_OK) == -1) &&
|
||||
if ((access(vg->cmd->archive_params->dir, R_OK | W_OK | X_OK) == -1) &&
|
||||
(errno == EROFS))
|
||||
return 0;
|
||||
return 0;
|
||||
|
||||
log_verbose("Archiving volume group \"%s\" metadata (seqno %u).", vg->name,
|
||||
vg->seqno);
|
||||
@@ -140,10 +134,8 @@ int archive_display(struct cmd_context *cmd, const char *vg_name)
|
||||
{
|
||||
int r1, r2;
|
||||
|
||||
init_partial(1);
|
||||
r1 = archive_list(cmd, cmd->archive_params->dir, vg_name);
|
||||
r2 = backup_list(cmd, cmd->backup_params->dir, vg_name);
|
||||
init_partial(0);
|
||||
|
||||
return r1 && r2;
|
||||
}
|
||||
@@ -152,9 +144,7 @@ int archive_display_file(struct cmd_context *cmd, const char *file)
|
||||
{
|
||||
int r;
|
||||
|
||||
init_partial(1);
|
||||
r = archive_list_file(cmd, file);
|
||||
init_partial(0);
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -196,10 +186,8 @@ static int __backup(struct volume_group *vg)
|
||||
char name[PATH_MAX];
|
||||
char *desc;
|
||||
|
||||
if (!(desc = _build_desc(vg->cmd->mem, vg->cmd->cmd_line, 0))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(desc = _build_desc(vg->cmd->mem, vg->cmd->cmd_line, 0)))
|
||||
return_0;
|
||||
|
||||
if (dm_snprintf(name, sizeof(name), "%s/%s",
|
||||
vg->cmd->backup_params->dir, vg->name) < 0) {
|
||||
@@ -227,9 +215,9 @@ int backup(struct volume_group *vg)
|
||||
return 0;
|
||||
|
||||
/* Trap a read-only file system */
|
||||
if ((access(vg->cmd->backup_params->dir, R_OK | W_OK | X_OK) == -1) &&
|
||||
if ((access(vg->cmd->backup_params->dir, R_OK | W_OK | X_OK) == -1) &&
|
||||
(errno == EROFS))
|
||||
return 0;
|
||||
return 0;
|
||||
|
||||
if (!__backup(vg)) {
|
||||
log_error("Backup of volume group %s metadata failed.",
|
||||
@@ -273,7 +261,7 @@ struct volume_group *backup_read_vg(struct cmd_context *cmd,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list_iterate_items(mda, &tf->metadata_areas) {
|
||||
dm_list_iterate_items(mda, &tf->metadata_areas) {
|
||||
if (!(vg = mda->ops->vg_read(tf, vg_name, mda)))
|
||||
stack;
|
||||
break;
|
||||
@@ -303,9 +291,9 @@ int backup_restore_vg(struct cmd_context *cmd, struct volume_group *vg)
|
||||
}
|
||||
|
||||
/* Add any metadata areas on the PVs */
|
||||
list_iterate_items(pvl, &vg->pvs) {
|
||||
dm_list_iterate_items(pvl, &vg->pvs) {
|
||||
pv = pvl->pv;
|
||||
if (!(info = info_from_pvid(pv->dev->pvid))) {
|
||||
if (!(info = info_from_pvid(pv->dev->pvid, 0))) {
|
||||
log_error("PV %s missing from cache",
|
||||
pv_dev_name(pv));
|
||||
return 0;
|
||||
@@ -324,10 +312,8 @@ int backup_restore_vg(struct cmd_context *cmd, struct volume_group *vg)
|
||||
}
|
||||
}
|
||||
|
||||
if (!vg_write(vg) || !vg_commit(vg)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!vg_write(vg) || !vg_commit(vg))
|
||||
return_0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -341,10 +327,8 @@ int backup_restore_from_file(struct cmd_context *cmd, const char *vg_name,
|
||||
/*
|
||||
* Read in the volume group from the text file.
|
||||
*/
|
||||
if (!(vg = backup_read_vg(cmd, vg_name, file))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(vg = backup_read_vg(cmd, vg_name, file)))
|
||||
return_0;
|
||||
|
||||
return backup_restore_vg(cmd, vg);
|
||||
}
|
||||
@@ -382,7 +366,7 @@ int backup_to_file(const char *file, const char *desc, struct volume_group *vg)
|
||||
}
|
||||
|
||||
/* Write and commit the metadata area */
|
||||
list_iterate_items(mda, &tf->metadata_areas) {
|
||||
dm_list_iterate_items(mda, &tf->metadata_areas) {
|
||||
if (!(r = mda->ops->vg_write(tf, vg, mda))) {
|
||||
stack;
|
||||
continue;
|
||||
@@ -405,7 +389,7 @@ void check_current_backup(struct volume_group *vg)
|
||||
char path[PATH_MAX];
|
||||
struct volume_group *vg_backup;
|
||||
|
||||
if ((vg->status & PARTIAL_VG) || (vg->status & EXPORTED_VG))
|
||||
if (vg->status & EXPORTED_VG)
|
||||
return;
|
||||
|
||||
if (dm_snprintf(path, sizeof(path), "%s/%s",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
@@ -37,7 +37,7 @@ typedef int (*nl_fn) (struct formatter * f);
|
||||
* Then argument list is reset and out_with_comment_fn is called again.
|
||||
*/
|
||||
#define _out_with_comment(f, buffer, fmt, ap) \
|
||||
do { \
|
||||
do { \
|
||||
va_start(ap, fmt); \
|
||||
r = f->out_with_comment(f, buffer, fmt, ap); \
|
||||
va_end(ap); \
|
||||
@@ -135,10 +135,8 @@ static int _nl_raw(struct formatter *f)
|
||||
{
|
||||
/* If metadata doesn't fit, extend buffer */
|
||||
if ((f->data.buf.used + 2 > f->data.buf.size) &&
|
||||
(!_extend_buffer(f))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
(!_extend_buffer(f)))
|
||||
return_0;
|
||||
|
||||
*(f->data.buf.start + f->data.buf.used) = '\n';
|
||||
f->data.buf.used += 1;
|
||||
@@ -195,10 +193,8 @@ static int _out_with_comment_raw(struct formatter *f,
|
||||
|
||||
/* If metadata doesn't fit, extend buffer */
|
||||
if (n < 0 || (n + f->data.buf.used + 2 > f->data.buf.size)) {
|
||||
if (!_extend_buffer(f)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!_extend_buffer(f))
|
||||
return_0;
|
||||
return -1; /* Retry */
|
||||
}
|
||||
|
||||
@@ -300,6 +296,7 @@ int out_text(struct formatter *f, const char *fmt, ...)
|
||||
static int _print_header(struct formatter *f,
|
||||
const char *desc)
|
||||
{
|
||||
char *buf;
|
||||
time_t t;
|
||||
|
||||
t = time(NULL);
|
||||
@@ -309,7 +306,12 @@ static int _print_header(struct formatter *f,
|
||||
outf(f, FORMAT_VERSION_FIELD " = %d", FORMAT_VERSION_VALUE);
|
||||
outnl(f);
|
||||
|
||||
outf(f, "description = \"%s\"", desc);
|
||||
if (!(buf = alloca(escaped_len(desc)))) {
|
||||
log_error("temporary stack allocation for description"
|
||||
"string failed");
|
||||
return 0;
|
||||
}
|
||||
outf(f, "description = \"%s\"", escape_double_quotes(buf, desc));
|
||||
outnl(f);
|
||||
outf(f, "creation_host = \"%s\"\t# %s %s %s %s %s", _utsname.nodename,
|
||||
_utsname.sysname, _utsname.nodename, _utsname.release,
|
||||
@@ -319,30 +321,37 @@ static int _print_header(struct formatter *f,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _print_flag_config(struct formatter *f, int status, int type)
|
||||
{
|
||||
char buffer[4096];
|
||||
if (!print_flags(status, type | STATUS_FLAG, buffer, sizeof(buffer)))
|
||||
return_0;
|
||||
outf(f, "status = %s", buffer);
|
||||
|
||||
if (!print_flags(status, type, buffer, sizeof(buffer)))
|
||||
return_0;
|
||||
outf(f, "flags = %s", buffer);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _print_vg(struct formatter *f, struct volume_group *vg)
|
||||
{
|
||||
char buffer[4096];
|
||||
|
||||
if (!id_write_format(&vg->id, buffer, sizeof(buffer))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!id_write_format(&vg->id, buffer, sizeof(buffer)))
|
||||
return_0;
|
||||
|
||||
outf(f, "id = \"%s\"", buffer);
|
||||
|
||||
outf(f, "seqno = %u", vg->seqno);
|
||||
|
||||
if (!print_flags(vg->status, VG_FLAGS, buffer, sizeof(buffer))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
outf(f, "status = %s", buffer);
|
||||
if (!_print_flag_config(f, vg->status, VG_FLAGS))
|
||||
return_0;
|
||||
|
||||
if (!list_empty(&vg->tags)) {
|
||||
if (!print_tags(&vg->tags, buffer, sizeof(buffer))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!dm_list_empty(&vg->tags)) {
|
||||
if (!print_tags(&vg->tags, buffer, sizeof(buffer)))
|
||||
return_0;
|
||||
outf(f, "tags = %s", buffer);
|
||||
}
|
||||
|
||||
@@ -350,10 +359,8 @@ static int _print_vg(struct formatter *f, struct volume_group *vg)
|
||||
outf(f, "system_id = \"%s\"", vg->system_id);
|
||||
|
||||
if (!out_size(f, (uint64_t) vg->extent_size, "extent_size = %u",
|
||||
vg->extent_size)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
vg->extent_size))
|
||||
return_0;
|
||||
outf(f, "max_lv = %u", vg->max_lv);
|
||||
outf(f, "max_pv = %u", vg->max_pv);
|
||||
|
||||
@@ -382,60 +389,54 @@ static int _print_pvs(struct formatter *f, struct volume_group *vg)
|
||||
struct pv_list *pvl;
|
||||
struct physical_volume *pv;
|
||||
char buffer[4096];
|
||||
char *buf;
|
||||
const char *name;
|
||||
|
||||
outf(f, "physical_volumes {");
|
||||
_inc_indent(f);
|
||||
|
||||
list_iterate_items(pvl, &vg->pvs) {
|
||||
dm_list_iterate_items(pvl, &vg->pvs) {
|
||||
pv = pvl->pv;
|
||||
|
||||
if (!(name = _get_pv_name(f, pv))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(name = _get_pv_name(f, pv)))
|
||||
return_0;
|
||||
|
||||
outnl(f);
|
||||
outf(f, "%s {", name);
|
||||
_inc_indent(f);
|
||||
|
||||
if (!id_write_format(&pv->id, buffer, sizeof(buffer))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!id_write_format(&pv->id, buffer, sizeof(buffer)))
|
||||
return_0;
|
||||
|
||||
outf(f, "id = \"%s\"", buffer);
|
||||
if (!out_hint(f, "device = \"%s\"", pv_dev_name(pv))) {
|
||||
stack;
|
||||
|
||||
if (!(buf = alloca(escaped_len(pv_dev_name(pv))))) {
|
||||
log_error("temporary stack allocation for device name"
|
||||
"string failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!out_hint(f, "device = \"%s\"",
|
||||
escape_double_quotes(buf, pv_dev_name(pv))))
|
||||
return_0;
|
||||
outnl(f);
|
||||
|
||||
if (!print_flags(pv->status, PV_FLAGS, buffer, sizeof(buffer))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
outf(f, "status = %s", buffer);
|
||||
if (!_print_flag_config(f, pv->status, PV_FLAGS))
|
||||
return_0;
|
||||
|
||||
if (!list_empty(&pv->tags)) {
|
||||
if (!print_tags(&pv->tags, buffer, sizeof(buffer))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!dm_list_empty(&pv->tags)) {
|
||||
if (!print_tags(&pv->tags, buffer, sizeof(buffer)))
|
||||
return_0;
|
||||
outf(f, "tags = %s", buffer);
|
||||
}
|
||||
|
||||
if (!out_size(f, pv->size, "dev_size = %" PRIu64, pv->size)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!out_size(f, pv->size, "dev_size = %" PRIu64, pv->size))
|
||||
return_0;
|
||||
|
||||
outf(f, "pe_start = %" PRIu64, pv->pe_start);
|
||||
if (!out_size(f, vg->extent_size * (uint64_t) pv->pe_count,
|
||||
"pe_count = %u", pv->pe_count)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
"pe_count = %u", pv->pe_count))
|
||||
return_0;
|
||||
|
||||
_dec_indent(f);
|
||||
outf(f, "}");
|
||||
@@ -456,27 +457,21 @@ static int _print_segment(struct formatter *f, struct volume_group *vg,
|
||||
|
||||
outf(f, "start_extent = %u", seg->le);
|
||||
if (!out_size(f, (uint64_t) seg->len * vg->extent_size,
|
||||
"extent_count = %u", seg->len)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
"extent_count = %u", seg->len))
|
||||
return_0;
|
||||
|
||||
outnl(f);
|
||||
outf(f, "type = \"%s\"", seg->segtype->name);
|
||||
|
||||
if (!list_empty(&seg->tags)) {
|
||||
if (!print_tags(&seg->tags, buffer, sizeof(buffer))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!dm_list_empty(&seg->tags)) {
|
||||
if (!print_tags(&seg->tags, buffer, sizeof(buffer)))
|
||||
return_0;
|
||||
outf(f, "tags = %s", buffer);
|
||||
}
|
||||
|
||||
if (seg->segtype->ops->text_export &&
|
||||
!seg->segtype->ops->text_export(seg, f)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
!seg->segtype->ops->text_export(seg, f))
|
||||
return_0;
|
||||
|
||||
_dec_indent(f);
|
||||
outf(f, "}");
|
||||
@@ -498,10 +493,8 @@ int out_areas(struct formatter *f, const struct lv_segment *seg,
|
||||
for (s = 0; s < seg->area_count; s++) {
|
||||
switch (seg_type(seg, s)) {
|
||||
case AREA_PV:
|
||||
if (!(name = _get_pv_name(f, seg_pv(seg, s)))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(name = _get_pv_name(f, seg_pv(seg, s))))
|
||||
return_0;
|
||||
|
||||
outf(f, "\"%s\", %u%s", name,
|
||||
seg_pe(seg, s),
|
||||
@@ -534,24 +527,17 @@ static int _print_lv(struct formatter *f, struct logical_volume *lv)
|
||||
_inc_indent(f);
|
||||
|
||||
/* FIXME: Write full lvid */
|
||||
if (!id_write_format(&lv->lvid.id[1], buffer, sizeof(buffer))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!id_write_format(&lv->lvid.id[1], buffer, sizeof(buffer)))
|
||||
return_0;
|
||||
|
||||
outf(f, "id = \"%s\"", buffer);
|
||||
|
||||
if (!print_flags(lv->status, LV_FLAGS, buffer, sizeof(buffer))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
outf(f, "status = %s", buffer);
|
||||
if (!_print_flag_config(f, lv->status, LV_FLAGS))
|
||||
return_0;
|
||||
|
||||
if (!list_empty(&lv->tags)) {
|
||||
if (!print_tags(&lv->tags, buffer, sizeof(buffer))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!dm_list_empty(&lv->tags)) {
|
||||
if (!print_tags(&lv->tags, buffer, sizeof(buffer)))
|
||||
return_0;
|
||||
outf(f, "tags = %s", buffer);
|
||||
}
|
||||
|
||||
@@ -574,15 +560,13 @@ static int _print_lv(struct formatter *f, struct logical_volume *lv)
|
||||
outf(f, "major = %d", lv->major);
|
||||
if (lv->minor >= 0)
|
||||
outf(f, "minor = %d", lv->minor);
|
||||
outf(f, "segment_count = %u", list_size(&lv->segments));
|
||||
outf(f, "segment_count = %u", dm_list_size(&lv->segments));
|
||||
outnl(f);
|
||||
|
||||
seg_count = 1;
|
||||
list_iterate_items(seg, &lv->segments) {
|
||||
if (!_print_segment(f, lv->vg, seg_count++, seg)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
dm_list_iterate_items(seg, &lv->segments) {
|
||||
if (!_print_segment(f, lv->vg, seg_count++, seg))
|
||||
return_0;
|
||||
}
|
||||
|
||||
_dec_indent(f);
|
||||
@@ -598,7 +582,7 @@ static int _print_lvs(struct formatter *f, struct volume_group *vg)
|
||||
/*
|
||||
* Don't bother with an lv section if there are no lvs.
|
||||
*/
|
||||
if (list_empty(&vg->lvs))
|
||||
if (dm_list_empty(&vg->lvs))
|
||||
return 1;
|
||||
|
||||
outf(f, "logical_volumes {");
|
||||
@@ -607,22 +591,18 @@ static int _print_lvs(struct formatter *f, struct volume_group *vg)
|
||||
/*
|
||||
* Write visible LVs first
|
||||
*/
|
||||
list_iterate_items(lvl, &vg->lvs) {
|
||||
dm_list_iterate_items(lvl, &vg->lvs) {
|
||||
if (!(lvl->lv->status & VISIBLE_LV))
|
||||
continue;
|
||||
if (!_print_lv(f, lvl->lv)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!_print_lv(f, lvl->lv))
|
||||
return_0;
|
||||
}
|
||||
|
||||
list_iterate_items(lvl, &vg->lvs) {
|
||||
dm_list_iterate_items(lvl, &vg->lvs) {
|
||||
if ((lvl->lv->status & VISIBLE_LV))
|
||||
continue;
|
||||
if (!_print_lv(f, lvl->lv)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!_print_lv(f, lvl->lv))
|
||||
return_0;
|
||||
}
|
||||
|
||||
_dec_indent(f);
|
||||
@@ -649,7 +629,7 @@ static int _build_pv_names(struct formatter *f, struct volume_group *vg)
|
||||
if (!(f->pv_names = dm_hash_create(128)))
|
||||
return_0;
|
||||
|
||||
list_iterate_items(pvl, &vg->pvs) {
|
||||
dm_list_iterate_items(pvl, &vg->pvs) {
|
||||
pv = pvl->pv;
|
||||
|
||||
/* FIXME But skip if there's already an LV called pv%d ! */
|
||||
@@ -671,10 +651,8 @@ static int _text_vg_export(struct formatter *f,
|
||||
{
|
||||
int r = 0;
|
||||
|
||||
if (!_build_pv_names(f, vg)) {
|
||||
stack;
|
||||
goto out;
|
||||
}
|
||||
if (!_build_pv_names(f, vg))
|
||||
goto_out;
|
||||
|
||||
if (f->header && !_print_header(f, desc))
|
||||
goto_out;
|
||||
@@ -721,10 +699,8 @@ int text_vg_export_file(struct volume_group *vg, const char *desc, FILE *fp)
|
||||
|
||||
_init();
|
||||
|
||||
if (!(f = dm_malloc(sizeof(*f)))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(f = dm_malloc(sizeof(*f))))
|
||||
return_0;
|
||||
|
||||
memset(f, 0, sizeof(*f));
|
||||
f->data.fp = fp;
|
||||
@@ -748,10 +724,8 @@ int text_vg_export_raw(struct volume_group *vg, const char *desc, char **buf)
|
||||
|
||||
_init();
|
||||
|
||||
if (!(f = dm_malloc(sizeof(*f)))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(f = dm_malloc(sizeof(*f))))
|
||||
return_0;
|
||||
|
||||
memset(f, 0, sizeof(*f));
|
||||
|
||||
@@ -767,9 +741,8 @@ int text_vg_export_raw(struct volume_group *vg, const char *desc, char **buf)
|
||||
f->nl = &_nl_raw;
|
||||
|
||||
if (!_text_vg_export(f, vg, desc)) {
|
||||
stack;
|
||||
dm_free(f->data.buf.start);
|
||||
goto out;
|
||||
goto_out;
|
||||
}
|
||||
|
||||
r = f->data.buf.used + 1;
|
||||
@@ -780,5 +753,10 @@ int text_vg_export_raw(struct volume_group *vg, const char *desc, char **buf)
|
||||
return r;
|
||||
}
|
||||
|
||||
int export_vg_to_buffer(struct volume_group *vg, char **buf)
|
||||
{
|
||||
return text_vg_export_raw(vg, "", buf);
|
||||
}
|
||||
|
||||
#undef outf
|
||||
#undef outnl
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
@@ -25,47 +25,52 @@
|
||||
struct flag {
|
||||
const int mask;
|
||||
const char *description;
|
||||
int kind;
|
||||
};
|
||||
|
||||
static struct flag _vg_flags[] = {
|
||||
{EXPORTED_VG, "EXPORTED"},
|
||||
{RESIZEABLE_VG, "RESIZEABLE"},
|
||||
{PARTIAL_VG, "PARTIAL"},
|
||||
{PVMOVE, "PVMOVE"},
|
||||
{LVM_READ, "READ"},
|
||||
{LVM_WRITE, "WRITE"},
|
||||
{CLUSTERED, "CLUSTERED"},
|
||||
{SHARED, "SHARED"},
|
||||
{PRECOMMITTED, NULL},
|
||||
{0, NULL}
|
||||
{EXPORTED_VG, "EXPORTED", STATUS_FLAG},
|
||||
{RESIZEABLE_VG, "RESIZEABLE", STATUS_FLAG},
|
||||
{PVMOVE, "PVMOVE", STATUS_FLAG},
|
||||
{LVM_READ, "READ", STATUS_FLAG},
|
||||
{LVM_WRITE, "WRITE", STATUS_FLAG},
|
||||
{CLUSTERED, "CLUSTERED", STATUS_FLAG},
|
||||
{SHARED, "SHARED", STATUS_FLAG},
|
||||
{PARTIAL_VG, NULL, 0},
|
||||
{PRECOMMITTED, NULL, 0},
|
||||
{0, NULL, 0}
|
||||
};
|
||||
|
||||
static struct flag _pv_flags[] = {
|
||||
{ALLOCATABLE_PV, "ALLOCATABLE"},
|
||||
{EXPORTED_VG, "EXPORTED"},
|
||||
{0, NULL}
|
||||
{ALLOCATABLE_PV, "ALLOCATABLE", STATUS_FLAG},
|
||||
{EXPORTED_VG, "EXPORTED", STATUS_FLAG},
|
||||
{MISSING_PV, "MISSING", COMPATIBLE_FLAG},
|
||||
{0, NULL, 0}
|
||||
};
|
||||
|
||||
static struct flag _lv_flags[] = {
|
||||
{LVM_READ, "READ"},
|
||||
{LVM_WRITE, "WRITE"},
|
||||
{FIXED_MINOR, "FIXED_MINOR"},
|
||||
{VISIBLE_LV, "VISIBLE"},
|
||||
{PVMOVE, "PVMOVE"},
|
||||
{LOCKED, "LOCKED"},
|
||||
{MIRROR_NOTSYNCED, "NOTSYNCED"},
|
||||
{MIRROR_IMAGE, NULL},
|
||||
{MIRROR_LOG, NULL},
|
||||
{MIRRORED, NULL},
|
||||
{VIRTUAL, NULL},
|
||||
{SNAPSHOT, NULL},
|
||||
{ACTIVATE_EXCL, NULL},
|
||||
{0, NULL}
|
||||
{LVM_READ, "READ", STATUS_FLAG},
|
||||
{LVM_WRITE, "WRITE", STATUS_FLAG},
|
||||
{FIXED_MINOR, "FIXED_MINOR", STATUS_FLAG},
|
||||
{VISIBLE_LV, "VISIBLE", STATUS_FLAG},
|
||||
{PVMOVE, "PVMOVE", STATUS_FLAG},
|
||||
{LOCKED, "LOCKED", STATUS_FLAG},
|
||||
{MIRROR_NOTSYNCED, "NOTSYNCED", STATUS_FLAG},
|
||||
{MIRROR_IMAGE, NULL, 0},
|
||||
{MIRROR_LOG, NULL, 0},
|
||||
{MIRRORED, NULL, 0},
|
||||
{VIRTUAL, NULL, 0},
|
||||
{SNAPSHOT, NULL, 0},
|
||||
{ACTIVATE_EXCL, NULL, 0},
|
||||
{CONVERTING, NULL, 0},
|
||||
{PARTIAL_LV, NULL, 0},
|
||||
{POSTORDER_FLAG, NULL, 0},
|
||||
{0, NULL, 0}
|
||||
};
|
||||
|
||||
static struct flag *_get_flags(int type)
|
||||
{
|
||||
switch (type) {
|
||||
switch (type & ~STATUS_FLAG) {
|
||||
case VG_FLAGS:
|
||||
return _vg_flags;
|
||||
|
||||
@@ -90,10 +95,8 @@ int print_flags(uint32_t status, int type, char *buffer, size_t size)
|
||||
int f, first = 1;
|
||||
struct flag *flags;
|
||||
|
||||
if (!(flags = _get_flags(type))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(flags = _get_flags(type)))
|
||||
return_0;
|
||||
|
||||
if (!emit_to_buffer(&buffer, &size, "["))
|
||||
return 0;
|
||||
@@ -102,6 +105,9 @@ int print_flags(uint32_t status, int type, char *buffer, size_t size)
|
||||
if (status & flags[f].mask) {
|
||||
status &= ~flags[f].mask;
|
||||
|
||||
if ((type & STATUS_FLAG) != flags[f].kind)
|
||||
continue;
|
||||
|
||||
/* Internal-only flag? */
|
||||
if (!flags[f].description)
|
||||
continue;
|
||||
@@ -134,10 +140,8 @@ int read_flags(uint32_t *status, int type, struct config_value *cv)
|
||||
uint32_t s = 0;
|
||||
struct flag *flags;
|
||||
|
||||
if (!(flags = _get_flags(type))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(flags = _get_flags(type)))
|
||||
return_0;
|
||||
|
||||
if (cv->type == CFG_EMPTY_ARRAY)
|
||||
goto out;
|
||||
@@ -154,7 +158,16 @@ int read_flags(uint32_t *status, int type, struct config_value *cv)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!flags[f].description) {
|
||||
if (type == VG_FLAGS && !strcmp(cv->v.str, "PARTIAL")) {
|
||||
/*
|
||||
* Exception: We no longer write this flag out, but it
|
||||
* might be encountered in old backup files, so restore
|
||||
* it in that case. It is never part of live metadata
|
||||
* though, so only vgcfgrestore needs to be concerned
|
||||
* by this case.
|
||||
*/
|
||||
s |= PARTIAL_VG;
|
||||
} else if (!flags[f].description && (type & STATUS_FLAG)) {
|
||||
log_err("Unknown status flag '%s'.", cv->v.str);
|
||||
return 0;
|
||||
}
|
||||
@@ -163,6 +176,6 @@ int read_flags(uint32_t *status, int type, struct config_value *cv)
|
||||
}
|
||||
|
||||
out:
|
||||
*status = s;
|
||||
*status |= s;
|
||||
return 1;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user