1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-12-24 16:23:50 +03:00

Compare commits

..

467 Commits

Author SHA1 Message Date
Alasdair Kergon
f9c8c1b964 pre-release 2008-10-17 17:42:08 +00:00
Alasdair Kergon
5650f67ef5 Use temp table to set device size when converting mirrors.
(Avoids having same mirror table loaded twice concurrently by first
using a 'zero' table to set the size of the device so when mirror
table is preloaded it doesn't have to be activated immediately.)
2008-10-17 10:57:15 +00:00
Alasdair Kergon
5ec25dfb94 In resume_mirror_images replace activate_lv with resume_lv as workaround.
(The resume has the side-effect of resuming all of the original
mirror's sub-lvs in addition to the new 'error' target middle layer.)
2008-10-17 10:50:14 +00:00
Alasdair Kergon
ef16682725 Avoid overwriting in-use on-disk text metadata by forgetting MDA_HEADER_SIZE. (Edward Allcutt) 2008-10-17 00:55:46 +00:00
Petr Rockai
883486cc67 Re-indent test-utils.sh consistently, using tabs. 2008-10-14 19:48:01 +00:00
Petr Rockai
f367f9b747 Conversion of last 2 tests to use test-utils.sh, by jstava. 2008-10-14 19:41:12 +00:00
Milan Broz
a3d987fa73 Fix snapshot monitoring library to not cancel monitoring invalid snapshot.
snapshot DSO unregistered itself when snapshot changed state to invalid.

This can cause a race (and several timeouts), when for example another snapshot
is added and in the middle of operation (suspend/resume) the monitoring thread
unregister itself.

Fix it by keeping the snapshot monitored after invalidation - just reset
threshold to not really print any messages to syslog.
2008-10-13 12:06:30 +00:00
Alasdair Kergon
2d48685673 . 2008-10-09 10:47:37 +00:00
Alasdair Kergon
9b21ace1e9 Generate man pages from templates and include version. (romster) 2008-10-08 12:50:13 +00:00
Alasdair Kergon
be2c03fa96 Add usrlibdir & usrsbindir to configure. 2008-10-07 19:11:59 +00:00
Alasdair Kergon
f5585e9252 Add usrsbindir to configure. 2008-10-07 19:08:46 +00:00
Petr Rockai
4d534dd7e4 Add a workaround for missing losetup -s by jstava, and a print a stacktrace
on errors (also by jstava). Currently requires bash, a fix for that may come
later -- explicitly using bash to run tests in the meantime.
2008-10-06 16:55:30 +00:00
Petr Rockai
c8584e1cce More test conversions by jstava. Make check still passes. 2008-10-06 16:47:07 +00:00
Alasdair Kergon
84a1de464c Fix conversion of md chunk size into sectors. 2008-10-03 14:22:18 +00:00
Alasdair Kergon
3966f3d319 device->devices 2008-10-01 22:48:26 +00:00
Petr Rockai
e6166cf711 Make harness.sh exit with non-zero status when tests fail. 2008-09-30 21:45:42 +00:00
Petr Rockai
2285712834 Cosmetic: get rid of trailing garbage on comments in t-vgslpit-usage.sh. 2008-09-30 21:43:55 +00:00
Petr Rockai
53cb6128e8 Improve harness.sh output: also mention failing test's name near the end of its
output. Avoids the need to scroll back just to see which failing test you are
looking at.
2008-09-30 21:43:16 +00:00
Alasdair Kergon
8c317baf19 Free text metadata buffer after a failure writing it. 2008-09-30 20:37:52 +00:00
Petr Rockai
8cac933c71 Fix [ a = b ] usage in t-vgsplit-operation: string comparison is '=', not '=='. 2008-09-30 18:29:10 +00:00
Petr Rockai
03e61a4bf8 Conversion of t-vgsplit-operation.sh by jstava. 2008-09-30 17:56:54 +00:00
Petr Rockai
71446a76b2 Fix a syntax error in one of the scripts, introduced by last commit. 2008-09-30 17:50:56 +00:00
Petr Rockai
28db8d6c7c More test conversions, all of these are by jstava. 2008-09-30 17:47:34 +00:00
Petr Rockai
786e33d7d5 Port over t-vgreduce-usage. Should fix testsuite hangs where pvremove -ff would
have waited for input on certain test failures.
2008-09-30 17:17:04 +00:00
Petr Rockai
b140d6c50e Convert t-vgsplit-usage.sh to use the new test-utils.sh. Original conversion by
jstava. Lvm1 testing restored by mornfall.
2008-09-30 15:20:09 +00:00
Petr Rockai
64a95abdee Convert t-pvremove-usage to use the new test-utils.sh. 2008-09-30 13:19:56 +00:00
Petr Rockai
57f926be17 Update test/Makefile.in to use the new harness for calling tests. 2008-09-29 16:07:02 +00:00
Petr Rockai
4933b67959 Add a test for reappearing lost PVs causing endless metadata correction
updates. (A problem Milan fixed recently.)
2008-09-29 16:06:10 +00:00
Petr Rockai
370b4f1b9e Add a simple test for partial activation. 2008-09-29 16:04:57 +00:00
Petr Rockai
f3b7baa84e Update a bunch of tests to use functionality from test-utils.sh. 2008-09-29 16:02:50 +00:00
Petr Rockai
eafdb2c807 Export testlib_cleanup_ from test-lib.sh, which is needed for test-utils.sh to
be able to call proper EXIT traps.
2008-09-29 16:00:53 +00:00
Petr Rockai
a91fa821ab Import new test utilities and a test harness. 2008-09-29 15:59:19 +00:00
Milan Broz
37ef162cda Fix misleading error message when there is no allocatable extents in VG. 2008-09-29 09:59:10 +00:00
Milan Broz
770928acfc Fix handling of PVs which reappeared with old metadata version. 2008-09-25 15:59:10 +00:00
Milan Broz
d0f3570219 Try to fix possible infinite loop in dependency tree walking (by mornfall). 2008-09-25 15:57:02 +00:00
Milan Broz
3d07c2605f Fix mirror DSO to call vgreduce with proper parameters. 2008-09-25 15:52:29 +00:00
Milan Broz
c350798528 Fix validation of --minor and --major in lvcreate to require -My always. 2008-09-24 16:32:51 +00:00
Alasdair Kergon
6bc3cc0bec . 2008-09-19 18:31:20 +00:00
Alasdair Kergon
2e3e5fcc81 suppress warning if old value found for now 2008-09-19 18:26:41 +00:00
Milan Broz
dfdb10f6de Add more vgreduce tests. (Jaroslav Stava) 2008-09-19 16:12:25 +00:00
Milan Broz
5cbe5909eb Fix vgreduce test, now requires --force flag. (Jaroslav Stava) 2008-09-19 16:10:46 +00:00
Alasdair Kergon
04d52b450b fix last release 2008-09-19 15:44:03 +00:00
Alasdair Kergon
a586a89547 . 2008-09-19 07:18:03 +00:00
Alasdair Kergon
1905eacf15 rename var 2008-09-19 07:12:45 +00:00
Alasdair Kergon
858ec0d740 revert unexplained removal of a '<backtrace>' message 2008-09-19 07:03:23 +00:00
Alasdair Kergon
76cfd406ca pre-release 2008-09-19 06:48:48 +00:00
Alasdair Kergon
9dbaad859d . 2008-09-19 06:44:54 +00:00
Alasdair Kergon
95d43e17b3 Improve the way VGs with PVs missing are handled so manual intervention
is required in fewer circumstances.  (mornfall)
2008-09-19 06:42:00 +00:00
Alasdair Kergon
09a2dff8de Add device/md_chunk_alignment to lvm.conf 2008-09-19 05:33:37 +00:00
Alasdair Kergon
57208f879a adjust pe_align for md chunk size 2008-09-19 05:19:09 +00:00
Alasdair Kergon
149638431d remove unsed var 2008-09-19 04:30:02 +00:00
Alasdair Kergon
30d2940c67 Pass struct physical_volume to pe_align. 2008-09-19 04:28:58 +00:00
Alasdair Kergon
5ee86fc5d0 remove unused var 2008-09-19 03:45:34 +00:00
Alasdair Kergon
a03d0e2c3f Store sysfs location in struct cmd_context. 2008-09-19 03:42:37 +00:00
Alasdair Kergon
8bd367d58d fix last patch return code 2008-09-19 00:20:39 +00:00
Alasdair Kergon
bc633e03aa Fix last checkin - tested wrong dnode. 2008-09-18 22:55:33 +00:00
Alasdair Kergon
797d0f1ef1 post-release 2008-09-18 20:09:51 +00:00
Alasdair Kergon
1be3e86aa0 Avoid shuffling remaining mirror images when removing one, retaining primary. 2008-09-18 19:56:50 +00:00
Alasdair Kergon
e56dd38021 Add missing LV error target activation in _remove_mirror_images. 2008-09-18 19:09:47 +00:00
Alasdair Kergon
410904bef1 Prevent resizing an LV while lvconvert is using it. 2008-09-18 18:51:58 +00:00
Alasdair Kergon
026cc120e7 Only resume devices in dm_tree_preload_children if size changes. 2008-09-18 18:34:53 +00:00
Alasdair Kergon
ef2fda05cf Avoid repeatedly wiping cache while VG_GLOBAL is held in vgscan & pvscan. 2008-09-16 18:05:11 +00:00
Alasdair Kergon
92277e3ae2 revert unnecessary 'stack's 2008-09-15 17:06:55 +00:00
Milan Broz
fbc34d70b0 Fix pvresize to not allow resize if PV has two metadata areas.
If the PV has two metadata areas, second one is located at the end of the device.

Do not allow resize of PV or second metadata area can be overwritten.
(The check was active only for orphan PVs.)
2008-09-12 15:26:45 +00:00
Milan Broz
91dcddbdf7 Do not scan for lvm1 entries in /proc if not running 2.4 kernel.
(LVM1 is only present in 2.4 kernel.)
2008-09-10 10:14:59 +00:00
Alasdair Kergon
874f42ad6c Extend deptree buffers so the largest possible device numbers fit. 2008-09-02 12:16:07 +00:00
Milan Broz
1989ef4ebc Fix setting of volume limit count if converting to lvm1 format.
Fixes problem when after downconvert to lvm1 VG is broken:

# lvcreate -n lv1 -l 4 vg_test
  Invalid LV in extent map (PV /dev/sdb1, PE 0, LV 0, LE 0)
  ...
2008-08-29 13:41:21 +00:00
Dave Wysochanski
4f4c72c065 Add ctype.h header file to silence compile warning on 'isdigit'.
uuid/uuid.c:86: warning: implicit declaration of function 'isdigit'
2008-08-29 00:49:46 +00:00
Milan Broz
666cc72661 Fix vgconvert logical volume id metadata validation.
If volume group is downconverted to lvm1 format,
check if lvid has supported format for conversion to lv_num in lvm1.
2008-08-28 18:41:51 +00:00
Milan Broz
4524e8f5c9 format1: Not detecing label on disc is not error, remove <backtrace> from debug log
(happens when you explicitly use -M 1)
2008-08-28 13:41:46 +00:00
Milan Broz
bd07a29886 Not detecing label on disc is not error, remove <backtrace> from debug log
and report it only if device cannot be read.
2008-08-28 13:28:13 +00:00
Milan Broz
a0d865492e fix vgreduce tests to detect partial command failure (Jaroslav Stava) 2008-08-28 11:20:49 +00:00
Milan Broz
de27790de8 add vgcreate rejects repeated invocation test
add vgcreate fails when the only pv has --metadatacopies 0 test
(by Jaroslav Stava)
2008-08-28 11:09:58 +00:00
Milan Broz
9c910b7be2 add vgrename by uuid test (Jaroslav Stava)
fix vgsplit rejects last mda copy test (Jaroslav Stava)
2008-08-28 10:59:10 +00:00
Milan Broz
7f23ab94e2 Fix lvmdump metadata gather option (-m) to work correctly. (Jaroslav Stava) 2008-08-28 10:40:44 +00:00
Milan Broz
77dc036c8f Add pvremove usage test (Jaroslav Stava) 2008-08-28 10:24:55 +00:00
Milan Broz
aa6e8d82ce - fix environment variable prefix to LVM (this is not GIT:-)
- add lvcreate rejects repeated invocation test
- fix pvs metadata test for partial failure test
- add pvchange reject --addtag to lvm1 pv test

(All fixes by Jaroslav Stava)
2008-08-28 10:07:34 +00:00
Dave Wysochanski
3010285bb3 Fix symbolic link creation in test infrastructure.
Original code would create "*.so" symbolic links if there were no actual
files ending in "so".  The second iteration would then cause an error
in the test logs.
2008-08-21 14:33:48 +00:00
Zdeněk Kabeláč
aaad3252f8 fail testcase for failed commands inside the for loop 2008-08-20 13:34:33 +00:00
Milan Broz
9065f534d8 Fix allocation bug in text metadata format write error path.
Function _text_pv_write doesn't use memory pool but static buffer,
call dm_pool_free in error path in _raw_write_mda_header is wrong.

Move pool free only to path where is the memory pool used.
2008-08-16 09:46:55 +00:00
Zdeněk Kabeláč
52361c94e5 valid parameter for lvchange -p is 'rw' 2008-08-13 14:28:17 +00:00
Zdeněk Kabeláč
798be60fef added test for coverage improvement
added test for metadata type 1
2008-08-13 13:49:07 +00:00
Zdeněk Kabeláč
6294154b15 get lv_list properly from vg->lst and fix compiler warning 2008-08-13 13:42:35 +00:00
Milan Broz
6594fe077d Fix vgcfgbackup to properly check filename if template is used. 2008-08-13 12:44:24 +00:00
Milan Broz
582706cde6 add tests for pvchange and vgreduce usage (Jaroslav Stava) 2008-08-12 10:04:31 +00:00
Milan Broz
6537cbdc17 test vgsplit: reject to give away pv with the last mda copy (Jaroslav Stava) 2008-08-12 10:01:56 +00:00
Zdeněk Kabeláč
53959459bb * more strict const 2008-08-07 14:02:32 +00:00
Zdeněk Kabeláč
22d6121099 added const modifiers
switched const char* to  const char[] elements to save few relocation entries
2008-08-07 14:01:17 +00:00
Zdeněk Kabeláč
48d7f6f2f4 added const and saved relocation entry 2008-08-07 13:59:49 +00:00
Zdeněk Kabeláč
9fd4ddc490 configure aborts if lcov or genhtml are missing with --enable-profiling 2008-08-05 14:29:38 +00:00
Zdeněk Kabeláč
a4d2fddbb2 add test for pool labels gfs
add test for metadatacopies0 and snapshot manipulation
2008-08-05 12:33:41 +00:00
Zdeněk Kabeláč
c54a3f2721 put dmeventd into the LD_LIBRARY_PATH for lvm-wrapper 2008-08-05 12:32:08 +00:00
Zdeněk Kabeláč
04c0dba697 vgremove tries to remove lv snapshot first.
Added function lv_remove_with_dependencies().
2008-08-05 12:05:26 +00:00
Zdeněk Kabeláč
5406e3b7c5 avoid endless option parsing loop
add support for lvm verbose operation -vvvv
add dlsym path to the test config file
2008-08-05 11:39:54 +00:00
Zdeněk Kabeláč
6b624b7d00 * parse error output for 'auto' keyword 2008-08-04 09:15:15 +00:00
Alasdair Kergon
2d364d4d80 Improve file descriptor leak detection to display likely culprit and filename. 2008-08-01 19:51:27 +00:00
Zdeněk Kabeláč
1f27bf3774 disable mdadm test-case until a better solution is found 2008-08-01 15:44:53 +00:00
Alasdair Kergon
d30a2653b5 remove now-redundant slash-stripping 2008-07-31 15:38:52 +00:00
Alasdair Kergon
3086822cd2 Change clustered mirror kernel module name from cmirror to dm-log-clustered. 2008-07-31 14:43:39 +00:00
Alasdair Kergon
2c08336490 Avoid looping forever in _pv_analyze_mda_raw used by pvck. 2008-07-31 13:07:01 +00:00
Alasdair Kergon
5936ac58c2 Change lvchange exit status to indicate if any part of the operation failed. 2008-07-31 13:03:01 +00:00
Alasdair Kergon
ded77e3f5c remove unused mdas variable 2008-07-31 12:40:52 +00:00
Alasdair Kergon
8a29df0a6c fix pvremove for pvs without mdas 2008-07-31 12:38:31 +00:00
Alasdair Kergon
9db22babaf Fix pvchange to handle PVs without mdas. 2008-07-31 12:28:51 +00:00
Alasdair Kergon
c318c5ed61 Refactor _text_pv_read and always return mda list if requested. 2008-07-31 10:50:18 +00:00
Dave Wysochanski
61243c65cd Add pvcreate tests to verify failure on md array detection. 2008-07-29 21:05:20 +00:00
Dave Wysochanski
4a5d5cb462 Fix trivial typo in pvcreate man page. 2008-07-29 18:35:00 +00:00
Dave Wysochanski
cbf1447ebd Refactor pvcreate - simplify return codes. 2008-07-25 14:59:51 +00:00
Dave Wysochanski
30104441bf Refactor pvcreate - --yes argument 2008-07-25 14:45:24 +00:00
Dave Wysochanski
b4a70804f0 Refactor pvcreate - --force parameter. 2008-07-25 14:36:55 +00:00
Dave Wysochanski
74f6707bde Refactor pvcreate - use '0' for no --uuid or --restorefile options. 2008-07-25 14:12:29 +00:00
Jim Meyering
223eb8c84d configure: regenerate 2008-07-25 08:00:40 +00:00
Jim Meyering
107d000606 Avoid compiler warnings (provoked by new configure.in bug) on RHEL5.
Do not override the default action of AC_CHECK_LIB([readline],...
(i.e., leave the ACTION-IF-FOUND parameter blank) so that the
subsequent check for rl_completion_matches can use -lreadline.

Also, replace AC_CHECK_FUNC+AC_DEFINE with an equivalent AC_CHECK_FUNCS call.
2008-07-25 08:00:18 +00:00
Dave Wysochanski
43e05607af Refactor pvcreate - move uuid and restorefile options. 2008-07-25 00:30:57 +00:00
Dave Wysochanski
55793452d5 Add pvcreate tests for uuid and restorefile. 2008-07-24 17:33:40 +00:00
Alasdair Kergon
686ba37255 . 2008-07-24 15:39:47 +00:00
Alasdair Kergon
03ed19dad5 reinstate lost FIXME
- only if kernel gives the info, not to be worked out in userspace
- with lvm.conf option to enable/disable the check
2008-07-24 15:25:09 +00:00
Jim Meyering
ad2b6e5de1 configure: regenerate 2008-07-24 14:54:26 +00:00
Jim Meyering
767676d6ff Don't make configure fail when readline library is not available. 2008-07-24 14:54:06 +00:00
Dave Wysochanski
bc7a54c615 Remove dead code, is_lvm_partition() - no functional change.
This code does nothing.  The function is #defined to 1 which ensures the only
two if statements referencing it will never be true.
2008-07-23 19:46:33 +00:00
Dave Wysochanski
1bda393678 Refactor pvcreate - move labelsector parameter parsing & validation. 2008-07-23 19:29:58 +00:00
Dave Wysochanski
bb5495c6bd Refactor pvcreate - divide parameter parsing & validation from create logic.
Move size (setphysicalvolumesize option), metadatacopies and metadatasize
validation.
2008-07-21 19:27:22 +00:00
Dave Wysochanski
484f905749 Refactor pvcreate to divide parameter parsing & validation from create logic. 2008-07-21 19:26:33 +00:00
Dave Wysochanski
e0d61a4336 Add more pvcreate tests to validate writing lvm2 label using --labelsector. 2008-07-21 18:50:10 +00:00
Dave Wysochanski
e643a16ba5 Refactor _lvcreate() - no functional change. 2008-07-17 15:19:42 +00:00
Dave Wysochanski
98fadec2b6 Only use lvm2 metadata for now. 2008-07-17 04:03:04 +00:00
Dave Wysochanski
14f464ecb0 Update pvcreate and vgsplit tests.
Add more pvcreate tests.
Start handling lvm1 and lvm2 metadata and metadatacopies=0,1.
2008-07-17 03:17:01 +00:00
Dave Wysochanski
2ecdaf9bd4 Add pvcreate sanity tests, check for label_write() failure in _text_pv_write().
Failure to check for label_write() return code caused the following test
to indicate it passed when it really failed:
pvcreate rejects labelsector > 1000000000000
2008-07-16 21:32:38 +00:00
Alasdair Kergon
707c898f66 Fix pvchange -M1 -u to preserve existing extent locations when there's a VG. 2008-07-16 10:46:12 +00:00
Alasdair Kergon
69e4400774 Cease recognising snapshot-in-use percentages returned by early development kernels. 2008-07-15 00:25:52 +00:00
Petr Rockai
695efde68d Fix gcc warnings. 2008-07-11 09:19:54 +00:00
Petr Rockai
0c4b769011 Add "flags" metadata field (akin to "status") for backward-compatible flags.
The "status" field is treated as it ever has been, unknown flags there are
treated as fatal metadata errors. However, in the "flags" field, any unknown
flags will be ignored and silently dropped. This improves
backward-compatibility possibilities. (Any versions without support for this
new "flag" field will drop the field altogether, which is same as ignoring all
the flags there.)
2008-07-10 11:30:57 +00:00
Alasdair Kergon
e53eff0634 . 2008-07-10 09:50:23 +00:00
Petr Rockai
6c75243a06 Add #include <signal.h> to dmeventd.c, fixes compilation on NetBSD. 2008-07-09 13:26:07 +00:00
Petr Rockai
efde37880b Fix dmeventd regression where mirror and snapshot monitoring libraries
failed to link against liblvm2cmd.

Dmeventd DSOs *require* lvm2cmd to be linked in.

For the future:
1) AC_SUBST does not create Makefile variables, only @foo@-style substitutions
2) When using `test', whitespace around `=' is essential:
    test a=b is true, as is test a=a
2008-07-09 09:59:42 +00:00
Alasdair Kergon
7d8f6381be post-release 2008-06-27 22:35:22 +00:00
Alasdair Kergon
3c361e3393 pre-release 2008-06-27 21:56:35 +00:00
Alasdair Kergon
8440ecef5e Enable readline by default if available. 2008-06-27 19:57:27 +00:00
Alasdair Kergon
6401f1b1c9 tweak lcov configuration/makefiles 2008-06-27 19:24:17 +00:00
Zdeněk Kabeláč
7487a7c988 Added generation of the versioned libdevmapper-event.so for LVM's test 2008-06-27 15:36:51 +00:00
Zdeněk Kabeláč
f44584fa10 extended configure with --enable-profiling for compiling code with gcov info
extended Makefile with targets:
  cov-reset - reset counters
  cov       - generete report to covhtml subdirectory
  covd      - generate report to covhtml-DATE-TIME subdirectory
2008-06-27 15:35:09 +00:00
Alasdair Kergon
7b32165614 Fix up cache for PVs without mdas after consistent VG metadata is processed. 2008-06-27 15:18:31 +00:00
Alasdair Kergon
b0dc94d187 Update validation of safe mirror log type conversions in lvconvert. (brassow) 2008-06-26 23:05:11 +00:00
Alasdair Kergon
0383c4e1d8 Fix lvconvert to disallow snapshot and mirror combinations. (mpatocka) 2008-06-26 21:38:58 +00:00
Alasdair Kergon
a8c5758222 Underline longer report help text headings. 2008-06-25 19:52:52 +00:00
Alasdair Kergon
a7fabfd8cb Fix reporting of LV fields alongside unallocated PV segments. 2008-06-25 16:52:27 +00:00
Dave Wysochanski
5d5b575d16 Test script cleanup. 2008-06-25 16:51:26 +00:00
Alasdair Kergon
ac1373653c post-release 2008-06-25 14:44:00 +00:00
Alasdair Kergon
b097aa787b pre-commit 2008-06-25 14:24:17 +00:00
Alasdair Kergon
723be0fe69 Align struct memblock in dbg_malloc for sparc. 2008-06-25 14:10:33 +00:00
Alasdair Kergon
f0597a03de Cope with missing field values. 2008-06-25 00:10:36 +00:00
Alasdair Kergon
65f0656f54 Add --rows to dmsetup. 2008-06-24 22:53:48 +00:00
Alasdair Kergon
507ece15a5 Add --rows to reports. 2008-06-24 22:48:53 +00:00
Alasdair Kergon
30be4d1613 Add --unquoted to reporting tools. 2008-06-24 21:21:04 +00:00
Alasdair Kergon
366e89bda0 dmsetup --unquoted 2008-06-24 20:16:47 +00:00
Dave Wysochanski
f159c3f768 Refactor pv_create() to take cmd_context - no functional change. 2008-06-24 20:10:32 +00:00
Dave Wysochanski
8506d1d567 Suppress invalid 'sb_offset' compiler warning (FC8) with uninitialized_var().
device/dev-md.c:61: warning: ‘sb_offset’ may be used uninitialized in this function
2008-06-23 19:26:21 +00:00
Dave Wysochanski
111829da46 Add uninitialized_var macro to suppress invalid compiler warnings.
One such warning is seen on fedora9 gcc compiler:
/metadata.c:1923: warning: 'results' may be used uninitialized in this function
2008-06-23 19:04:34 +00:00
Dave Wysochanski
605798073e Suppress 'sb_offset' compiler warning by using enum for md superblock versions.
The warning is bogus and is only seen on certain versions of gcc.
However using the enum does seem to clarify the intent of the code - only
3 possible md minor superblock versions.

Related compiler warning:
device/dev-md.c:53: warning: 'sb_offset' may be used uninitialized in this function
2008-06-23 14:54:50 +00:00
Jim Meyering
8320f2b094 lvm2_run: don't return uninitialized for _memlock_inc or _memlock_dec
* tools/lvmcmdlib.c: Initialize "ret".  Also avoid useless string
comparison.
2008-06-23 09:27:45 +00:00
Jim Meyering
df0d8d809b configure: regenerate 2008-06-23 09:25:57 +00:00
Jim Meyering
062886df64 avoid link failure when configuring without --enable-cmdlib
* configure.in (LVM2CMD_LIB): Define if --enable-cmdlib.
* dmeventd/mirror/Makefile.in (CLDFLAGS): Use $(LVM2CMD_LIB) rather
than hard-coding -llvm2cmd.
* dmeventd/snapshot/Makefile.in (CLDFLAGS): Likewise.
2008-06-23 09:25:08 +00:00
Jim Meyering
148ea3aaa8 avoid link failure when configuring without --enable-readline
* configure.in: Define READLINE_SUPPORT not when processing
--enable-readline or --disable-readline, but rather only after
determining that readline support is desired and the readline
library is available/usable.
2008-06-23 09:23:48 +00:00
Christine Caulfield
ab5f66c13a Make clvmd return immediately if other nodes are down in an openais cluster. 2008-06-20 12:46:21 +00:00
Christine Caulfield
e65ffb8e68 Make clvmd return immediately if other nodes are down in a gulm cluster.
bz#447799
2008-06-20 10:58:28 +00:00
Zdeněk Kabeláč
949c1ab517 Improve/Fix read ahead 'auto' calculation for stripe_size
Fix lvchange output for -r auto setting if auto is already set
Add testcase for read ahead
2008-06-18 11:32:14 +00:00
Jim Meyering
946d8ee046 avoid compiler warning about cast in OFFSET_OF macro
* dmsetup/dmsetup.c (OFFSET_OF): Use an equivalent definition
that does not cast a pointer value to a narrower type.
2008-06-18 10:19:25 +00:00
Dave Wysochanski
c54a8a2e10 Fix identifier 'error_message_produced' used ambiguously.
Related compiler warning:
log/log.c:242: warning: declaration of 'error_message_produced' shadows a global declaration
../include/log.h:98: warning: shadowed declaration is here
2008-06-17 14:14:00 +00:00
Dave Wysochanski
31177e4f85 Trivial fix to lvcreate man page for --mirrorlog option. 2008-06-16 14:16:02 +00:00
Jim Meyering
750f81b4b5 Begin syncing configure.in for merge/unification with device-mapper. 2008-06-13 14:37:18 +00:00
Jim Meyering
987ff02a45 Don't deref uninitialized log_lv upon failed mirror addition.
* mirror.c (add_mirror_images): Ensure that log_lv is initialized.
2008-06-13 12:15:55 +00:00
Christine Caulfield
f5adaf813c Don't call openlog for every invocation of debuglog.
Patch from Masatake YAMATO
2008-06-13 07:44:14 +00:00
Alasdair Kergon
78ff7dc7f0 Add --force to lvextend and lvresize. 2008-06-12 13:24:02 +00:00
Milan Broz
d1fced3324 Fix vgchange to not activate mirror leg and log volumes directly. 2008-06-12 11:49:46 +00:00
Jim Meyering
e7df9c289b Makefile.in: correct distclean rule
* Makefile.in (SUBDIRS): Remove long-unused test/* names.
(SUBDIRS) [distclean]: Append "test".
Discovered with Zdeněk Kabeláč.
2008-06-12 09:48:45 +00:00
Jim Meyering
a78d7231a9 break (rather than return) so we have only one point of return
* tools/toollib.c (process_each_segment_in_lv): Upon sigint_caught,
break rather than returning ret_max.  No semantic change.
2008-06-11 15:02:52 +00:00
Zdeněk Kabeláč
ba7ae0002e copy vgid only when volume group is present in import_pool_pv 2008-06-11 13:14:41 +00:00
Alasdair Kergon
a090f7b839 post-release 2008-06-11 12:14:41 +00:00
Alasdair Kergon
34ed15a987 pre-release 2008-06-11 12:08:19 +00:00
Alasdair Kergon
cacec4c910 Fix tracking of validity of PVs with no mdas in lvmcache. 2008-06-11 11:02:05 +00:00
Dave Wysochanski
3e47d4e65b Fix return values for reporting commands when run with no PVs, LVs, or VGs.
The new error checking code caught some commands that were returning '0' as
an exit status for success.  This is incorrect and resulted in a benign error
message displayed (see below).  As of today, all commands should return a
value defined in lib/commands/errors.h (1-5).  This results in an exit code of
0 on success, or > 0 on failure (as stated in the lvm.8 man page).

Before change:
1. Make sure no PVs are on the system
2. Run 'pvs'
  Command failed with status code 0.

After change:
<no output>
2008-06-10 20:07:04 +00:00
Dave Wysochanski
8b42fa150b Add ommitted unlock_vg() call when sigint_caught() during vg processing.
Specific test case:
1. pvcreate /dev/loop1; vgcreate vg1 /dev/loop1; lvcreate -L 64M -n lv1 vg1
2. vgremove vg1 (will prompt user)
3. CTRL-C
Code will exit with:
Do you really want to remove volume group "vg2" containing 2 logical volumes? [y/n]:
  Volume group "vg2" not removed
  Command failed with status code 5.
  Internal error: Volume Group vg2 was not unlocked
  Device '/dev/loop1' has been left open.

After change:
Do you really want to remove volume group "vg2" containing 2 logical volumes? [y/n]:
  Volume group "vg2" not removed
  Command failed with status code 5.
2008-06-10 15:25:38 +00:00
Zdeněk Kabeláč
60e660b9c7 Fix wrong free_count on imported volume group from pool device
Fix segfault when calling pvcreate on the pool device
2008-06-10 14:55:14 +00:00
Alasdair Kergon
fe74f013e3 Fix inverted no_flush debug message. (mpatocka) 2008-06-10 11:19:19 +00:00
Alasdair Kergon
24c0c70f90 Fix segfault after _free_vginfo by remembering to remove vginfo from list. 2008-06-09 16:22:33 +00:00
Dave Wysochanski
757f91ca89 Add simple test case to repro pvs segfault with duplicate vgnames. 2008-06-09 15:31:58 +00:00
Alasdair Kergon
5c34f7847e bring list.h into line with lvm2 2008-06-08 14:53:51 +00:00
Alasdair Kergon
de456f014e Tweak detection of invalid fid after changes to PVs in VG in _vg_read. 2008-06-08 14:18:44 +00:00
Alasdair Kergon
d29565066d Revert assuming precommitted metadata is live when activating (unnecessary). 2008-06-08 11:33:15 +00:00
Alasdair Kergon
4d52c9233b . 2008-06-06 20:45:41 +00:00
Alasdair Kergon
6da1ca0cb9 rename some config vars 2008-06-06 20:44:35 +00:00
Alasdair Kergon
2f02f1518a Bring configure.in into line with the lvm2 version. 2008-06-06 20:33:13 +00:00
Alasdair Kergon
e8863707de Drop cached metadata for disappearing VG in vgmerge. 2008-06-06 19:32:35 +00:00
Alasdair Kergon
6a336dfc69 post-release 2008-06-06 19:28:35 +00:00
Alasdair Kergon
35dec1b9e4 pre-release 2008-06-06 19:09:19 +00:00
Alasdair Kergon
f148280c99 switch to single quotes rather than double for nameprefixes 2008-06-06 19:07:47 +00:00
Alasdair Kergon
599fe39749 nameprefixes 2008-06-06 18:53:26 +00:00
Alasdair Kergon
44f3fcb238 change --prefixes to --nameprefixes 2008-06-06 18:53:08 +00:00
Alasdair Kergon
af40fdb285 back out unnecessary changes for this release 2008-06-06 17:36:19 +00:00
Alasdair Kergon
9daf8b825c pre-release 2008-06-06 17:24:28 +00:00
Alasdair Kergon
ef5d8ce367 cleaner LCK_LV decoding 2008-06-06 16:37:51 +00:00
Alasdair Kergon
4a199ab23b cache dropping needs to use old name not new
rename variable to reduce confusion
2008-06-06 16:13:35 +00:00
Jim Meyering
6f0f5a569d * lvm-utils.sh (init_root_dir_): Correct a diagnostic.
Author: Jim Meyering <meyering@redhat.com>
2008-06-06 13:48:57 +00:00
Alasdair Kergon
3172fbfde6 Drop cached metadata when renaming a VG. 2008-06-06 13:04:44 +00:00
Alasdair Kergon
e97a07a505 fix _free_vginfo not to remove a ref to a *different* vginfo from the vgid cache 2008-06-06 12:43:40 +00:00
Alasdair Kergon
6579ad92da cope with volatile vginfo in vg_read 2008-06-06 11:12:50 +00:00
Alasdair Kergon
ec2fad0cfa Allow for vginfo changing during _vg_read. 2008-06-06 09:48:04 +00:00
Alasdair Kergon
6196ac7995 Initialise params buffer to empty string in _emit_segment. 2008-06-05 19:10:35 +00:00
Alasdair Kergon
095a861018 Decode numbers in clvmd debugging output. 2008-06-05 14:24:28 +00:00
Alasdair Kergon
2449ed7765 Add missing deactivation after activation failure in lvcreate -Zy. 2008-06-05 13:38:30 +00:00
Alasdair Kergon
117a0408d6 When activating, if precommitted metadata is still cached, assume it's live. 2008-06-05 13:06:39 +00:00
Alasdair Kergon
a54b0223a3 When removing LV symlinks, skip any where the VG name is not determined. 2008-06-05 12:45:55 +00:00
Alasdair Kergon
44ee708ba5 Drop metadata cache if update fails in vg_revert or vg_commit. 2008-06-03 17:56:54 +00:00
Alasdair Kergon
58a20d0fb6 Correct config file line numbers in messages when parsing comments. (kabi) 2008-06-03 17:51:04 +00:00
Alasdair Kergon
063078a02d suppress warning on silent failure with ECMD_PROCESSED 2008-06-03 17:48:13 +00:00
Dave Wysochanski
01402fea50 Trivial fix to lvchange man pg for consistency. 2008-06-02 15:54:32 +00:00
Alasdair Kergon
b7fc2d1147 In script-processing mode, stop if any command fails.
Warn if command exits with non-zero status code without a prior log_error.
2008-05-30 15:27:44 +00:00
Alasdair Kergon
43eeb7011c fix setpriority int error 2008-05-28 23:12:45 +00:00
Alasdair Kergon
d7901a4220 Avoid spurious duplicate VG messages referring to VGs that are gone.
(untested)
2008-05-28 22:27:47 +00:00
Alasdair Kergon
0c6271dabc Skip add_dev_node when ioctls disabled.
Make dm_hash_iter safe against deletion.
Accept a NULL pointer to dm_free silently.
2008-05-21 16:14:46 +00:00
Alasdair Kergon
2d4cf0c9f5 Temporarily disable dmeventd mirror monitoring during lvchange --resync. 2008-05-21 14:10:11 +00:00
Alasdair Kergon
0646d0dd91 revert accidental checkin 2008-05-19 20:06:34 +00:00
Alasdair Kergon
83e54b45a5 Refactor some vginfo manipulation code. 2008-05-19 19:49:56 +00:00
Alasdair Kergon
5cd87d3d27 more cleanup 2008-05-09 19:26:58 +00:00
Alasdair Kergon
689d8a80b5 More P_ and V_ lock cleanup. 2008-05-09 18:45:15 +00:00
Alasdair Kergon
b1d82a92e7 Add missing mutex around clvmd lvmcache_drop_metadata library call. 2008-05-09 15:13:20 +00:00
Christine Caulfield
4d65627a50 Fix uninitialised mutex in clvmd if all daemons are not running at startup.
Thanks to Mark Hlawatschek for pointing this out.
2008-05-09 09:59:39 +00:00
Christine Caulfield
ce3a68d817 Make clvmd-cman use a hash rather than an array for node updown info.
This will allow it to cope with very large nodeids such as those
generated by clusters using cman_tool join -X
2008-05-09 07:20:04 +00:00
Alasdair Kergon
409725be24 Avoid unnecessary unlock attempts with LCK_CACHE pseudo-locks. 2008-05-08 18:35:58 +00:00
Alasdair Kergon
b74f74a0d7 When asked to drop cached committed VG metadata, invalidate cached PV labels. 2008-05-08 18:28:27 +00:00
Alasdair Kergon
719d554430 Drop metadata cache before writing precommitted metadata instead of after. 2008-05-08 18:06:58 +00:00
Alasdair Kergon
13f54f4521 remove unused lvmcache_drop_vg prototype 2008-05-08 18:00:47 +00:00
Alasdair Kergon
57dfc9cf42 Don't touch /dev in vgrename if activation is disabled. 2008-04-30 14:34:02 +00:00
Alasdair Kergon
57244a6823 post-release - reinstate incomplete enhancements 2008-04-29 16:11:28 +00:00
Alasdair Kergon
8bdde01bef pre-release (bug fixes only - enhancements excluded) 2008-04-29 15:58:25 +00:00
Zdeněk Kabeláč
09bbd5a472 fixing fsadm usage with older blockdev,blkid,readline tools
fixing lvresize extension code path where size was not set for fsadm
2008-04-29 15:25:28 +00:00
Christine Caulfield
9154a74400 . remove_lock_wait.diff remove the definition of "struct lock_wait",
which is not used since the switch away from async version saLck
. num_nodes should equal to member_list_entries, i.e.
joined_list_entires is 0 when a node leaves the group.

Thanks to Xinwei Hu for the patch.
2008-04-29 08:55:20 +00:00
Christine Caulfield
1399b84b32 The attached patch is a try to make clvmd work correctly on openais stack.
It does 2 things.

1. The cpg_deliver_callback make a compare between target_nodeid and our_nodeid.
It turns out openais set target_nodeid to 0 sometimes. for broadcasting ? I change the behavior so that lvm will process_remote also on target_nodeid == 0

2. The joined_list passed to cpg_confchg_callback doesn't include the already exist nodes in the group, which leads to an incomplete node_hash. I simply add all other nodes in member_list to node_hash also.

Thanks to Xinwei Hu for this patch.
2008-04-28 08:57:11 +00:00
Alasdair Kergon
2ddbb3a8fa Exclude VG_GLOBAL from internal concurrent VG lock counter.
(Avoids 'device left open' warning messages from vgscan etc.)
2008-04-24 02:22:07 +00:00
Dave Wysochanski
e46a6d1cc1 Add test for rhbz440405 - lvconvert -m0 fails incorrectly if all PEs allocated. 2008-04-23 18:27:59 +00:00
Dave Wysochanski
b698ab9011 Fix vgsplit internal counting of snapshot LVs. 2008-04-23 14:33:06 +00:00
Dave Wysochanski
0a2572a5eb Update test function _check_{vg|lv|pv}_field to aid in test debug.
Author: Dave Wysochanski <dwysocha@redhat.com>
2008-04-23 13:02:03 +00:00
Dave Wysochanski
77d049cc3d Fix internal snapshot_count when vgmerge with snapshots in source VG. 2008-04-23 12:53:10 +00:00
Christine Caulfield
7b8f053be2 Simplify locking code by using saLckResourceLock rather than
saLckResourceLockAsync.

Thanks to Xinwei Hu for the patch.
2008-04-23 09:53:49 +00:00
Alasdair Kergon
2c850d5293 Check lv_count in vg_validate.
Fix internal LV counter when a snapshot is removed.
2008-04-22 12:54:33 +00:00
Alasdair Kergon
4056bbf10b Fix metadata corruption writing lvm1-formatted metadata with snapshots. 2008-04-22 11:47:22 +00:00
Alasdair Kergon
896b04a846 Use 'active' for !suspended as the code already uses that. 2008-04-21 16:57:11 +00:00
Alasdair Kergon
93cda8b6ec Add 3 new reporting colums: tables_loaded, readonly, suspended. 2008-04-21 13:16:30 +00:00
Alasdair Kergon
bb5e930684 Add --prefixes to dmsetup
E.g. dmsetup info -c --prefixes

Again, might change the name of this option.
2008-04-21 11:59:22 +00:00
Alasdair Kergon
43761fed2a Add --prefixes to reporting tools for field name prefix output format.
E.g. lvs --prefixes --noheadings --unbuffered --units m --nosuffix

(Used '--prefixes' for now, but I'm looking for a better name.)
2008-04-20 00:15:08 +00:00
Alasdair Kergon
a636299680 Add field name prefix option to reporting functions. 2008-04-20 00:11:08 +00:00
Alasdair Kergon
08e5bd5b72 Calculate string size within dm_pool_grow_object. 2008-04-19 15:50:18 +00:00
Alasdair Kergon
2f057bef5e Fix lvconvert -m0 allocatable space check. 2008-04-18 12:50:24 +00:00
Alasdair Kergon
5ab4f21444 post-release 2008-04-15 15:01:18 +00:00
Alasdair Kergon
9ec26ed481 missing stack 2008-04-15 14:57:12 +00:00
Alasdair Kergon
29c9df1389 pre-release 2008-04-15 14:49:17 +00:00
Milan Broz
867e9c51d4 Drop cached VG metadata before and after committing changes to it. 2008-04-15 14:46:19 +00:00
Alasdair Kergon
0170f7b42a rename P_global to P_#global 2008-04-15 11:36:46 +00:00
Alasdair Kergon
74bb6ead95 Don't attempt remote metadata backups of non-clustered VGs. (2.02.29) 2008-04-14 19:49:12 +00:00
Alasdair Kergon
303388e5cb Don't store fid in VG metadata cache to avoid clvmd segfault. (2.02.34) 2008-04-14 19:24:16 +00:00
Dave Wysochanski
8388779937 Fix vgsplit and vgmerge tests for updated lv counting. 2008-04-11 14:06:16 +00:00
Dave Wysochanski
fc7dfca452 Update vgsplit test to verify loosening of active LV restriction.
This and prior 2 commits resolve Red Hat bz 252041:
Ability to vgsplit an active Volume Group where the split involves only inactive LVs
2008-04-10 21:38:52 +00:00
Dave Wysochanski
e5a1db2392 Update vgsplit to only restrict split with active LVs involved in split.
Existing code will reject a vgsplit if any LVs in the source VG are active.
This patch updates vgsplit to only check LVs involved in the split.
2008-04-10 21:34:53 +00:00
Dave Wysochanski
6790656af6 Add lv_is_active() to determine whether an lv is active.
Handles non-clustered as well as clustered.  For clustered,
the best we can do is try exclusive local activation.  If this
succeeds, we know it is not active elsewhere in the cluster.
Otherwise, we assume it is active elsewhere.
2008-04-10 21:34:18 +00:00
Alasdair Kergon
b7477bdc15 post-release 2008-04-10 20:07:19 +00:00
Alasdair Kergon
ffc61f31de . 2008-04-10 20:02:04 +00:00
Alasdair Kergon
e612871ea7 more pre-release cleanup 2008-04-10 19:59:43 +00:00
Alasdair Kergon
7f40f09f10 fix 3rd copy 2008-04-10 19:16:35 +00:00
Alasdair Kergon
456e42257c make list_move consistent with other list fns 2008-04-10 19:14:27 +00:00
Dave Wysochanski
8618c271cf Update vgsplit tests that count LVs for adjusted LV counting. 2008-04-10 18:55:40 +00:00
Alasdair Kergon
72ca1ccc23 . 2008-04-10 18:53:36 +00:00
Alasdair Kergon
075b4bef3f pre-release 2008-04-10 18:19:49 +00:00
Alasdair Kergon
b59fce4393 post-release 2008-04-10 18:04:31 +00:00
Alasdair Kergon
8674a25eb8 pre-release 2008-04-10 18:00:45 +00:00
Alasdair Kergon
10bf8fd2cd Fix vgdisplay 'Cur LV' field to match lvdisplay output.
Fix lv_count report field to exclude hidden LVs.
2008-04-10 17:19:02 +00:00
Dave Wysochanski
57cb22ff3c Add vg_is_clustered() helper function.
Should be no functional change.
2008-04-10 17:09:32 +00:00
Dave Wysochanski
0162abdcae Minor vgsplit cleanups. 2008-04-10 02:15:56 +00:00
Dave Wysochanski
5801171518 Add _move_one_lv() helper function for vgsplit. 2008-04-10 01:30:22 +00:00
Dave Wysochanski
bf1edbd1e2 Fix lvm tool exit code display in some tests. 2008-04-10 01:06:48 +00:00
Dave Wysochanski
a8484d987d Add vgsplit tests to verify mirror is not moved unnecessarily. 2008-04-09 21:10:13 +00:00
Dave Wysochanski
9b2147f608 Fix vgsplit to only move hidden 'snapshotN' LVs when necessary.
This bug has been around for a long time as far as I can tell.
Without this fix, a vgsplit would unconditionally move the
'hidden/internal' snapshot LVs, and result in corrupted metadata
in the following case:
vg1: contains lv1, lv1snap, both on pvset1
vg1: contains lv2, on pvset2

"vgsplit vg1 vg2 pvset2"
would result in "snapshot0" hidden LV being moved to vg2, and
the origin and cow being left in vg1.  The tools detect the
corruption in vg2, but not in vg1.
2008-04-09 20:56:06 +00:00
Dave Wysochanski
32530b378e Update vgsplit tests for lvnames on the cmdline. 2008-04-09 14:47:34 +00:00
Dave Wysochanski
a42905efa6 Update vgsplit man page to reflect lvnames on cmdline. 2008-04-09 14:39:55 +00:00
Dave Wysochanski
c59745f9dd Update vgsplit to take "-n LogicalVolumeName" on the commandline. 2008-04-09 13:47:13 +00:00
Alasdair Kergon
b4ad9a5d08 Use clustered mirror log with pvmove in clustered VGs, if available. 2008-04-09 12:56:34 +00:00
Alasdair Kergon
3ead7a38b1 Fix some pvmove error status codes. 2008-04-09 12:45:32 +00:00
Dave Wysochanski
bf90435200 *** empty log message *** 2008-04-08 22:02:16 +00:00
Dave Wysochanski
9c181fa3d3 Fix vgsplit error display - fully remove log_suppress.
Author: Dave Wysochanski <dwysocha@redhat.com>
2008-04-08 21:47:54 +00:00
Dave Wysochanski
3af0b1eb90 Fix vgsplit error paths to release vg_to lock. 2008-04-08 21:38:09 +00:00
Alasdair Kergon
7110c318ee Indicate whether or not VG is clustered in vgcreate log message.
Mention default --clustered setting in vgcreate man page.
2008-04-08 14:22:13 +00:00
Christine Caulfield
49a552ccdc Add config file overrides to clvmd when it reads the LVs list so that
config items 'command_names' and 'prefix' don't prevent it working.
2008-04-08 13:03:13 +00:00
Alasdair Kergon
57685f17a9 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.
2008-04-08 12:49:21 +00:00
Alasdair Kergon
a1c09a463f create fids for internal orphan VGs 2008-04-07 22:12:37 +00:00
Milan Broz
194121760a Update lvmcache VG lock state for all locking types now. 2008-04-07 19:17:29 +00:00
Milan Broz
6a987d46bf Fix output if overriding command_names on cmdline. 2008-04-07 13:53:26 +00:00
Milan Broz
e3db0b39b9 Add detection of clustered mirror log capability.
Currently only check for kernel module presence.
2008-04-07 10:23:47 +00:00
Dave Wysochanski
4d4f0ee188 Add check to vg_commit() to ensure lock is held before writing new VG metadata. 2008-04-04 15:41:20 +00:00
Milan Broz
ac7334c167 Add validation of LV name to pvmove -n. 2008-04-04 11:59:31 +00:00
Christine Caulfield
e7bdd69af0 If lvm.conf was touched, clvmd attempted to update the toolcontext
but only did half of the job. It now shares the do_refresh_cache()
function that vgscan invokes.
2008-04-04 08:53:47 +00:00
Alasdair Kergon
fefc655969 Add some basic internal VG lock validation. 2008-04-03 18:56:40 +00:00
Alasdair Kergon
4dceaef60e . 2008-04-03 14:40:34 +00:00
Alasdair Kergon
6fc10dd3ae . 2008-04-03 14:32:31 +00:00
Alasdair Kergon
1ecd05a584 fix vd->virtblk 2008-04-03 10:29:00 +00:00
Alasdair Kergon
976acaca31 enable vg metadata cache by default 2008-04-02 21:31:14 +00:00
Alasdair Kergon
b4e5131d59 Add per-command flags to control which commands use the VG metadata cache. 2008-04-02 21:23:39 +00:00
Dave Wysochanski
49f7cfefd7 Fix vgsplit locking and remove unneeded error messages when split into new VG.
When vg_lock_and_read() calls were added, they were done so incorrectly for
the destination VG (vg_to).  This resulted in the VG lock not obtained when
a new VG was the destination (vg_lock_and_read() would fail in the vg_read()
clause, which would then release the lock before returning NULL), and could
result in corrupted destination VG.

The fix was to put back the original lock_vol() and vg_read() calls for 'vg_to'.
The failure of vg_read() indicates "vg does not exist", and we key off that
to determine whether we are dealing with a new or existing VG as the
destination.

The first two error messages were also the result of the incorrect
vg_lock_and_read() calls:
  Volume group "new" not found
  cluster request failed: Invalid argument
  New volume group "new" successfully split from "vg"

Fixes https://bugzilla.redhat.com/show_bug.cgi?id=438249
2008-04-02 19:30:12 +00:00
Dave Wysochanski
fc365092f6 Suppress "Volume group not found" message when vgsplit of new VG. 2008-04-02 13:08:49 +00:00
Dave Wysochanski
7f26240442 Fix lvresize to dump stack if vg_lock_and_read() fails.
Necessary because vg_lock_and_read() may fail silently if the vg_check_status() call fails.

Also add lvresize tests.
2008-04-02 12:17:30 +00:00
Alasdair Kergon
db559bb20a Cache VG metadata internally while VG lock is held. 2008-04-01 22:40:13 +00:00
Dave Wysochanski
52850faa15 Fix redundant lvresize message if vg doesn't exist.
BEFORE:
tools/lvm lvresize -l +4 vg22/lv1linear
  Volume group "vg22" not found
  Volume group vg22 doesn't exist

AFTER:
tools/lvm lvresize -l +4 vg22/lv1linear
  Volume group "vg22" not found
2008-04-01 22:15:16 +00:00
Christine Caulfield
57d9a6c836 Fix another allocation bug with clvmd and large node IDs.` 2008-04-01 15:01:30 +00:00
Dave Wysochanski
752c880bfc Add find_lv_in_lv_list() and find_pv_in_pv_list().
Update _add_pvs() to call find_pv_in_pv_list().
2008-03-28 19:08:23 +00:00
Dave Wysochanski
d83a354781 Enhance test debugging by updating verbose mode of check_*_field_ functions.
Author: Dave Wysochanski <dwysocha@redhat.com>
2008-03-28 18:02:22 +00:00
Christine Caulfield
17dd81336d Fix a couple of uninitialised variables. The newfd one could cause
some obscure hangs.
2008-03-28 12:58:09 +00:00
Dave Wysochanski
eaa46a2575 Add vgmerge tests. 2008-03-26 18:03:35 +00:00
Dave Wysochanski
fc0ec1e71e Use list_move() in applicable places. 2008-03-26 17:26:32 +00:00
Dave Wysochanski
fb2f92df1d Add pvseg_is_allocated() for identifying a PV segment allocated to a LV. 2008-03-26 16:48:10 +00:00
Dave Wysochanski
74adbb77b7 Add list_move() support function for list manipulation. 2008-03-26 16:20:54 +00:00
Dave Wysochanski
788e544e1d Add 'is_reserved_lvname()' helper function.
Very similar to apply_lvname_restrictions but without the error messages.
2008-03-25 15:24:59 +00:00
Alasdair Kergon
368a0d4d2d Correct command name in lvmdiskscan man page. 2008-03-25 12:37:48 +00:00
Christine Caulfield
962b7222d0 When reallocating the node IDs array, make it bigger rather than smaller! 2008-03-25 10:41:59 +00:00
Dave Wysochanski
17c1f54369 Add vgsplit tests to verfy attributes of new VG match source VG.
Author: Dave Wysochanski <dwysocha@redhat.com>
2008-03-23 15:40:35 +00:00
Dave Wysochanski
33ae38e71b Fixup vgsplit tests in preparation for vgsplit changes. 2008-03-21 22:00:29 +00:00
Dave Wysochanski
ef58af4bf1 Update vgsplit tests to execute twice (existing and new VG as destination). 2008-03-21 21:14:38 +00:00
Dave Wysochanski
3fad2db2f8 Add LV and VG name restrictions to the lvm man page.
Original patch by: Gerrard Geldenhuis <Gerrard.Geldenhuis@datacash.com>
2008-03-20 18:34:29 +00:00
Alasdair Kergon
9feaeb28ca preparation for vg cache 2008-03-17 16:51:31 +00:00
Christine Caulfield
0075364715 Fix potential thread deadlock.
Also make local sockets non-blocking.
2008-03-17 09:37:47 +00:00
Dave Wysochanski
99c5da5da5 Const cleanups in find_* functions. 2008-03-13 22:51:24 +00:00
Alasdair Kergon
22c957bc20 Refactor text format initialisation into _init_text_import. 2008-03-13 12:33:22 +00:00
Milan Broz
3316d59910 Add metadata test for escaping double quotes in device names (bz431474). 2008-03-12 17:34:58 +00:00
Alasdair Kergon
a109ce1eca 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.
2008-03-12 16:03:22 +00:00
Alasdair Kergon
e581a78d65 Use return_0 in a couple more places.
Correct a function name typo in _line_append error message.
2008-03-10 18:51:27 +00:00
Christine Caulfield
3c78f9900c Include limits.h so it compiles with newer headers. 2008-03-06 08:41:05 +00:00
Alasdair Kergon
bd606943e6 add vd to filters 2008-03-05 18:15:04 +00:00
Dave Wysochanski
6381666df4 Update vgsplit tests.
- Add validation on pv_count, lv_count, and snap_count after split
NOTE: Some of these counts are misleading.  If you compare "lvs" output
with these counts you will be left scratching your head what a "logical volume"
really is.  ;-)
2008-03-04 22:49:00 +00:00
Dave Wysochanski
736f1aa301 Update vgsplit tests.
- Divide into 'usage' and 'operation' tests.
- Add operation tests for specific LV types.
2008-03-04 19:48:32 +00:00
Dave Wysochanski
b1a4eac7a8 Refactor _move_pv() in vgsplit.
Should be no functional change.
2008-02-29 00:13:48 +00:00
Dave Wysochanski
8226a5276b Add vgsplit test to check failure when PV not in source volume group. 2008-02-29 00:09:21 +00:00
Dave Wysochanski
77ad0bb12e Fix t-vgsplit-operation.sh lv2-3 definitions to include test signature. 2008-02-28 17:39:47 +00:00
Dave Wysochanski
9412b42206 Fix t-vgsplit-operation.sh lv1 definition to include test signature. 2008-02-28 16:48:09 +00:00
Alasdair Kergon
2a91d87074 Fix resetting of MIRROR_IMAGE and VISIBLE_LV after removal of LV. 2008-02-22 13:28:29 +00:00
Alasdair Kergon
4a23617d79 Fix remove_layer_from_lv to empty the LV before removing it. (2.02.30) 2008-02-22 13:22:44 +00:00
Alasdair Kergon
0e2ceed74d Add missing no-longer-used segs_using_this_lv test to check_lv_segments. 2008-02-22 13:22:21 +00:00
Jim Meyering
ed56aed8eb Remove redundant if-before-free tests. 2008-02-15 14:14:58 +00:00
Jim Meyering
8d909cbdc0 Remove redundant if-before-free tests in clvmd.c. 2008-02-15 14:12:32 +00:00
Jim Meyering
bf98943cbb is_orphan: make parameter "const" to avoid compiler warning 2008-02-13 20:01:48 +00:00
Alasdair Kergon
6ff4552be2 Fix lvconvert detection of mirror conversion in progress. 2008-02-12 13:29:08 +00:00
Alasdair Kergon
1c7eb79370 Avoid automatic lvconvert polldaemon invocation when -R specified. 2008-02-12 13:26:53 +00:00
Dave Wysochanski
f095a75f1e Reflect actual default setting of preferred_names in example.conf and
update comments.
2008-02-11 16:57:40 +00:00
Alasdair Kergon
f70af6018c Fix 'pvs -a' to detect VGs of PVs without metadata areas. 2008-02-06 16:09:51 +00:00
Alasdair Kergon
71b3b1ff4c split orphan VG by format type 2008-02-06 15:47:28 +00:00
Zdeněk Kabeláč
d9fefa0c6c Fix lvresize to support /dev/mapper prefix in the lvname
Fix unfilled paramater passed to fsadm from lvresize
  Update fsadm to call lvresize if the partition size differs (with option -l)
  Fix fsadm to support vg/lv name (like the rest of lv-tools)
2008-02-06 12:45:32 +00:00
Patrick Caulfield
3bfe922381 Update usage message for clvmd.
Fix clvmd man page printing <br>, clarified debug options.
2008-02-05 09:38:04 +00:00
Dave Wysochanski
a85cf17bf1 Fix default preferred_names filter to use /dev/mapper/mpath devices.
If these devices exist, we should be using them for multipath rather than any
underlying device names.
Reference: http://kbase.redhat.com/faq/FAQ_96_11196.shtma
bz195685
2008-02-04 20:26:14 +00:00
Alasdair Kergon
dbb5a09918 post-release 2008-01-31 12:41:13 +00:00
Alasdair Kergon
93e5097f20 pre-release 2008-01-31 12:36:58 +00:00
Alasdair Kergon
dd53f2dc83 a couple more compiler warnings 2008-01-31 12:35:31 +00:00
Alasdair Kergon
2b83c80593 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.
Add mirror names test script.
2008-01-31 12:19:36 +00:00
Alasdair Kergon
6930f60c06 only read labels once between each lock event 2008-01-30 16:18:37 +00:00
Alasdair Kergon
376b76e75c undo a few 'stack' moves 2008-01-30 14:17:29 +00:00
Alasdair Kergon
1ddd4509dc Some whitespace tidy-ups. 2008-01-30 14:00:02 +00:00
Alasdair Kergon
6af3f4f4cf Use stack return macros throughout. 2008-01-30 13:19:47 +00:00
Alasdair Kergon
6726c5f958 Rely upon internally-cached PV labels while corresponding VG lock is held. 2008-01-29 23:45:48 +00:00
Alasdair Kergon
d5a9c43cb2 post-release 2008-01-29 12:02:04 +00:00
Alasdair Kergon
19a5a6a4eb pre-release 2008-01-29 11:48:11 +00:00
Alasdair Kergon
617a599ee9 Fix two check_lv_segments error messages to show whole segment. 2008-01-26 00:30:28 +00:00
Alasdair Kergon
25e2d4da44 . 2008-01-26 00:25:45 +00:00
Alasdair Kergon
ad2e7218cb Refactor mirror log attachment code. 2008-01-26 00:25:04 +00:00
Alasdair Kergon
917637fa9b Fix internal metadata corruption in lvchange --resync. 2008-01-26 00:13:45 +00:00
Alasdair Kergon
b595ee1c0b suppress compiler warning 2008-01-22 16:02:26 +00:00
Alasdair Kergon
c8260a4a56 update 2008-01-22 15:58:31 +00:00
Dave Wysochanski
d2eaff3204 Fix vgsplit test mode 2008-01-22 03:49:39 +00:00
Dave Wysochanski
b65f5a844f Fix vgsplit tests 12-13 2008-01-22 03:30:14 +00:00
Dave Wysochanski
95a69f99ba Fix vgsplit - print different message on successful split of existing / new vg
Fix vgsplit - fix a couple error paths that forgot to call unlock_vg
Update vgsplit test cases
2008-01-22 03:25:45 +00:00
Dave Wysochanski
71d609895a Fix vgsplit - print error if vgcreate option given w/existing vg destination
Fix vgsplit - reject split if metadata types or clustered attributes differ
Fix vgsplit - remove physicalextentsize option
Add vgsplit test cases
2008-01-22 02:48:53 +00:00
Patrick Caulfield
9229630447 Remove redundant cnxman-socket.h file. 2008-01-21 14:07:46 +00:00
Alasdair Kergon
eb18a0b7dc Fix pvs, vgs, lvs error exit status on some error paths.
(note -o help is now considered error)
2008-01-20 01:23:46 +00:00
Alasdair Kergon
05ed5c0d74 Use log_warn for reporting field help text instead of log_print. 2008-01-20 01:14:38 +00:00
Alasdair Kergon
41330ecc5e clarify 2008-01-19 12:36:37 +00:00
Alasdair Kergon
16fbcc6e36 post-release 2008-01-19 12:30:55 +00:00
Alasdair Kergon
d87da9c7de Pre-release 2008-01-19 12:28:03 +00:00
Alasdair Kergon
94563b6017 Fix lvcreate --nosync not to wait for non-happening sync. 2008-01-18 22:02:37 +00:00
Alasdair Kergon
34d22f7047 add lvconvert messages 2008-01-18 22:00:46 +00:00
Alasdair Kergon
e24d996fbe Fix lvcreate -M1 readahead. 2008-01-18 21:56:39 +00:00
Dave Wysochanski
9b52617919 Add a test case for 'vgreduce --removemissing' on stacked mirror 2008-01-17 18:29:36 +00:00
Dave Wysochanski
efc1d46c89 More test script fixes. 2008-01-17 18:05:57 +00:00
Alasdair Kergon
9397833ceb pre-release review cleanups 2008-01-17 17:17:09 +00:00
Dave Wysochanski
e9433e83cd Minor test fix 2008-01-17 15:56:53 +00:00
Alasdair Kergon
f3c58100a0 fix default stripesize 2008-01-17 15:53:01 +00:00
Alasdair Kergon
8900231d99 fix default extent_size 2008-01-17 15:31:18 +00:00
Alasdair Kergon
c7a63b8a2b pre-release 2008-01-17 15:02:59 +00:00
Alasdair Kergon
90e90672a4 rename lv_remap_error 2008-01-17 13:54:05 +00:00
Alasdair Kergon
fa51e5c762 mirror log stuff 2008-01-17 13:37:51 +00:00
Alasdair Kergon
911f55d005 lvconvert/vgreduce fixes 2008-01-17 13:13:54 +00:00
Dave Wysochanski
d30eb4e570 Fixup vgsplit man page 2008-01-17 03:18:18 +00:00
Dave Wysochanski
67bcfb6947 Fix descriptions in the newly added test cases 2008-01-17 02:20:48 +00:00
Alasdair Kergon
3915a61b1e another lvconvert fix 2008-01-16 22:54:49 +00:00
Alasdair Kergon
c170d321e8 fix a _get_vgs return 2008-01-16 22:52:46 +00:00
Dave Wysochanski
2802c476ee Fix 'make check' runnable with recent versions of dmsetup.
Fix 'make check' to use DMDIR to check DM_DEV_DIR support in dmsetup.
Add basic test cases for mirrored LV.
Add basic test cases for lvconvert mirror.
Add basic test cases for pvmove.
	Jun'ichi Nomura <j-nomura@ce.jp.nec.com>

Add new vgsplit and vgmerge tests.
	Dave Wysochanski <dwysocha@redhat.com>
2008-01-16 21:21:22 +00:00
Alasdair Kergon
1050cebf7f additional safety check on new segment list 2008-01-16 20:00:01 +00:00
Dave Wysochanski
dad73465fc Create vgs_are_compatible() fn to check whether vgs are compatible for merging.
Add new vgmerge and vgsplit tests to check rejection of incompatible vgs.
Cleanup comments.
Bugzilla: bz251992

---
 lib/metadata/metadata-exported.h |    3 +
 lib/metadata/metadata.c          |   89 +++++++++++++++++++++++++++++++++-
 test/t-vgmerge-usage.sh          |  101 +++++++++++++++++++++++++++++++++++++++
 test/t-vgsplit-operation.sh      |   20 +++++++
 tools/vgmerge.c                  |   69 --------------------------
 tools/vgsplit.c                  |    5 -
 6 files changed, 215 insertions(+), 72 deletions(-)
2008-01-16 19:54:39 +00:00
Alasdair Kergon
8e2ac98fe2 adjust mirror log error message 2008-01-16 19:50:23 +00:00
Alasdair Kergon
9aaf0c36d5 fix to earlier checkin 2008-01-16 19:40:42 +00:00
Alasdair Kergon
1cb07e9cfd cope with stacked LVs as well as PVs when deciding which bits of mirrors to remove 2008-01-16 19:38:39 +00:00
Alasdair Kergon
f1ccdf25b1 allow a mirror to contain only one mimage 2008-01-16 19:18:51 +00:00
Alasdair Kergon
6dca497b27 fix mirror log manipulation during lv convert 2008-01-16 19:16:48 +00:00
Alasdair Kergon
42a83262a1 export find_temporary_mirror() 2008-01-16 19:13:51 +00:00
Alasdair Kergon
63ee9cbee6 move removable_pvs checking 2008-01-16 19:11:39 +00:00
Alasdair Kergon
3862f8ca7c reorder funcs 2008-01-16 19:09:35 +00:00
Alasdair Kergon
4ada7cffd0 Maintain lists of stacked LV segments using each LV. 2008-01-16 19:00:59 +00:00
Alasdair Kergon
a664ce4298 use scan_vgs_for_pvs to detect non-orphans without MDAs 2008-01-16 18:15:26 +00:00
Dave Wysochanski
8d7b6c6905 Remove unused 'list' param from vgsplit - conflict with maxlogicalvolumes param.
Initialize lvm command getopt buffer to zero before building options string.
Bugzilla: bz251992

---
 man/vgsplit.8      |    3 +--
 tools/commands.h   |    3 +--
 tools/lvmcmdline.c |    1 +
 3 files changed, 3 insertions(+), 4 deletions(-)
2008-01-16 17:14:56 +00:00
Alasdair Kergon
16d22d404a revert temp change 2008-01-16 15:26:40 +00:00
Alasdair Kergon
ccb24d5779 reword 2008-01-16 15:25:10 +00:00
Alasdair Kergon
8795b45cb4 Don't use block_on_error with mirror targets above version 1.12. 2008-01-16 15:24:25 +00:00
Dave Wysochanski
628d3bff45 Move more parameter validation into the library.
Update vgrename to call validate_vg_rename_params().
Fix vgcreate and vgsplit default arguments by adding defaults parameter to
fill_vg_create_params().
Add t-vgrename-usage.sh test.
Bugzilla: bz251992
---
 tools/toollib.c  |   32 ++++++++------------------------
 tools/toollib.h  |    5 ++---
 tools/vgcreate.c |   35 +++++++++++++++++++++--------------
 tools/vgrename.c |   35 ++++++-----------------------------
 tools/vgsplit.c  |   21 ++++++++++++++-------
 5 files changed, 51 insertions(+), 77 deletions(-)
2008-01-15 22:56:30 +00:00
Jonathan Earl Brassow
0336bc9de9 - The automatic log module loading patch proposed for the upstream kernel
works on '-'s, not '_'s.  This is due to the preference to have log
  module file names that do not mix '_'s and '-'s.
2008-01-15 22:48:11 +00:00
Dave Wysochanski
033cb21797 Update WHATS_NEW for vgsplit changes 2008-01-15 20:37:49 +00:00
Alasdair Kergon
09b98a45df lvconvert waits for initial completion by default 2008-01-14 21:11:47 +00:00
Dave Wysochanski
38857ba29e Allow vgcreate options as input to vgsplit when new vg is split destination. 2008-01-14 21:07:58 +00:00
Dave Wysochanski
1c7520ec8f Allow vgsplit into existing vg.
Add vgsplit tests to validate operation for new and existing vg destinations.
2008-01-11 21:43:16 +00:00
Dave Wysochanski
362b9769b2 Fixup lvm man pg 2008-01-11 20:24:25 +00:00
Dave Wysochanski
b2d68bd3d2 Refactor vgsplit for accepting existing vg as destination 2008-01-11 20:17:18 +00:00
Dave Wysochanski
0dc7e635d4 Update lvm man page to enumerate lvm tools. 2008-01-11 19:24:25 +00:00
Dave Wysochanski
80e070a857 Fix warning on conditional compile, unused variable 2008-01-11 17:44:26 +00:00
Dave Wysochanski
cc203245e4 Refactor vgcreate for parameter validation and add tests 2008-01-11 07:02:35 +00:00
Alasdair Kergon
2f9a65fc93 convert_lv 2008-01-10 22:21:44 +00:00
Alasdair Kergon
62738e8001 correct field name 2008-01-10 22:21:25 +00:00
Alasdair Kergon
5ecacf0c7f Add lv_convert field to default lvs output. 2008-01-10 19:25:07 +00:00
Alasdair Kergon
06b103c8d4 Various lvconvert/polldaemon-related fixes from NEC. See lvm-devel
for original patches & explanations.
2008-01-10 18:35:51 +00:00
Petr Rockai
d473b7bca8 Print warning when lvm tools are running as non-root. 2008-01-09 15:55:44 +00:00
Petr Rockai
50a1e81ba7 Amend previous commit. * does not match .files... 2008-01-09 15:33:25 +00:00
Petr Rockai
d9885b1b64 Add snapshot dmeventd library (enables dmeventd snapshot monitoring). 2008-01-09 15:32:19 +00:00
Zdeněk Kabeláč
0a9c8cada2 install conditionally fsadm.8 manpage 2008-01-09 14:17:58 +00:00
Petr Rockai
60f55f8461 Prevent pvcreate from overwriting MDA-less PVs belonging to active VGs. 2008-01-09 00:18:36 +00:00
Zdeněk Kabeláč
7bedaea38f added manpage 2008-01-08 17:01:42 +00:00
Zdeněk Kabeláč
9e4b87e798 readahead at least twice the strip size (same as raid0 driver does) 2008-01-08 16:47:10 +00:00
Zdeněk Kabeláč
95bf59095c added more safety checks
fixed error reporting commands
extended with Exa and Peta support
2008-01-08 16:45:43 +00:00
Milan Broz
e0f34a9720 Fix a segfault if using pvs with --all argument. (2.02.29) 2008-01-07 20:42:57 +00:00
Milan Broz
f3797c2a8e Update --uuid argument description in man pages. 2008-01-04 11:48:40 +00:00
Alasdair Kergon
30cbcccc80 Fix vgreduce PV list processing not to process every PV in the VG. 2008-01-03 19:03:32 +00:00
Alasdair Kergon
f49c0d696f typo 2007-12-28 15:13:38 +00:00
Alasdair Kergon
71f564ee5b lvconvert uses polldaemon now 2007-12-22 12:13:29 +00:00
Alasdair Kergon
4b0950aba5 a few more changes/fixes to recent code 2007-12-22 02:13:00 +00:00
Alasdair Kergon
8c3af822ec auto-collapse layers 2007-12-21 01:08:18 +00:00
Alasdair Kergon
878a207d19 more fixes 2007-12-20 23:12:27 +00:00
Alasdair Kergon
0537ad860a various cleanups in recent patches 2007-12-20 22:37:42 +00:00
Alasdair Kergon
2cdbbb1aea stacked mirror support (incomplete) 2007-12-20 18:55:46 +00:00
Alasdair Kergon
7af977d36b avoid some compiler warnings 2007-12-20 16:49:37 +00:00
Alasdair Kergon
9afff4cf30 Major restructuring of pvmove and lvconvert layer manipulation code 2007-12-20 15:42:55 +00:00
Alasdair Kergon
48ba9734aa post-release 2007-12-20 15:16:14 +00:00
Alasdair Kergon
897fc59f72 pre-release 2007-12-20 15:12:57 +00:00
Alasdair Kergon
947e44ae67 tweak usage text 2007-12-17 14:47:22 +00:00
Alasdair Kergon
e44843beba replace fsadm.c with fsadm.sh 2007-12-17 12:31:50 +00:00
Alasdair Kergon
147482ea69 Build changes to replace fsadm C program with shell script. 2007-12-17 12:23:24 +00:00
Alasdair Kergon
09091c5cf8 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.
2007-12-14 21:53:02 +00:00
Alasdair Kergon
50827a5f69 more readahead node fixes/debug messages 2007-12-14 19:49:27 +00:00
Alasdair Kergon
2d6444c924 Fix deptree to pass new name to _resume_node after a rename. 2007-12-14 17:57:04 +00:00
Alasdair Kergon
1d2675d9aa Add node operation stack debug messages. 2007-12-14 17:26:09 +00:00
Alasdair Kergon
ad98990a8e Report error when empty device name passed to readahead functions. 2007-12-13 02:25:45 +00:00
Alasdair Kergon
8e58c143f2 post-release 2007-12-05 22:48:06 +00:00
Alasdair Kergon
556a4a2395 clarify 2007-12-05 22:45:56 +00:00
Alasdair Kergon
5be987b40f pre-release
N.B. This is a big release and some regressions are inevitable.
2007-12-05 22:19:24 +00:00
Alasdair Kergon
066bc35e69 export can_split parameter until rest of pvmove allocation restructuring gets done 2007-12-05 22:11:20 +00:00
Alasdair Kergon
403779437c round readahead to multiple of page size in tools 2007-12-05 19:24:32 +00:00
Alasdair Kergon
fb806f61d4 Fix minimum readahead debug message. 2007-12-05 18:57:34 +00:00
Alasdair Kergon
6ce306661c post-release 2007-12-05 17:14:30 +00:00
287 changed files with 17734 additions and 9688 deletions

View File

@@ -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.
#
@@ -36,9 +36,10 @@ ifeq ($(MAKECMDGOALS),distclean)
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
@@ -71,3 +72,36 @@ 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)/lib --zerocounters
$(LCOV) -d $(top_srcdir)/tools --zerocounters
lcov: all
$(RM) -rf $(LCOV_REPORTS_DIR)
$(MKDIR_P) $(LCOV_REPORTS_DIR)
$(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)/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

View File

@@ -1 +1 @@
2.02.29-cvs (2007-08-24)
2.02.41-cvs (2008-10-17)

278
WHATS_NEW
View File

@@ -1,5 +1,271 @@
Version 2.02.29 -
==================================
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 +302,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.

View File

@@ -1,10 +1,55 @@
Version 1.02.29 -
=====================================
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 +67,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 +355,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
View File

@@ -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
View File

@@ -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
;;

8157
configure vendored

File diff suppressed because it is too large Load Diff

View File

@@ -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=no
;;
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)
@@ -261,30 +270,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 +306,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,10 +320,27 @@ 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)
@@ -360,10 +369,15 @@ 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 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)
@@ -376,33 +390,35 @@ DMEVENTD=$enableval)
AC_MSG_RESULT($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 -- 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 +428,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 +451,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 +487,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 +515,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 +531,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
################################################################################
@@ -517,25 +555,25 @@ 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="$withval" CPPFLAGS="$CPPFLAGS -I$DMDIR/include"],
[ DMDIR= ])
# Convert a relative dir name to absolute.
@@ -544,6 +582,16 @@ case $DMDIR in
*) DMDIR="`pwd`/$DMDIR" ;;
esac
AC_ARG_WITH(usrlibdir,
[ --with-usrlibdir=DIR],
[ usrlibdir="$withval"],
[ usrlibdir='${prefix}/lib' ])
AC_ARG_WITH(usrsbindir,
[ --with-usrsbindir=DIR],
[ usrsbindir="$withval"],
[ usrsbindir='${prefix}/sbin' ])
################################################################################
dnl -- Ensure additional headers required
if test x$READLINE = xyes; then
@@ -558,11 +606,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))
@@ -590,52 +633,59 @@ if test x$MODPROBE_CMD != x; then
fi
################################################################################
if test "-f VERSION"; then
LVM_VERSION="\"`cat VERSION`\""
else
LVM_VERSION="Unknown"
fi
LVM_VERSION="\"`cat VERSION 2>/dev/null || echo Unknown`\""
################################################################################
AC_SUBST(JOBS)
AC_SUBST(STATIC_LINK)
AC_SUBST(LVM1)
AC_SUBST(POOL)
AC_SUBST(SNAPSHOTS)
AC_SUBST(MIRRORS)
AC_SUBST(OWNER)
AC_SUBST(GROUP)
AC_SUBST(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)
# FIXME: rename to LVM_USE_DMEVENTD
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(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)
# FIXME: rename to LVM_CONF_DIR
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(usrlibdir)
AC_SUBST(usrsbindir)
################################################################################
dnl -- First and last lines should not contain files to generate in order to
@@ -643,25 +693,25 @@ dnl -- keep utility scripts running properly
AC_CONFIG_FILES([
Makefile
make.tmpl
daemons/Makefile
daemons/clvmd/Makefile
dmeventd/Makefile
dmeventd/mirror/Makefile
doc/Makefile
include/Makefile
lib/Makefile
man/Makefile
po/Makefile
dmeventd/Makefile
daemons/Makefile
daemons/clvmd/Makefile
dmeventd/mirror/Makefile
dmeventd/snapshot/Makefile
doc/Makefile
lib/format1/Makefile
lib/format_pool/Makefile
lib/locking/Makefile
lib/mirror/Makefile
lib/snapshot/Makefile
test/Makefile
man/Makefile
po/Makefile
scripts/Makefile
tools/Makefile
tools/version.h
tools/fsadm/Makefile
])
AC_OUTPUT

View File

@@ -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)

View File

@@ -36,6 +36,7 @@
#include <fcntl.h>
#include <getopt.h>
#include <errno.h>
#include <libdevmapper.h>
#include <libdlm.h>
#include "clvmd-comms.h"
@@ -46,13 +47,17 @@
#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 +77,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 +172,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 +193,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 +248,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 +282,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 +296,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 +326,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;
}
}

View File

@@ -118,9 +118,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 +253,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:

View File

@@ -665,6 +665,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 +687,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 */

View File

@@ -50,11 +50,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 +87,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 +100,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 +238,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 +286,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 +336,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 +452,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 +466,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 +502,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 +527,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)

View File

@@ -37,6 +37,7 @@
#include <getopt.h>
#include <syslog.h>
#include <errno.h>
#include <limits.h>
#include <libdlm.h>
#include "clvmd-comms.h"
@@ -146,8 +147,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 +182,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 +193,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;
@@ -527,7 +584,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 +595,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 +687,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 +958,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 +993,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 +1039,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 +1118,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 +1223,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 +1472,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 +1495,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 +1604,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 +1635,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 +1670,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;
@@ -1730,8 +1787,7 @@ static __attribute__ ((noreturn)) void *lvm_thread_fn(void *arg)
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);
@@ -1824,8 +1880,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));

View File

@@ -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

View File

@@ -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.
*
@@ -61,6 +61,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 +399,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 +450,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 +472,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 +492,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 +518,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 +551,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 +581,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 +604,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)

View File

@@ -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

View File

@@ -26,6 +26,7 @@
#include <libdevmapper.h>
#include <stdint.h>
#include <stdio.h>
#include <limits.h>
#include "clvm.h"
#include "refresh_clvmd.h"

View File

@@ -23,6 +23,7 @@ ifeq ("@LIB_SUFFIX@","dylib")
LIB_SHARED = libdevmapper-event.dylib
else
LIB_SHARED = libdevmapper-event.so
VERSIONED_SHLIB = $(LIB_SHARED).$(LIB_VERSION)
endif
TARGETS = dmeventd
@@ -33,7 +34,7 @@ include ../make.tmpl
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
@@ -74,6 +75,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:

View File

@@ -36,6 +36,7 @@
#include <sys/time.h>
#include <sys/resource.h>
#include <unistd.h>
#include <signal.h>
#include <arpa/inet.h> /* for htonl, ntohl */
#ifdef linux

View File

@@ -16,7 +16,7 @@ srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
SUBDIRS += mirror
SUBDIRS += mirror snapshot
include $(top_srcdir)/make.tmpl

View File

@@ -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
@@ -33,4 +33,3 @@ install: libdevmapper-event-lvm2mirror.$(LIB_SUFFIX)
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \
$(libdir)/$<.$(LIB_VERSION)
$(LN_S) -f $<.$(LIB_VERSION) $(libdir)/$<

View File

@@ -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);

View File

@@ -0,0 +1,3 @@
process_event
register_device
unregister_device

View File

@@ -1,8 +1,8 @@
#
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
# Copyright (C) 2004 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
@@ -16,16 +16,20 @@ srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
SOURCES = fsadm.c
INCLUDES += -I${top_srcdir}/tools
CLDFLAGS += -L${top_srcdir}/tools -ldevmapper @LVM2CMD_LIB@
TARGETS = fsadm
SOURCES = dmeventd_snapshot.c
ifeq ("@LIB_SUFFIX@","dylib")
LIB_SHARED = libdevmapper-event-lvm2snapshot.dylib
else
LIB_SHARED = libdevmapper-event-lvm2snapshot.so
endif
include $(top_srcdir)/make.tmpl
fsadm: $(OBJECTS)
$(CC) -o $@ $(CFLAGS) $(OBJECTS) -rdynamic
install: fsadm
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) fsadm \
$(sbindir)/fsadm
install: libdevmapper-event-lvm2snapshot.$(LIB_SUFFIX)
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \
$(libdir)/$<.$(LIB_VERSION)
$(LN_S) -f $<.$(LIB_VERSION) $(libdir)/$<

View 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, &params);
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;
}

View File

@@ -16,7 +16,7 @@ srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
SUBDIRS += mirror
SUBDIRS += mirror snapshot
include $(top_srcdir)/make.tmpl

View File

@@ -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
@@ -33,4 +33,3 @@ install: libdevmapper-event-lvm2mirror.$(LIB_SUFFIX)
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \
$(libdir)/$<.$(LIB_VERSION)
$(LN_S) -f $<.$(LIB_VERSION) $(libdir)/$<

View File

@@ -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);

View File

@@ -0,0 +1,3 @@
process_event
register_device
unregister_device

View File

@@ -0,0 +1,35 @@
#
# 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 the LVM2.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
# of the GNU General Public License v.2.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
INCLUDES += -I${top_srcdir}/tools
CLDFLAGS += -L${top_srcdir}/tools -ldevmapper @LVM2CMD_LIB@
SOURCES = dmeventd_snapshot.c
ifeq ("@LIB_SUFFIX@","dylib")
LIB_SHARED = libdevmapper-event-lvm2snapshot.dylib
else
LIB_SHARED = libdevmapper-event-lvm2snapshot.so
endif
include $(top_srcdir)/make.tmpl
install: libdevmapper-event-lvm2snapshot.$(LIB_SUFFIX)
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \
$(libdir)/$<.$(LIB_VERSION)
$(LN_S) -f $<.$(LIB_VERSION) $(libdir)/$<

View 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, &params);
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;
}

View File

@@ -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"
#}

View File

@@ -61,6 +61,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 \

View File

@@ -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.
@@ -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 (list_size(&lv->segments) == 1 && first_seg(lv)->area_count == 1) {
*percent = 100.0;
return 1;
}
if (!activation())
return 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 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,9 +730,44 @@ int monitor_dev_for_events(struct cmd_context *cmd,
if (monitor && !dmeventd_monitor_mode())
return 1;
/*
* 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)) {
list_iterate_safe(snh, snht, &lv->snapshot_segs)
if (!monitor_dev_for_events(cmd, list_struct_base(snh,
struct lv_segment, origin_list)->cow, monitor))
r = 0;
return r;
}
list_iterate(tmp, &lv->segments) {
seg = 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;

View File

@@ -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,6 +40,7 @@ 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);
@@ -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);

View File

@@ -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, &params);
/* 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, &params);
/* 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");
@@ -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");
@@ -387,8 +376,7 @@ 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);
@@ -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;
}
@@ -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",
@@ -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;
}
if (!_add_lv_to_dtree(dm, dtree, 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)
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;
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,
@@ -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;
}
@@ -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)

View File

@@ -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:
@@ -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;
}

567
lib/cache/lvmcache.c vendored
View File

@@ -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,18 +17,24 @@
#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 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)
{
@@ -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;
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)
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;
list_add(&vginfo->infos, &info->list);
}
static void _vginfo_detach_info(struct lvmcache_info *info)
{
if (!list_empty(&info->list)) {
list_del(&info->list);
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));
@@ -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 */
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;
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! */
@@ -266,6 +471,51 @@ int lvmcache_label_scan(struct cmd_context *cmd, int full_scan)
return r;
}
struct volume_group *lvmcache_get_vg(const char *vgid, unsigned precommitted)
{
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 list *lvmcache_get_vgids(struct cmd_context *cmd, int full_scan)
{
struct list *vgids;
@@ -279,7 +529,7 @@ struct list *lvmcache_get_vgids(struct cmd_context *cmd, int full_scan)
}
list_iterate_items(vginfo, &_vginfos) {
if (!str_list_add(cmd->mem, vgids,
if (!str_list_add(cmd->mem, vgids,
dm_pool_strdup(cmd->mem, vginfo->vgid))) {
log_error("strlist allocation failed");
return NULL;
@@ -302,7 +552,7 @@ struct list *lvmcache_get_vgnames(struct cmd_context *cmd, int full_scan)
}
list_iterate_items(vginfo, &_vginfos) {
if (!str_list_add(cmd->mem, vgnames,
if (!str_list_add(cmd->mem, vgnames,
dm_pool_strdup(cmd->mem, vginfo->vgname))) {
log_error("strlist allocation failed");
return NULL;
@@ -328,7 +578,7 @@ struct list *lvmcache_get_pvids(struct cmd_context *cmd, const char *vgname,
return pvids;
list_iterate_items(info, &vginfo->infos) {
if (!str_list_add(cmd->mem, pvids,
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);
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) ||
!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 {
***/
@@ -625,7 +905,29 @@ static int _lvmcache_update_vgname(struct lvmcache_info *info,
return 0;
}
list_init(&vginfo->infos);
primary_vginfo = vginfo_from_vgname(vgname, NULL);
/*
* 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))
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",
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);
@@ -642,17 +944,28 @@ static int _lvmcache_update_vgname(struct lvmcache_info *info,
***/
}
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", 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,23 +1005,50 @@ 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 && !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';
@@ -716,13 +1056,18 @@ int lvmcache_update_vg(struct volume_group *vg)
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);
@@ -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;
}
if (!list_empty(&_vginfos))
log_error("Internal error: _vginfos list should be empty");
list_init(&_vginfos);
if (retain_orphans)
init_lvmcache_orphans(cmd);
}

18
lib/cache/lvmcache.h vendored
View File

@@ -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
@@ -43,6 +44,8 @@ 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 */
@@ -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);
@@ -104,4 +108,8 @@ struct list *lvmcache_get_vgids(struct cmd_context *cmd, int full_scan);
struct 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

View File

@@ -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;
@@ -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;
}
@@ -400,11 +462,8 @@ static int _init_tag_configs(struct cmd_context *cmd)
/* Tag list may grow while inside this loop */
list_iterate_items(sl, &cmd->tags) {
if (!_load_config_file(cmd, sl->str)) {
stack;
return 0;
}
if (!_load_config_file(cmd, sl->str))
return_0;
}
return 1;
@@ -424,10 +483,8 @@ static int _merge_config_files(struct cmd_context *cmd)
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;
@@ -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++;
}
@@ -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 "
@@ -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;
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;
@@ -759,6 +825,11 @@ static int _init_segtypes(struct cmd_context *cmd)
segtype->library = NULL;
list_add(&cmd->segtypes, &segtype->list);
if (!(segtype = init_free_segtype(cmd)))
return 0;
segtype->library = NULL;
list_add(&cmd->segtypes, &segtype->list);
#ifdef SNAPSHOT_INTERNAL
if (!(segtype = init_snapshot_segtype(cmd)))
return 0;
@@ -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 "
@@ -937,6 +1006,7 @@ 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);
@@ -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;
@@ -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);

View File

@@ -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;
@@ -65,8 +66,10 @@ 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? */
@@ -80,6 +83,7 @@ struct cmd_context {
struct archive_params *archive_params;
struct backup_params *backup_params;
const char *stripe_filler;
/* List of defined tags */
struct list tags;
@@ -88,11 +92,13 @@ struct cmd_context {
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

View File

@@ -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;
@@ -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;

View File

@@ -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"

View File

@@ -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;

View File

@@ -65,6 +65,15 @@ void list_del(struct list *elem)
elem->p->n = elem->n;
}
/*
* Remove an element from existing list and insert before 'head'.
*/
void list_move(struct list *head, struct list *elem)
{
list_del(elem);
list_add(head, elem);
}
/*
* Is the list empty?
*/

View File

@@ -54,6 +54,11 @@ void list_add_h(struct list *head, struct list *elem);
*/
void list_del(struct list *elem);
/*
* Remove an element from existing list and insert before 'head'.
*/
void list_move(struct list *head, struct list *elem);
/*
* Is the list empty?
*/

View File

@@ -24,6 +24,7 @@
/* Define some portable printing types */
#define PRIsize_t "zu"
#define PRIptrdiff_t "td"
#define PRIpid_t PRId32
struct str_list {
struct list list;

View File

@@ -20,10 +20,8 @@ struct list *str_list_create(struct dm_pool *mem)
{
struct list *sl;
if (!(sl = dm_pool_alloc(mem, sizeof(struct list)))) {
stack;
return NULL;
}
if (!(sl = dm_pool_alloc(mem, sizeof(struct list))))
return_NULL;
list_init(sl);
@@ -34,19 +32,15 @@ int str_list_add(struct dm_pool *mem, struct 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);
@@ -74,10 +68,8 @@ int str_list_dup(struct dm_pool *mem, struct list *sllnew,
list_init(sllnew);
list_iterate_items(sl, sllold) {
if (!str_list_add(mem, sllnew, dm_pool_strdup(mem, sl->str))) {
stack;
return 0;
}
if (!str_list_add(mem, sllnew, dm_pool_strdup(mem, sl->str)))
return_0;
}
return 1;

View File

@@ -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.
@@ -236,10 +236,8 @@ 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) {
@@ -249,10 +247,8 @@ static int _add_alias(struct device *dev, const char *path)
}
}
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;
@@ -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;
}
@@ -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))) {
@@ -704,7 +687,8 @@ const char *dev_name_confirmed(struct device *dev, int quiet)
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;
}

View File

@@ -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) {
@@ -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);
@@ -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,

View File

@@ -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

View File

@@ -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 */

View File

@@ -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);

View File

@@ -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"},
@@ -270,7 +270,7 @@ void pvdisplay_segments(const struct physical_volume *pv)
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;
@@ -577,12 +574,11 @@ void vgdisplay_full(const struct volume_group *vg)
{
uint32_t access;
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);
@@ -605,13 +601,18 @@ void vgdisplay_full(const struct volume_group *vg)
/* 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");
}
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,13 +656,16 @@ void vgdisplay_full(const struct volume_group *vg)
void vgdisplay_colons(const struct volume_group *vg)
{
uint32_t active_pvs;
uint32_t lv_count;
struct lv_list *lvl;
const char *access;
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);
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:
@@ -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;

View File

@@ -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;
@@ -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);

View File

@@ -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");

View File

@@ -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;

View File

@@ -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)
@@ -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)))

View File

@@ -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.
@@ -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;

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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,10 +253,10 @@ 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';
@@ -288,10 +287,10 @@ static int _read_lvs(struct disk_list *data)
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;
@@ -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,10 +326,11 @@ 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;
}
@@ -347,10 +347,8 @@ 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;
@@ -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);
@@ -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);
@@ -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);
@@ -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);
@@ -731,7 +725,7 @@ int write_disks(const struct format_type *fmt, struct list *pvs)
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));

View File

@@ -212,7 +212,7 @@ 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);

View File

@@ -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,15 +18,12 @@
#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 list *pvs)
{
struct list *pvh, *t;
struct disk_list *dl = NULL;
@@ -36,8 +33,6 @@ 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
@@ -101,10 +96,6 @@ static int _check_vgs(struct list *pvs, int *partial)
dl->vgd.pe_total, dl->vgd.pe_allocated,
dl->vgd.pvg_total);
list_del(pvh);
if (partial_mode()) {
*partial = 1;
continue;
}
return 0;
}
pv_count++;
@@ -114,9 +105,6 @@ 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;
@@ -128,7 +116,6 @@ static struct volume_group *_build_vg(struct format_instance *fid,
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;
@@ -145,12 +132,12 @@ static struct volume_group *_build_vg(struct format_instance *fid,
list_init(&vg->lvs);
list_init(&vg->tags);
if (!_check_vgs(pvs, &partial))
if (!_check_vgs(pvs))
goto_bad;
dl = 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;
}
@@ -182,10 +168,8 @@ static struct volume_group *_format1_vg_read(struct format_instance *fid,
struct volume_group *vg = NULL;
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,10 +193,8 @@ 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;
@@ -224,9 +206,8 @@ static struct disk_list *_flatten_pv(struct format_instance *fid,
!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;
@@ -241,10 +222,8 @@ static int _flatten_vg(struct format_instance *fid, struct dm_pool *mem,
struct disk_list *data;
list_iterate_items(pvl, &vg->pvs) {
if (!(data = _flatten_pv(fid, mem, vg, pvl->pv, dev_dir))) {
stack;
return 0;
}
if (!(data = _flatten_pv(fid, mem, vg, pvl->pv, dev_dir)))
return_0;
list_add(pvds, &data->list);
}
@@ -252,10 +231,8 @@ static int _flatten_vg(struct format_instance *fid, struct dm_pool *mem,
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;
}
@@ -267,10 +244,8 @@ static int _format1_vg_write(struct format_instance *fid, struct volume_group *v
struct list pvds;
int r = 0;
if (!mem) {
stack;
return 0;
}
if (!mem)
return_0;
list_init(&pvds);
@@ -278,7 +253,7 @@ static int _format1_vg_write(struct format_instance *fid, struct volume_group *v
fid->fmt->cmd->filter) &&
write_disks(fid->fmt, &pvds));
lvmcache_update_vg(vg);
lvmcache_update_vg(vg, 0);
dm_pool_destroy(mem);
return r;
}
@@ -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;
@@ -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)) ||
@@ -390,10 +355,8 @@ static int _format1_pv_write(const struct format_type *fmt, struct physical_volu
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;
@@ -406,10 +369,8 @@ static int _format1_pv_write(const struct format_type *fmt, struct physical_volu
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;
@@ -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,19 +453,16 @@ 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);
/* 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;
@@ -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;

View File

@@ -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);

View File

@@ -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)) {
@@ -117,10 +119,8 @@ int import_pv(const struct format_type *fmt, struct dm_pool *mem,
list_init(&pv->tags);
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;
@@ -361,6 +342,7 @@ int import_lv(struct dm_pool *mem, struct logical_volume *lv, struct lv_disk *lv
list_init(&lv->snapshot_segs);
list_init(&lv->segments);
list_init(&lv->tags);
list_init(&lv->segs_using_this_lv);
return 1;
}
@@ -456,15 +438,11 @@ int import_pvs(const struct format_type *fmt, struct dm_pool *mem,
*count = 0;
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);
@@ -482,17 +460,13 @@ 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);
vg->lv_count++;
@@ -511,10 +485,8 @@ int import_lvs(struct dm_pool *mem, struct volume_group *vg, struct list *pvds)
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) {
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;
@@ -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;
@@ -674,10 +634,8 @@ int export_uuids(struct disk_list *dl, struct volume_group *vg)
struct pv_list *pvl;
list_iterate_items(pvl, &vg->pvs) {
if (!(ul = dm_pool_alloc(dl->mem, sizeof(*ul)))) {
stack;
return 0;
}
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);
@@ -722,10 +680,8 @@ int export_vg_number(struct format_instance *fid, struct list *pvds,
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)
dl->vgd.vg_number = vg_num;

View File

@@ -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.
@@ -118,10 +118,8 @@ static int _fill_maps(struct dm_hash_table *maps, struct volume_group *vg,
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);
@@ -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
*/
@@ -334,10 +328,8 @@ 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;
@@ -350,10 +342,8 @@ int import_extents(struct cmd_context *cmd, struct volume_group *vg,
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.");

View File

@@ -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

View File

@@ -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,21 +60,23 @@ 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;

View File

@@ -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.
@@ -33,15 +33,11 @@ int get_free_vg_number(struct format_instance *fid, struct dev_filter *filter,
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));

View File

@@ -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.
@@ -45,10 +45,8 @@ 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;
}
@@ -98,10 +96,8 @@ 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;
@@ -252,10 +248,8 @@ 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) {
if (info->dev &&
@@ -354,20 +348,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;

View File

@@ -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,8 +24,6 @@
#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,
int *sps)
@@ -128,44 +126,32 @@ static struct volume_group *_build_vg_from_pds(struct format_instance
list_init(&vg->lvs);
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;
}
@@ -182,25 +168,19 @@ static struct volume_group *_pool_vg_read(struct format_instance *fid,
/* 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);
@@ -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;
@@ -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;

View File

@@ -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

View File

@@ -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.
@@ -36,6 +36,7 @@ int import_pool_vg(struct volume_group *vg, struct dm_pool *mem, struct list *pl
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;
@@ -83,6 +83,7 @@ int import_pool_lvs(struct volume_group *vg, struct dm_pool *mem, struct list *p
list_init(&lv->snapshot_segs);
list_init(&lv->segments);
list_init(&lv->tags);
list_init(&lv->segs_using_this_lv);
list_iterate_items(pl, pls) {
lv->size += pl->pd.pl_blocks;
@@ -90,10 +91,8 @@ int import_pool_lvs(struct volume_group *vg, struct dm_pool *mem, struct list *p
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,
@@ -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);
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,10 +226,8 @@ 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));
@@ -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,10 +266,8 @@ 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;
}
if (!set_lv_segment_area_pv(seg, 0, usp->devs[j].pv, 0))
return_0;
list_add(&lv->segments, &seg->list);
*le_cur += seg->len;
@@ -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;
}
}
}

View File

@@ -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.

View File

@@ -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.
@@ -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);
}
@@ -134,10 +132,8 @@ static struct list *_scan_archive(struct dm_pool *mem,
struct archive_file *af;
struct 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);
@@ -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.
@@ -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,10 +260,8 @@ 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))
ix = 0;
@@ -343,10 +334,8 @@ int archive_list(struct cmd_context *cmd, const char *dir, const char *vgname)
struct 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))
log_print("No archives found in %s.", dir);
@@ -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);

View File

@@ -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.",
@@ -305,7 +293,7 @@ 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) {
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);
}
@@ -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",

View File

@@ -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 (!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,6 +389,7 @@ 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 {");
@@ -390,52 +398,45 @@ static int _print_pvs(struct formatter *f, struct volume_group *vg)
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 (!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 (!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 (!print_tags(&lv->tags, buffer, sizeof(buffer)))
return_0;
outf(f, "tags = %s", buffer);
}
@@ -579,10 +565,8 @@ static int _print_lv(struct formatter *f, struct logical_volume *lv)
seg_count = 1;
list_iterate_items(seg, &lv->segments) {
if (!_print_segment(f, lv->vg, seg_count++, seg)) {
stack;
return 0;
}
if (!_print_segment(f, lv->vg, seg_count++, seg))
return_0;
}
_dec_indent(f);
@@ -610,19 +594,15 @@ static int _print_lvs(struct formatter *f, struct volume_group *vg)
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) {
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);
@@ -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

View File

@@ -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;
}

View File

@@ -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.
@@ -36,9 +36,6 @@
#include <dirent.h>
#include <ctype.h>
#define FMT_TEXT_NAME "lvm2"
#define FMT_TEXT_ALIAS "text"
static struct mda_header *_raw_read_mda_header(const struct format_type *fmt,
struct device_area *dev_area);
@@ -142,7 +139,7 @@ static int _pv_analyze_mda_raw (const struct format_type * fmt,
struct raw_locn *rlocn;
uint64_t area_start;
uint64_t area_size;
uint64_t prev_sector;
uint64_t prev_sector, prev_sector2;
uint64_t latest_mrec_offset;
int i;
uint64_t offset;
@@ -187,8 +184,11 @@ static int _pv_analyze_mda_raw (const struct format_type * fmt,
offset2 = size2 = 0;
i = 0;
while (prev_sector != latest_mrec_offset) {
prev_sector2 = prev_sector;
prev_sector = _get_prev_sector_circular(area_start, area_size,
prev_sector);
if (prev_sector > prev_sector2)
goto_out;
/*
* FIXME: for some reason, the whole metadata region from
* area->start to area->start+area->size is not used.
@@ -250,7 +250,7 @@ static int _pv_analyze_mda_raw (const struct format_type * fmt,
static int _text_lv_setup(struct format_instance *fid __attribute((unused)),
struct logical_volume *lv)
{
/******** FIXME Any LV size restriction?
/******** FIXME Any LV size restriction?
uint64_t max_size = UINT_MAX;
if (lv->size > max_size) {
@@ -297,40 +297,38 @@ static struct mda_header *_raw_read_mda_header(const struct format_type *fmt,
return NULL;
}
if (!dev_read(dev_area->dev, dev_area->start, MDA_HEADER_SIZE, mdah)) {
stack;
goto error;
}
if (!dev_read(dev_area->dev, dev_area->start, MDA_HEADER_SIZE, mdah))
goto_bad;
if (mdah->checksum_xl != xlate32(calc_crc(INITIAL_CRC, mdah->magic,
MDA_HEADER_SIZE -
sizeof(mdah->checksum_xl)))) {
log_error("Incorrect metadata area header checksum");
goto error;
goto bad;
}
_xlate_mdah(mdah);
if (strncmp((char *)mdah->magic, FMTT_MAGIC, sizeof(mdah->magic))) {
log_error("Wrong magic number in metadata area header");
goto error;
goto bad;
}
if (mdah->version != FMTT_VERSION) {
log_error("Incompatible metadata area header version: %d",
mdah->version);
goto error;
goto bad;
}
if (mdah->start != dev_area->start) {
log_error("Incorrect start sector in metadata area header: %"
PRIu64, mdah->start);
goto error;
goto bad;
}
return mdah;
error:
bad:
dm_pool_free(fmt->cmd->mem, mdah);
return NULL;
}
@@ -348,11 +346,8 @@ static int _raw_write_mda_header(const struct format_type *fmt,
MDA_HEADER_SIZE -
sizeof(mdah->checksum_xl)));
if (!dev_write(dev, start_byte, MDA_HEADER_SIZE, mdah)) {
stack;
dm_pool_free(fmt->cmd->mem, mdah);
return 0;
}
if (!dev_write(dev, start_byte, MDA_HEADER_SIZE, mdah))
return_0;
return 1;
}
@@ -380,19 +375,18 @@ static struct raw_locn *_find_vg_rlocn(struct device_area *dev_area,
/* FIXME Loop through rlocns two-at-a-time. List null-terminated. */
/* FIXME Ignore if checksum incorrect!!! */
if (!dev_read(dev_area->dev, dev_area->start + rlocn->offset,
sizeof(vgnamebuf), vgnamebuf)) {
stack;
goto error;
}
sizeof(vgnamebuf), vgnamebuf))
goto_bad;
if (!strncmp(vgnamebuf, vgname, len = strlen(vgname)) &&
(isspace(vgnamebuf[len]) || vgnamebuf[len] == '{')) {
return rlocn;
}
error:
if ((info = info_from_pvid(dev_area->dev->pvid)))
lvmcache_update_vgname_and_id(info, ORPHAN, ORPHAN, 0, NULL);
bad:
if ((info = info_from_pvid(dev_area->dev->pvid, 0)))
lvmcache_update_vgname_and_id(info, FMT_TEXT_ORPHAN_VG_NAME,
FMT_TEXT_ORPHAN_VG_NAME, 0, NULL);
return NULL;
}
@@ -422,15 +416,11 @@ static int _raw_holds_vgname(struct format_instance *fid,
int noprecommit = 0;
struct mda_header *mdah;
if (!dev_open(dev_area->dev)) {
stack;
return 0;
}
if (!dev_open(dev_area->dev))
return_0;
if (!(mdah = _raw_read_mda_header(fid->fmt, dev_area))) {
stack;
return 0;
}
if (!(mdah = _raw_read_mda_header(fid->fmt, dev_area)))
return_0;
if (_find_vg_rlocn(dev_area, mdah, vgname, &noprecommit))
r = 1;
@@ -453,15 +443,11 @@ static struct volume_group *_vg_read_raw_area(struct format_instance *fid,
char *desc;
uint32_t wrap = 0;
if (!dev_open(area->dev)) {
stack;
return NULL;
}
if (!dev_open(area->dev))
return_NULL;
if (!(mdah = _raw_read_mda_header(fid->fmt, area))) {
stack;
goto out;
}
if (!(mdah = _raw_read_mda_header(fid->fmt, area)))
goto_out;
if (!(rlocn = _find_vg_rlocn(area, mdah, vgname, &precommitted))) {
log_debug("VG %s not found on %s", vgname, dev_name(area->dev));
@@ -483,10 +469,8 @@ static struct volume_group *_vg_read_raw_area(struct format_instance *fid,
(uint32_t) (rlocn->size - wrap),
(off_t) (area->start + MDA_HEADER_SIZE),
wrap, calc_crc, rlocn->checksum, &when,
&desc))) {
stack;
goto out;
}
&desc)))
goto_out;
log_debug("Read %s %smetadata (%u) from %s at %" PRIu64 " size %"
PRIu64, vg->name, precommitted ? "pre-commit " : "",
vg->seqno, dev_name(area->dev),
@@ -529,7 +513,7 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
struct mda_header *mdah;
struct pv_list *pvl;
int r = 0;
uint32_t new_wrap = 0, old_wrap = 0;
uint64_t new_wrap = 0, old_wrap = 0, new_end;
int found = 0;
int noprecommit = 0;
@@ -544,15 +528,11 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
if (!found)
return 1;
if (!dev_open(mdac->area.dev)) {
stack;
return 0;
}
if (!dev_open(mdac->area.dev))
return_0;
if (!(mdah = _raw_read_mda_header(fid->fmt, &mdac->area))) {
stack;
goto out;
}
if (!(mdah = _raw_read_mda_header(fid->fmt, &mdac->area)))
goto_out;
rlocn = _find_vg_rlocn(&mdac->area, mdah, vg->name, &noprecommit);
mdac->rlocn.offset = _next_rlocn_offset(rlocn, mdah);
@@ -572,10 +552,11 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
if (rlocn && (rlocn->offset + rlocn->size > mdah->size))
old_wrap = (rlocn->offset + rlocn->size) - mdah->size;
new_end = new_wrap ? new_wrap + MDA_HEADER_SIZE :
mdac->rlocn.offset + mdac->rlocn.size;
if ((new_wrap && old_wrap) ||
(rlocn && ((new_wrap > rlocn->offset) ||
(old_wrap && (mdac->rlocn.offset + mdac->rlocn.size >
rlocn->offset)))) ||
(rlocn && (new_wrap || old_wrap) && (new_end > rlocn->offset)) ||
(mdac->rlocn.size >= mdah->size)) {
log_error("VG %s metadata too large for circular buffer",
vg->name);
@@ -589,24 +570,20 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
/* Write text out, circularly */
if (!dev_write(mdac->area.dev, mdac->area.start + mdac->rlocn.offset,
(size_t) (mdac->rlocn.size - new_wrap),
fidtc->raw_metadata_buf)) {
stack;
goto out;
}
fidtc->raw_metadata_buf))
goto_out;
if (new_wrap) {
log_debug("Writing metadata to %s at %" PRIu64 " len %" PRIu32,
log_debug("Writing metadata to %s at %" PRIu64 " len %" PRIu64,
dev_name(mdac->area.dev), mdac->area.start +
MDA_HEADER_SIZE, new_wrap);
if (!dev_write(mdac->area.dev,
mdac->area.start + MDA_HEADER_SIZE,
(size_t) new_wrap,
fidtc->raw_metadata_buf +
mdac->rlocn.size - new_wrap)) {
stack;
goto out;
}
fidtc->raw_metadata_buf +
mdac->rlocn.size - new_wrap))
goto_out;
}
mdac->rlocn.checksum = calc_crc(INITIAL_CRC, fidtc->raw_metadata_buf,
@@ -616,13 +593,20 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
mdac->rlocn.checksum = calc_crc(mdac->rlocn.checksum,
fidtc->raw_metadata_buf +
mdac->rlocn.size -
new_wrap, new_wrap);
new_wrap, (uint32_t) new_wrap);
r = 1;
out:
if (!r && !dev_close(mdac->area.dev))
stack;
if (!r) {
if (!dev_close(mdac->area.dev))
stack;
if (fidtc->raw_metadata_buf) {
dm_free(fidtc->raw_metadata_buf);
fidtc->raw_metadata_buf = NULL;
}
}
return r;
}
@@ -652,10 +636,8 @@ static int _vg_commit_raw_rlocn(struct format_instance *fid,
if (!found)
return 1;
if (!(mdah = _raw_read_mda_header(fid->fmt, &mdac->area))) {
stack;
goto out;
}
if (!(mdah = _raw_read_mda_header(fid->fmt, &mdac->area)))
goto_out;
if (!(rlocn = _find_vg_rlocn(&mdac->area, mdah, vg->name, &noprecommit))) {
mdah->raw_locns[0].offset = 0;
@@ -694,6 +676,7 @@ static int _vg_commit_raw_rlocn(struct format_instance *fid,
if (!_raw_write_mda_header(fid->fmt, mdac->area.dev, mdac->area.start,
mdah)) {
dm_pool_free(fid->fmt->cmd->mem, mdah);
log_error("Failed to write metadata area header");
goto out;
}
@@ -759,15 +742,11 @@ static int _vg_remove_raw(struct format_instance *fid, struct volume_group *vg,
int r = 0;
int noprecommit = 0;
if (!dev_open(mdac->area.dev)) {
stack;
return 0;
}
if (!dev_open(mdac->area.dev))
return_0;
if (!(mdah = _raw_read_mda_header(fid->fmt, &mdac->area))) {
stack;
goto out;
}
if (!(mdah = _raw_read_mda_header(fid->fmt, &mdac->area)))
goto_out;
if (!(rlocn = _find_vg_rlocn(&mdac->area, mdah, vg->name, &noprecommit))) {
rlocn = &mdah->raw_locns[0];
@@ -780,6 +759,7 @@ static int _vg_remove_raw(struct format_instance *fid, struct volume_group *vg,
if (!_raw_write_mda_header(fid->fmt, mdac->area.dev, mdac->area.start,
mdah)) {
dm_pool_free(fid->fmt->cmd->mem, mdah);
log_error("Failed to write metadata area header");
goto out;
}
@@ -801,10 +781,8 @@ static struct volume_group *_vg_read_file_name(struct format_instance *fid,
time_t when;
char *desc;
if (!(vg = text_vg_import_file(fid, read_path, &when, &desc))) {
stack;
return NULL;
}
if (!(vg = text_vg_import_file(fid, read_path, &when, &desc)))
return_NULL;
/*
* Currently you can only have a single volume group per
@@ -1038,7 +1016,7 @@ static int _scan_file(const struct format_type *fmt)
if ((vg = _vg_read_file_name(fid, vgname,
path)))
/* FIXME Store creation host in vg */
lvmcache_update_vg(vg);
lvmcache_update_vg(vg, 0);
}
if (closedir(d))
@@ -1065,10 +1043,8 @@ const char *vgname_from_mda(const struct format_type *fmt,
if (mda_free_sectors)
*mda_free_sectors = ((dev_area->size - MDA_HEADER_SIZE) / 2) >> SECTOR_SHIFT;
if (!dev_open(dev_area->dev)) {
stack;
return NULL;
}
if (!dev_open(dev_area->dev))
return_NULL;
if (!(mdah = _raw_read_mda_header(fmt, dev_area)))
goto_out;
@@ -1114,20 +1090,18 @@ const char *vgname_from_mda(const struct format_type *fmt,
/* Ignore this entry if the characters aren't permissible */
if (!validate_name(vgname)) {
stack;
vgname = NULL;
goto out;
goto_out;
}
if (!id_write_format(vgid, uuid, sizeof(uuid))) {
stack;
vgname = NULL;
goto out;
goto_out;
}
log_debug("%s: Found metadata at %" PRIu64 " size %" PRIu64
" (in area at %" PRIu64 " size %" PRIu64
") for %s (%s)",
") for %s (%s)",
dev_name(dev_area->dev), dev_area->start + rlocn->offset,
rlocn->size, dev_area->start, dev_area->size, vgname, uuid);
@@ -1170,7 +1144,7 @@ static int _scan_raw(const struct format_type *fmt)
NULL, NULL))) {
if ((vg = _vg_read_raw_area(&fid, vgname,
&rl->dev_area, 0)))
lvmcache_update_vg(vg);
lvmcache_update_vg(vg, 0);
}
}
@@ -1200,7 +1174,7 @@ static int _mda_setup(const struct format_type *fmt,
if (!pvmetadatacopies)
return 1;
alignment = pe_align() << SECTOR_SHIFT;
alignment = pe_align(pv) << SECTOR_SHIFT;
disk_size = pv->size << SECTOR_SHIFT;
pe_start <<= SECTOR_SHIFT;
pe_end <<= SECTOR_SHIFT;
@@ -1328,10 +1302,8 @@ static int _text_pv_write(const struct format_type *fmt, struct physical_volume
/* FIXME Test mode don't update cache? */
if (!(info = lvmcache_add(fmt->labeller, (char *) &pv->id, pv->dev,
ORPHAN, NULL, 0))) {
stack;
return 0;
}
FMT_TEXT_ORPHAN_VG_NAME, NULL, 0)))
return_0;
label = info->label;
if (label_sector != -1)
@@ -1367,9 +1339,9 @@ static int _text_pv_write(const struct format_type *fmt, struct physical_volume
else
list_init(&info->das);
/* Set pe_start to first aligned sector after any metadata
/* Set pe_start to first aligned sector after any metadata
* areas that begin before pe_start */
pv->pe_start = pe_align();
pv->pe_start = pe_align(pv);
list_iterate_items(mda, &info->mdas) {
mdac = (struct mda_context *) mda->metadata_locn;
if (pv->dev == mdac->area.dev &&
@@ -1378,21 +1350,17 @@ static int _text_pv_write(const struct format_type *fmt, struct physical_volume
(pv->pe_start << SECTOR_SHIFT))) {
pv->pe_start = (mdac->area.start + mdac->area.size)
>> SECTOR_SHIFT;
adjustment = pv->pe_start % pe_align();
adjustment = pv->pe_start % pe_align(pv);
if (adjustment)
pv->pe_start += (pe_align() - adjustment);
pv->pe_start += (pe_align(pv) - adjustment);
}
}
if (!add_da
(NULL, &info->das, pv->pe_start << SECTOR_SHIFT, UINT64_C(0))) {
stack;
return 0;
}
(NULL, &info->das, pv->pe_start << SECTOR_SHIFT, UINT64_C(0)))
return_0;
if (!dev_open(pv->dev)) {
stack;
return 0;
}
if (!dev_open(pv->dev))
return_0;
list_iterate_items(mda, &info->mdas) {
mdac = mda->metadata_locn;
@@ -1400,20 +1368,20 @@ static int _text_pv_write(const struct format_type *fmt, struct physical_volume
mdah->size = mdac->area.size;
if (!_raw_write_mda_header(fmt, mdac->area.dev,
mdac->area.start, mdah)) {
stack;
if (!dev_close(pv->dev))
stack;
return 0;
return_0;
}
}
label_write(pv->dev, label);
if (!dev_close(pv->dev)) {
stack;
return 0;
if (!label_write(pv->dev, label)) {
dev_close(pv->dev);
return_0;
}
if (!dev_close(pv->dev))
return_0;
return 1;
}
@@ -1439,6 +1407,55 @@ static int _add_raw(struct list *raw_list, struct device_area *dev_area)
return 1;
}
static int _get_pv_if_in_vg(struct lvmcache_info *info,
struct physical_volume *pv)
{
if (info->vginfo && info->vginfo->vgname &&
!is_orphan_vg(info->vginfo->vgname) &&
get_pv_from_vg_by_id(info->fmt, info->vginfo->vgname,
info->vginfo->vgid, info->dev->pvid, pv))
return 1;
return 0;
}
static int _populate_pv_fields(struct lvmcache_info *info,
struct physical_volume *pv)
{
struct data_area_list *da;
/* Have we already cached vgname? */
if (_get_pv_if_in_vg(info, pv))
return 1;
/* Perform full scan (just the first time) and try again */
if (!memlock() && !full_scan_done()) {
lvmcache_label_scan(info->fmt->cmd, 2);
if (_get_pv_if_in_vg(info, pv))
return 1;
}
/* Orphan */
pv->dev = info->dev;
pv->fmt = info->fmt;
pv->size = info->device_size >> SECTOR_SHIFT;
pv->vg_name = FMT_TEXT_ORPHAN_VG_NAME;
memcpy(&pv->id, &info->dev->pvid, sizeof(pv->id));
/* Currently only support exactly one data area */
if (list_size(&info->das) != 1) {
log_error("Must be exactly one data area (found %d) on PV %s",
list_size(&info->das), dev_name(info->dev));
return 0;
}
list_iterate_items(da, &info->das)
pv->pe_start = da->disk_locn.offset >> SECTOR_SHIFT;
return 1;
}
static int _text_pv_read(const struct format_type *fmt, const char *pv_name,
struct physical_volume *pv, struct list *mdas)
{
@@ -1447,57 +1464,16 @@ static int _text_pv_read(const struct format_type *fmt, const char *pv_name,
struct lvmcache_info *info;
struct metadata_area *mda, *mda_new;
struct mda_context *mdac, *mdac_new;
struct data_area_list *da;
if (!(dev = dev_cache_get(pv_name, fmt->cmd->filter))) {
stack;
return 0;
}
if (!(dev = dev_cache_get(pv_name, fmt->cmd->filter)))
return_0;
/* FIXME Optimise out repeated reading when cache lock held */
if (!(label_read(dev, &label, UINT64_C(0)))) {
stack;
return 0;
}
if (!(label_read(dev, &label, UINT64_C(0))))
return_0;
info = (struct lvmcache_info *) label->info;
/* Have we already cached vgname? */
if (info->vginfo && info->vginfo->vgname &&
!is_orphan_vg(info->vginfo->vgname) &&
get_pv_from_vg_by_id(info->fmt, info->vginfo->vgname,
info->vginfo->vgid, info->dev->pvid, pv)) {
return 1;
}
/* Perform full scan (just the first time) and try again */
if (!memlock() && !full_scan_done()) {
lvmcache_label_scan(fmt->cmd, 2);
if (info->vginfo && info->vginfo->vgname &&
!is_orphan_vg(info->vginfo->vgname) &&
get_pv_from_vg_by_id(info->fmt, info->vginfo->vgname,
info->vginfo->vgid,
info->dev->pvid, pv)) {
return 1;
}
}
/* Orphan */
pv->dev = info->dev;
pv->fmt = info->fmt;
pv->size = info->device_size >> SECTOR_SHIFT;
pv->vg_name = ORPHAN;
memcpy(&pv->id, &info->dev->pvid, sizeof(pv->id));
/* Currently only support exactly one data area */
if (list_size(&info->das) != 1) {
log_error("Must be exactly one data area (found %d) on PV %s",
list_size(&info->das), dev_name(dev));
if (!_populate_pv_fields(info, pv))
return 0;
}
list_iterate_items(da, &info->das)
pv->pe_start = da->disk_locn.offset >> SECTOR_SHIFT;
if (!mdas)
return 1;
@@ -1610,7 +1586,7 @@ static int _text_pv_setup(const struct format_type *fmt,
/* If new vg, add any further mdas on this PV to the fid's mda list */
if (vg) {
/* Iterate through all mdas on this PV */
if ((info = info_from_pvid(pv->dev->pvid))) {
if ((info = info_from_pvid(pv->dev->pvid, 0))) {
pvmdas = &info->mdas;
list_iterate_items(mda, pvmdas) {
mda_count++;
@@ -1642,16 +1618,12 @@ static int _text_pv_setup(const struct format_type *fmt,
continue;
if (!(mda_new = dm_pool_alloc(fmt->cmd->mem,
sizeof(*mda_new)))) {
stack;
return 0;
}
sizeof(*mda_new))))
return_0;
if (!(mdac_new = dm_pool_alloc(fmt->cmd->mem,
sizeof(*mdac_new)))) {
stack;
return 0;
}
sizeof(*mdac_new))))
return_0;
/* FIXME multiple dev_areas inside area */
memcpy(mda_new, mda, sizeof(*mda));
memcpy(mdac_new, mdac, sizeof(*mdac));
@@ -1687,11 +1659,8 @@ static int _text_pv_setup(const struct format_type *fmt,
if (extent_count)
pe_end = pe_start + extent_count * extent_size - 1;
if (!_mda_setup(fmt, pe_start, pe_end, pvmetadatacopies,
pvmetadatasize, mdas, pv, vg)) {
stack;
return 0;
}
pvmetadatasize, mdas, pv, vg))
return_0;
}
return 1;
@@ -1732,10 +1701,8 @@ static struct format_instance *_text_create_text_instance(const struct format_ty
list_init(&fid->metadata_areas);
if (!vgname) {
if (!(mda = dm_pool_alloc(fmt->cmd->mem, sizeof(*mda)))) {
stack;
return NULL;
}
if (!(mda = dm_pool_alloc(fmt->cmd->mem, sizeof(*mda))))
return_NULL;
mda->ops = &_metadata_text_file_backup_ops;
mda->metadata_locn = context;
list_add(&fid->metadata_areas, &mda->list);
@@ -1751,10 +1718,8 @@ static struct format_instance *_text_create_text_instance(const struct format_ty
}
context = create_text_context(fmt->cmd, path, NULL);
if (!(mda = dm_pool_alloc(fmt->cmd->mem, sizeof(*mda)))) {
stack;
return NULL;
}
if (!(mda = dm_pool_alloc(fmt->cmd->mem, sizeof(*mda))))
return_NULL;
mda->ops = &_metadata_text_file_ops;
mda->metadata_locn = context;
list_add(&fid->metadata_areas, &mda->list);
@@ -1767,15 +1732,11 @@ static struct format_instance *_text_create_text_instance(const struct format_ty
if (!_raw_holds_vgname(fid, &rl->dev_area, vgname))
continue;
if (!(mda = dm_pool_alloc(fmt->cmd->mem, sizeof(*mda)))) {
stack;
return NULL;
}
if (!(mda = dm_pool_alloc(fmt->cmd->mem, sizeof(*mda))))
return_NULL;
if (!(mdac = dm_pool_alloc(fmt->cmd->mem, sizeof(*mdac)))) {
stack;
return NULL;
}
if (!(mdac = dm_pool_alloc(fmt->cmd->mem, sizeof(*mdac))))
return_NULL;
mda->metadata_locn = mdac;
/* FIXME Allow multiple dev_areas inside area */
memcpy(&mdac->area, &rl->dev_area, sizeof(mdac->area));
@@ -1786,10 +1747,8 @@ static struct format_instance *_text_create_text_instance(const struct format_ty
/* Scan PVs in VG for any further MDAs */
lvmcache_label_scan(fmt->cmd, 0);
if (!(vginfo = vginfo_from_vgname(vgname, vgid))) {
stack;
goto out;
}
if (!(vginfo = vginfo_from_vgname(vgname, vgid)))
goto_out;
list_iterate_items(info, &vginfo->infos) {
mdas = &info->mdas;
list_iterate_items(mda, mdas) {
@@ -1798,16 +1757,12 @@ static struct format_instance *_text_create_text_instance(const struct format_ty
/* FIXME Check it holds this VG */
if (!(mda_new = dm_pool_alloc(fmt->cmd->mem,
sizeof(*mda_new)))) {
stack;
return NULL;
}
sizeof(*mda_new))))
return_NULL;
if (!(mdac_new = dm_pool_alloc(fmt->cmd->mem,
sizeof(*mdac_new)))) {
stack;
return NULL;
}
sizeof(*mdac_new))))
return_NULL;
/* FIXME multiple dev_areas inside area */
memcpy(mda_new, mda, sizeof(*mda));
memcpy(mdac_new, mdac, sizeof(*mdac));
@@ -1834,33 +1789,26 @@ void *create_text_context(struct cmd_context *cmd, const char *path,
return NULL;
}
if (!(tc = dm_pool_alloc(cmd->mem, sizeof(*tc)))) {
stack;
return NULL;
}
if (!(tc = dm_pool_alloc(cmd->mem, sizeof(*tc))))
return_NULL;
if (!(tc->path_live = dm_pool_strdup(cmd->mem, path))) {
stack;
goto no_mem;
}
if (!(tc->path_live = dm_pool_strdup(cmd->mem, path)))
goto_bad;
if (!(tc->path_edit = dm_pool_alloc(cmd->mem, strlen(path) + 5)))
goto_bad;
if (!(tc->path_edit = dm_pool_alloc(cmd->mem, strlen(path) + 5))) {
stack;
goto no_mem;
}
sprintf(tc->path_edit, "%s.tmp", path);
if (!desc)
desc = "";
if (!(tc->desc = dm_pool_strdup(cmd->mem, desc))) {
stack;
goto no_mem;
}
if (!(tc->desc = dm_pool_strdup(cmd->mem, desc)))
goto_bad;
return (void *) tc;
no_mem:
bad:
dm_pool_free(cmd->mem, tc);
log_err("Couldn't allocate text format context object.");
@@ -1956,15 +1904,14 @@ struct format_type *create_text_format(struct cmd_context *cmd)
struct config_value *cv;
struct mda_lists *mda_lists;
if (!(fmt = dm_malloc(sizeof(*fmt)))) {
stack;
return NULL;
}
if (!(fmt = dm_malloc(sizeof(*fmt))))
return_NULL;
fmt->cmd = cmd;
fmt->ops = &_text_handler;
fmt->name = FMT_TEXT_NAME;
fmt->alias = FMT_TEXT_ALIAS;
fmt->orphan_vg_name = ORPHAN_VG_NAME(FMT_TEXT_NAME);
fmt->features = FMT_SEGMENTS | FMT_MDAS | FMT_TAGS | FMT_PRECOMMIT |
FMT_UNLIMITED_VOLS | FMT_RESIZE_PV |
FMT_UNLIMITED_STRIPESIZE;

View File

@@ -19,6 +19,10 @@
#include "lvm-types.h"
#include "metadata.h"
#define FMT_TEXT_NAME "lvm2"
#define FMT_TEXT_ALIAS "text"
#define FMT_TEXT_ORPHAN_VG_NAME ORPHAN_VG_NAME(FMT_TEXT_NAME)
/*
* Archives a vg config. 'retain_days' is the minimum number of
* days that an archive file must be held for. 'min_archives' is

View File

@@ -36,9 +36,11 @@
* common code for reading and writing them.
*/
enum {
COMPATIBLE_FLAG = 0x0,
VG_FLAGS,
PV_FLAGS,
LV_FLAGS
LV_FLAGS,
STATUS_FLAG = 0x8,
};
struct text_vg_version_ops {

View File

@@ -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) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -23,6 +23,18 @@
/* FIXME Use tidier inclusion method */
static struct text_vg_version_ops *(_text_vsn_list[2]);
static int _text_import_initialised = 0;
static void _init_text_import()
{
if (_text_import_initialised)
return;
_text_vsn_list[0] = text_vg_vsn1_init();
_text_vsn_list[1] = NULL;
_text_import_initialised = 1;
}
const char *text_vgname_import(const struct format_type *fmt,
struct device *dev,
off_t offset, uint32_t size,
@@ -35,13 +47,7 @@ const char *text_vgname_import(const struct format_type *fmt,
struct text_vg_version_ops **vsn;
const char *vgname = NULL;
static int _text_import_initialised = 0;
if (!_text_import_initialised) {
_text_vsn_list[0] = text_vg_vsn1_init();
_text_vsn_list[1] = NULL;
_text_import_initialised = 1;
}
_init_text_import();
if (!(cft = create_config_tree(NULL, 0)))
return_NULL;
@@ -51,7 +57,7 @@ const char *text_vgname_import(const struct format_type *fmt,
offset2, size2, checksum_fn, checksum)))
goto_out;
/*
/*
* Find a set of version functions that can read this file
*/
for (vsn = &_text_vsn_list[0]; *vsn; vsn++) {
@@ -83,13 +89,7 @@ struct volume_group *text_vg_import_fd(struct format_instance *fid,
struct config_tree *cft;
struct text_vg_version_ops **vsn;
static int _text_vg_import_initialised = 0;
if (!_text_vg_import_initialised) {
_text_vsn_list[0] = text_vg_vsn1_init();
_text_vsn_list[1] = NULL;
_text_vg_import_initialised = 1;
}
_init_text_import();
*desc = NULL;
*when = 0;
@@ -104,17 +104,15 @@ struct volume_group *text_vg_import_fd(struct format_instance *fid,
goto out;
}
/*
/*
* Find a set of version functions that can read this file
*/
for (vsn = &_text_vsn_list[0]; *vsn; vsn++) {
if (!(*vsn)->check_version(cft))
continue;
if (!(vg = (*vsn)->read_vg(fid, cft))) {
stack;
goto out;
}
if (!(vg = (*vsn)->read_vg(fid, cft)))
goto_out;
(*vsn)->read_desc(fid->fmt->cmd->mem, cft, when, desc);
break;
@@ -132,3 +130,27 @@ struct volume_group *text_vg_import_file(struct format_instance *fid,
return text_vg_import_fd(fid, file, NULL, (off_t)0, 0, (off_t)0, 0, NULL, 0,
when, desc);
}
struct volume_group *import_vg_from_buffer(char *buf,
struct format_instance *fid)
{
struct volume_group *vg = NULL;
struct config_tree *cft;
struct text_vg_version_ops **vsn;
_init_text_import();
if (!(cft = create_config_tree_from_string(fid->fmt->cmd, buf)))
return_NULL;
for (vsn = &_text_vsn_list[0]; *vsn; vsn++) {
if (!(*vsn)->check_version(cft))
continue;
if (!(vg = (*vsn)->read_vg(fid, cft)))
stack;
break;
}
destroy_config_tree(cft);
return vg;
}

View File

@@ -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.
@@ -86,6 +86,22 @@ static int _check_version(struct config_tree *cft)
return 1;
}
static int _is_converting(struct logical_volume *lv)
{
struct lv_segment *seg;
if (lv->status & MIRRORED) {
seg = first_seg(lv);
/* Can't use is_temporary_mirror() because the metadata for
* seg_lv may not be read in and flags may not be set yet. */
if (seg_type(seg, 0) == AREA_LV &&
strstr(seg_lv(seg, 0)->name, MIRROR_SYNC_LAYER))
return 1;
}
return 0;
}
static int _read_id(struct id *id, struct config_node *cn, const char *path)
{
struct config_value *cv;
@@ -109,6 +125,31 @@ static int _read_id(struct id *id, struct config_node *cn, const char *path)
return 1;
}
static int _read_flag_config(struct config_node *n, uint32_t *status, int type)
{
struct config_node *cn;
*status = 0;
if (!(cn = find_config_node(n, "status"))) {
log_error("Could not find status flags.");
return 0;
}
if (!(read_flags(status, type | STATUS_FLAG, cn->v))) {
log_error("Could not read status flags.");
return 0;
}
if ((cn = find_config_node(n, "flags"))) {
if (!(read_flags(status, type, cn->v))) {
log_error("Could not read flags.");
return 0;
}
}
return 1;
}
static int _read_pv(struct format_instance *fid, struct dm_pool *mem,
struct volume_group *vg, struct config_node *pvn,
struct config_node *vgn __attribute((unused)),
@@ -120,10 +161,8 @@ static int _read_pv(struct format_instance *fid, struct dm_pool *mem,
uint64_t size;
if (!(pvl = dm_pool_zalloc(mem, sizeof(*pvl))) ||
!(pvl->pv = dm_pool_zalloc(mem, sizeof(*pvl->pv)))) {
stack;
return 0;
}
!(pvl->pv = dm_pool_zalloc(mem, sizeof(*pvl->pv))))
return_0;
pv = pvl->pv;
@@ -131,10 +170,8 @@ static int _read_pv(struct format_instance *fid, struct dm_pool *mem,
* Add the pv to the pv hash for quick lookup when we read
* the lv segments.
*/
if (!dm_hash_insert(pv_hash, pvn->key, pv)) {
stack;
return 0;
}
if (!dm_hash_insert(pv_hash, pvn->key, pv))
return_0;
if (!(pvn = pvn->child)) {
log_error("Empty pv section.");
@@ -157,30 +194,21 @@ static int _read_pv(struct format_instance *fid, struct dm_pool *mem,
else
log_error("Couldn't find device with uuid '%s'.",
buffer);
if (partial_mode())
vg->status |= PARTIAL_VG;
else
return 0;
}
if (!(pv->vg_name = dm_pool_strdup(mem, vg->name))) {
stack;
return 0;
}
if (!(pv->vg_name = dm_pool_strdup(mem, vg->name)))
return_0;
memcpy(&pv->vgid, &vg->id, sizeof(vg->id));
if (!(cn = find_config_node(pvn, "status"))) {
log_error("Couldn't find status flags for physical volume.");
return 0;
}
if (!(read_flags(&pv->status, PV_FLAGS, cn->v))) {
if (!_read_flag_config(pvn, &pv->status, PV_FLAGS)) {
log_error("Couldn't read status flags for physical volume.");
return 0;
}
if (!pv->dev)
pv->status |= MISSING_PV;
/* Late addition */
_read_int64(pvn, "dev_size", &pv->size);
@@ -213,32 +241,31 @@ static int _read_pv(struct format_instance *fid, struct dm_pool *mem,
pv->pe_size = vg->extent_size;
pv->pe_alloc_count = 0;
pv->pe_align = 0;
pv->fmt = fid->fmt;
/* Fix up pv size if missing or impossibly large */
if ((!pv->size || pv->size > (1ULL << 62)) && pv->dev) {
if (!dev_get_size(pv->dev, &pv->size)) {
log_error("%s: Couldn't get size.", pv_dev_name(pv));
return 0;
}
log_verbose("Fixing up missing size (%s) "
"for PV %s", display_size(fid->fmt->cmd, pv->size),
pv_dev_name(pv));
if (vg) {
size = pv->pe_count * (uint64_t) vg->extent_size +
pv->pe_start;
if (size > pv->size)
log_error("WARNING: Physical Volume %s is too "
"large for underlying device",
pv_dev_name(pv));
}
}
if (!alloc_pv_segment_whole_pv(mem, pv)) {
stack;
return 0;
/* Fix up pv size if missing or impossibly large */
if ((!pv->size || pv->size > (1ULL << 62)) && pv->dev) {
if (!dev_get_size(pv->dev, &pv->size)) {
log_error("%s: Couldn't get size.", pv_dev_name(pv));
return 0;
}
log_verbose("Fixing up missing size (%s) "
"for PV %s", display_size(fid->fmt->cmd, pv->size),
pv_dev_name(pv));
if (vg) {
size = pv->pe_count * (uint64_t) vg->extent_size +
pv->pe_start;
if (size > pv->size)
log_error("WARNING: Physical Volume %s is too "
"large for underlying device",
pv_dev_name(pv));
}
}
if (!alloc_pv_segment_whole_pv(mem, pv))
return_0;
vg->pv_count++;
list_add(&vg->pvs, &pvl->list);
@@ -300,16 +327,12 @@ static int _read_segment(struct dm_pool *mem, struct volume_group *vg,
segtype_str = cv->v.str;
}
if (!(segtype = get_segtype_from_string(vg->cmd, segtype_str))) {
stack;
return 0;
}
if (!(segtype = get_segtype_from_string(vg->cmd, segtype_str)))
return_0;
if (segtype->ops->text_import_area_count &&
!segtype->ops->text_import_area_count(sn, &area_count)) {
stack;
return 0;
}
!segtype->ops->text_import_area_count(sn, &area_count))
return_0;
if (!(seg = alloc_lv_segment(mem, segtype, lv, start_extent,
extent_count, 0, 0, NULL, area_count,
@@ -319,10 +342,8 @@ static int _read_segment(struct dm_pool *mem, struct volume_group *vg,
}
if (seg->segtype->ops->text_import &&
!seg->segtype->ops->text_import(seg, sn, pv_hash)) {
stack;
return 0;
}
!seg->segtype->ops->text_import(seg, sn, pv_hash))
return_0;
/* Optional tags */
if ((cn = find_config_node(sn, "tags")) &&
@@ -343,6 +364,9 @@ static int _read_segment(struct dm_pool *mem, struct volume_group *vg,
if (seg_is_virtual(seg))
lv->status |= VIRTUAL;
if (_is_converting(lv))
lv->status |= CONVERTING;
return 1;
}
@@ -384,13 +408,13 @@ int text_import_areas(struct lv_segment *seg, const struct config_node *sn,
/* FIXME Cope if LV not yet read in */
if ((pv = dm_hash_lookup(pv_hash, cv->v.str))) {
if (!set_lv_segment_area_pv(seg, s, pv, (uint32_t) cv->next->v.i)) {
stack;
return 0;
}
if (!set_lv_segment_area_pv(seg, s, pv, (uint32_t) cv->next->v.i))
return_0;
} else if ((lv1 = find_lv(seg->lv->vg, cv->v.str))) {
set_lv_segment_area_lv(seg, s, lv1, (uint32_t) cv->next->v.i,
flags);
if (!set_lv_segment_area_lv(seg, s, lv1,
(uint32_t) cv->next->v.i,
flags))
return_0;
} else {
log_error("Couldn't find volume '%s' "
"for segment '%s'.",
@@ -426,10 +450,8 @@ static int _read_segments(struct dm_pool *mem, struct volume_group *vg,
* All sub-sections are assumed to be segments.
*/
if (!sn->v) {
if (!_read_segment(mem, vg, lv, sn, pv_hash)) {
stack;
return 0;
}
if (!_read_segment(mem, vg, lv, sn, pv_hash))
return_0;
count++;
}
@@ -454,18 +476,14 @@ static int _read_segments(struct dm_pool *mem, struct volume_group *vg,
/*
* Check there are no gaps or overlaps in the lv.
*/
if (!check_lv_segments(lv, 0)) {
stack;
return 0;
}
if (!check_lv_segments(lv, 0))
return_0;
/*
* Merge segments in case someones been editing things by hand.
*/
if (!lv_merge_segments(lv)) {
stack;
return 0;
}
if (!lv_merge_segments(lv))
return_0;
return 1;
}
@@ -481,30 +499,22 @@ static int _read_lvnames(struct format_instance *fid __attribute((unused)),
struct config_node *cn;
if (!(lvl = dm_pool_zalloc(mem, sizeof(*lvl))) ||
!(lvl->lv = dm_pool_zalloc(mem, sizeof(*lvl->lv)))) {
stack;
return 0;
}
!(lvl->lv = dm_pool_zalloc(mem, sizeof(*lvl->lv))))
return_0;
lv = lvl->lv;
if (!(lv->name = dm_pool_strdup(mem, lvn->key))) {
stack;
return 0;
}
if (!(lv->name = dm_pool_strdup(mem, lvn->key)))
return_0;
if (!(lvn = lvn->child)) {
log_error("Empty logical volume section.");
return 0;
}
if (!(cn = find_config_node(lvn, "status"))) {
log_error("Couldn't find status flags for logical volume.");
return 0;
}
if (!(read_flags(&lv->status, LV_FLAGS, cn->v))) {
log_error("Couldn't read status flags for logical volume.");
if (!_read_flag_config(lvn, &lv->status, LV_FLAGS)) {
log_error("Couldn't read status flags for logical volume %s.",
lv->name);
return 0;
}
@@ -517,10 +527,8 @@ static int _read_lvnames(struct format_instance *fid __attribute((unused)),
}
lv->alloc = get_alloc_from_string(cv->v.str);
if (lv->alloc == ALLOC_INVALID) {
stack;
return 0;
}
if (lv->alloc == ALLOC_INVALID)
return_0;
}
if (!_read_int32(lvn, "read_ahead", &lv->read_ahead))
@@ -531,7 +539,7 @@ static int _read_lvnames(struct format_instance *fid __attribute((unused)),
case 0:
lv->read_ahead = DM_READ_AHEAD_AUTO;
break;
case -1:
case (uint32_t) -1:
lv->read_ahead = DM_READ_AHEAD_NONE;
break;
default:
@@ -543,6 +551,7 @@ static int _read_lvnames(struct format_instance *fid __attribute((unused)),
list_init(&lv->snapshot_segs);
list_init(&lv->segments);
list_init(&lv->tags);
list_init(&lv->segs_using_this_lv);
/* Optional tags */
if ((cn = find_config_node(lvn, "tags")) &&
@@ -589,10 +598,8 @@ static int _read_lvsegs(struct format_instance *fid __attribute((unused)),
memcpy(&lv->lvid.id[0], &lv->vg->id, sizeof(lv->lvid.id[0]));
if (!_read_segments(mem, vg, lv, lvn, pv_hash)) {
stack;
return 0;
}
if (!_read_segments(mem, vg, lv, lvn, pv_hash))
return_0;
lv->size = (uint64_t) lv->le_count * (uint64_t) vg->extent_size;
@@ -642,10 +649,8 @@ static int _read_sections(struct format_instance *fid,
}
for (n = n->child; n; n = n->sib) {
if (!fn(fid, mem, vg, n, vgn, pv_hash)) {
stack;
return 0;
}
if (!fn(fid, mem, vg, n, vgn, pv_hash))
return_0;
}
return 1;
@@ -667,10 +672,8 @@ static struct volume_group *_read_vg(struct format_instance *fid,
return NULL;
}
if (!(vg = dm_pool_zalloc(mem, sizeof(*vg)))) {
stack;
return NULL;
}
if (!(vg = dm_pool_zalloc(mem, sizeof(*vg))))
return_NULL;
vg->cmd = fid->fmt->cmd;
/* FIXME Determine format type from file contents */
@@ -704,14 +707,8 @@ static struct volume_group *_read_vg(struct format_instance *fid,
goto bad;
}
if (!(cn = find_config_node(vgn, "status"))) {
log_error("Couldn't find status flags for volume group %s.",
vg->name);
goto bad;
}
if (!(read_flags(&vg->status, VG_FLAGS, cn->v))) {
log_error("Couldn't read status flags for volume group %s.",
if (!_read_flag_config(vgn, &vg->status, VG_FLAGS)) {
log_error("Error reading flags of volume group %s.",
vg->name);
goto bad;
}
@@ -748,10 +745,8 @@ static struct volume_group *_read_vg(struct format_instance *fid,
}
vg->alloc = get_alloc_from_string(cv->v.str);
if (vg->alloc == ALLOC_INVALID) {
stack;
return 0;
}
if (vg->alloc == ALLOC_INVALID)
return_0;
}
/*
@@ -803,11 +798,6 @@ static struct volume_group *_read_vg(struct format_instance *fid,
dm_hash_destroy(pv_hash);
if (vg->status & PARTIAL_VG) {
vg->status &= ~LVM_WRITE;
vg->status |= LVM_READ;
}
/*
* Finished.
*/
@@ -840,7 +830,7 @@ static const char *_read_vgname(const struct format_type *fmt,
struct config_tree *cft, struct id *vgid,
uint32_t *vgstatus, char **creation_host)
{
struct config_node *vgn, *cn;
struct config_node *vgn;
struct dm_pool *mem = fmt->cmd->mem;
char *vgname;
int old_suppress;
@@ -848,7 +838,7 @@ static const char *_read_vgname(const struct format_type *fmt,
old_suppress = log_suppress(2);
*creation_host = dm_pool_strdup(mem,
find_config_str(cft->root,
"creation_host", ""));
"creation_host", ""));
log_suppress(old_suppress);
/* skip any top-level values */
@@ -869,18 +859,12 @@ static const char *_read_vgname(const struct format_type *fmt,
return 0;
}
if (!(cn = find_config_node(vgn, "status"))) {
if (!_read_flag_config(vgn, vgstatus, VG_FLAGS)) {
log_error("Couldn't find status flags for volume group %s.",
vgname);
return 0;
}
if (!(read_flags(vgstatus, VG_FLAGS, cn->v))) {
log_error("Couldn't read status flags for volume group %s.",
vgname);
return 0;
}
return vgname;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -24,30 +24,22 @@ int print_tags(struct list *tags, char *buffer, size_t size)
struct str_list *sl;
int first = 1;
if (!emit_to_buffer(&buffer, &size, "[")) {
stack;
return 0;
}
if (!emit_to_buffer(&buffer, &size, "["))
return_0;
list_iterate_items(sl, tags) {
if (!first) {
if (!emit_to_buffer(&buffer, &size, ", ")) {
stack;
return 0;
}
if (!emit_to_buffer(&buffer, &size, ", "))
return_0;
} else
first = 0;
if (!emit_to_buffer(&buffer, &size, "\"%s\"", sl->str)) {
stack;
return 0;
}
if (!emit_to_buffer(&buffer, &size, "\"%s\"", sl->str))
return_0;
}
if (!emit_to_buffer(&buffer, &size, "]")) {
stack;
return 0;
}
if (!emit_to_buffer(&buffer, &size, "]"))
return_0;
return 1;
}
@@ -63,10 +55,8 @@ int read_tags(struct dm_pool *mem, struct list *tags, struct config_value *cv)
return 0;
}
if (!str_list_add(mem, tags, dm_pool_strdup(mem, cv->v.str))) {
stack;
return 0;
}
if (!str_list_add(mem, tags, dm_pool_strdup(mem, cv->v.str)))
return_0;
cv = cv->next;
}

View File

@@ -16,8 +16,8 @@
#ifndef _LVM_TEXT_EXPORT_H
#define _LVM_TEXT_EXPORT_H
#define outf(args...) do {if (!out_text(args)) {stack; return 0;}} while (0)
#define outnl(f) do {if (!f->nl(f)) {stack; return 0;}} while (0)
#define outf(args...) do {if (!out_text(args)) return_0;} while (0)
#define outnl(f) do {if (!f->nl(f)) return_0;} while (0)
struct formatter;
struct lv_segment;

View File

@@ -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.
@@ -207,7 +207,9 @@ static int _text_read(struct labeller *l, struct device *dev, void *buf,
pvhdr = (struct pv_header *) ((void *) buf + xlate32(lh->offset_xl));
if (!(info = lvmcache_add(l, (char *)pvhdr->pv_uuid, dev, NULL, NULL, 0)))
if (!(info = lvmcache_add(l, (char *)pvhdr->pv_uuid, dev,
FMT_TEXT_ORPHAN_VG_NAME,
FMT_TEXT_ORPHAN_VG_NAME, 0)))
return_0;
*label = info->label;
@@ -239,7 +241,7 @@ static int _text_read(struct labeller *l, struct device *dev, void *buf,
list_iterate_items(mda, &info->mdas) {
mdac = (struct mda_context *) mda->metadata_locn;
if ((vgname = vgname_from_mda(info->fmt, &mdac->area,
if ((vgname = vgname_from_mda(info->fmt, &mdac->area,
&vgid, &vgstatus, &creation_host,
&mdac->free_sectors)) &&
!lvmcache_update_vgname_and_id(info, vgname,

60
lib/freeseg/freeseg.c Normal file
View File

@@ -0,0 +1,60 @@
/*
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License v.2.1.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
#include "toolcontext.h"
#include "segtype.h"
#include "display.h"
#include "text_export.h"
#include "text_import.h"
#include "config.h"
#include "str_list.h"
#include "targets.h"
#include "lvm-string.h"
#include "activate.h"
#include "str_list.h"
#include "metadata.h"
static const char *_freeseg_name(const struct lv_segment *seg)
{
return seg->segtype->name;
}
static void _freeseg_destroy(const struct segment_type *segtype)
{
dm_free((void *)segtype);
}
static struct segtype_handler _freeseg_ops = {
.name = _freeseg_name,
.destroy = _freeseg_destroy,
};
struct segment_type *init_free_segtype(struct cmd_context *cmd)
{
struct segment_type *segtype = dm_malloc(sizeof(*segtype));
if (!segtype)
return_NULL;
segtype->cmd = cmd;
segtype->ops = &_freeseg_ops;
segtype->name = "free";
segtype->private = NULL;
segtype->flags = SEG_VIRTUAL | SEG_CANNOT_BE_ZEROED;
log_very_verbose("Initialised segtype: %s", segtype->name);
return segtype;
}

View File

@@ -86,10 +86,8 @@ int label_register_handler(const char *name, struct labeller *handler)
{
struct labeller_i *li;
if (!(li = _alloc_li(name, handler))) {
stack;
return 0;
}
if (!(li = _alloc_li(name, handler)))
return_0;
list_add(&_labellers, &li->list);
return 1;
@@ -145,7 +143,7 @@ static struct labeller *_find_labeller(struct device *dev, char *buf,
continue;
}
if (calc_crc(INITIAL_CRC, &lh->offset_xl, LABEL_SIZE -
((void *) &lh->offset_xl - (void *) lh)) !=
((uintptr_t) &lh->offset_xl - (uintptr_t) lh)) !=
xlate32(lh->crc_xl)) {
log_info("Label checksum incorrect on %s - "
"ignoring", dev_name(dev));
@@ -179,8 +177,9 @@ static struct labeller *_find_labeller(struct device *dev, char *buf,
out:
if (!found) {
if ((info = info_from_pvid(dev->pvid)))
lvmcache_update_vgname_and_id(info, ORPHAN, ORPHAN,
if ((info = info_from_pvid(dev->pvid, 0)))
lvmcache_update_vgname_and_id(info, info->fmt->orphan_vg_name,
info->fmt->orphan_vg_name,
0, NULL);
log_very_verbose("%s: No label detected", dev_name(dev));
}
@@ -203,10 +202,8 @@ int label_remove(struct device *dev)
log_very_verbose("Scanning for labels to wipe from %s", dev_name(dev));
if (!dev_open(dev)) {
stack;
return 0;
}
if (!dev_open(dev))
return_0;
/*
* We flush the device just in case someone is stupid
@@ -260,7 +257,6 @@ int label_remove(struct device *dev)
return r;
}
/* FIXME Avoid repeated re-reading if cache lock held */
int label_read(struct device *dev, struct label **result,
uint64_t scan_sector)
{
@@ -270,18 +266,25 @@ int label_read(struct device *dev, struct label **result,
struct lvmcache_info *info;
int r = 0;
if ((info = info_from_pvid(dev->pvid, 1))) {
log_debug("Using cached label for %s", dev_name(dev));
*result = info->label;
return 1;
}
if (!dev_open(dev)) {
stack;
if ((info = info_from_pvid(dev->pvid)))
lvmcache_update_vgname_and_id(info, ORPHAN, ORPHAN,
if ((info = info_from_pvid(dev->pvid, 0)))
lvmcache_update_vgname_and_id(info, info->fmt->orphan_vg_name,
info->fmt->orphan_vg_name,
0, NULL);
return r;
}
if (!(l = _find_labeller(dev, buf, &sector, scan_sector)))
goto_out;
goto out;
if ((r = (l->ops->read)(l, dev, buf, result)) && result && *result)
(*result)->sector = sector;
@@ -317,18 +320,14 @@ int label_write(struct device *dev, struct label *label)
lh->sector_xl = xlate64(label->sector);
lh->offset_xl = xlate32(sizeof(*lh));
if (!(label->labeller->ops->write)(label, buf)) {
stack;
return 0;
}
if (!(label->labeller->ops->write)(label, buf))
return_0;
lh->crc_xl = xlate32(calc_crc(INITIAL_CRC, &lh->offset_xl, LABEL_SIZE -
((void *) &lh->offset_xl - (void *) lh)));
((uintptr_t) &lh->offset_xl - (uintptr_t) lh)));
if (!dev_open(dev)) {
stack;
return 0;
}
if (!dev_open(dev))
return_0;
log_info("%s: Writing label to sector %" PRIu64, dev_name(dev),
label->sector);
@@ -353,15 +352,16 @@ int label_verify(struct device *dev)
int r = 0;
if (!dev_open(dev)) {
if ((info = info_from_pvid(dev->pvid)))
lvmcache_update_vgname_and_id(info, ORPHAN, ORPHAN,
if ((info = info_from_pvid(dev->pvid, 0)))
lvmcache_update_vgname_and_id(info, info->fmt->orphan_vg_name,
info->fmt->orphan_vg_name,
0, NULL);
return_0;
}
if (!(l = _find_labeller(dev, buf, &sector, UINT64_C(0))))
goto_out;
goto out;
r = l->ops->verify ? l->ops->verify(l, buf, sector) : 1;

View File

@@ -104,8 +104,8 @@ static int _send_request(char *inbuf, int inlen, char **retbuf)
/* Send it to CLVMD */
rewrite:
if ( (err = write(_clvmd_sock, inbuf, inlen)) != inlen) {
if (err == -1 && errno == EINTR)
goto rewrite;
if (err == -1 && errno == EINTR)
goto rewrite;
log_error("Error writing data to clvmd: %s", strerror(errno));
return 0;
}
@@ -113,8 +113,8 @@ static int _send_request(char *inbuf, int inlen, char **retbuf)
/* Get the response */
reread:
if ((len = read(_clvmd_sock, outbuf, sizeof(struct clvm_header))) < 0) {
if (errno == EINTR)
goto reread;
if (errno == EINTR)
goto reread;
log_error("Error reading data from clvmd: %s", strerror(errno));
return 0;
}
@@ -315,9 +315,6 @@ static int _lock_for_cluster(unsigned char cmd, uint32_t flags, const char *name
args[0] = flags & 0x7F; /* Maskoff lock flags */
args[1] = flags & 0xC0; /* Bitmap flags */
if (partial_mode())
args[1] |= LCK_PARTIAL_MODE;
if (mirror_in_sync())
args[1] |= LCK_MIRROR_NOSYNC_MODE;
@@ -330,7 +327,7 @@ static int _lock_for_cluster(unsigned char cmd, uint32_t flags, const char *name
* locks are cluster-wide.
* Also, if the lock is exclusive it makes no sense to try to
* acquire it on all nodes, so just do that on the local node too.
* One exception, is that P_ locks /do/ get distributed across
* One exception, is that P_ locks /do/ get distributed across
* the cluster because they might have side-effects.
*/
if (strncmp(name, "P_", 2) &&
@@ -387,13 +384,12 @@ int lock_resource(struct cmd_context *cmd, const char *resource, uint32_t flags)
switch (flags & LCK_SCOPE_MASK) {
case LCK_VG:
/* If the VG name is empty then lock the unused PVs */
if (!*resource) /* FIXME Deprecated */
dm_snprintf(lockname, sizeof(lockname), "P_orphans");
else if (*resource == '#')
dm_snprintf(lockname, sizeof(lockname), "P_%s", resource + 1);
if (*resource == '#' || (flags & LCK_CACHE))
dm_snprintf(lockname, sizeof(lockname), "P_%s",
resource);
else
dm_snprintf(lockname, sizeof(lockname), "V_%s",
resource);
resource);
lock_scope = "VG";
cluster_cmd = CLVMD_CMD_LOCK_VG;
@@ -438,18 +434,20 @@ int lock_resource(struct cmd_context *cmd, const char *resource, uint32_t flags)
return 0;
}
/* If we are unlocking a VG, then trigger remote metadata backups */
if (cluster_cmd == CLVMD_CMD_LOCK_VG && ((flags & LCK_TYPE_MASK) == LCK_UNLOCK)) {
/* If we are unlocking a clustered VG, then trigger remote metadata backups */
if (cluster_cmd == CLVMD_CMD_LOCK_VG &&
((flags & LCK_TYPE_MASK) == LCK_UNLOCK) &&
(flags & LCK_CLUSTER_VG)) {
log_very_verbose("Requesing backup of VG metadata for %s", resource);
_lock_for_cluster(CLVMD_CMD_VG_BACKUP, LCK_CLUSTER_VG, resource);
}
log_very_verbose("Locking %s %s %s %s%s%s%s (0x%x)", lock_scope, lockname,
lock_type,
flags & LCK_NONBLOCK ? "" : "B",
flags & LCK_HOLD ? "H" : "",
flags & LCK_LOCAL ? "L" : "",
flags & LCK_CLUSTER_VG ? "C" : "",
flags & LCK_NONBLOCK ? "" : "B",
flags & LCK_HOLD ? "H" : "",
flags & LCK_LOCAL ? "L" : "",
flags & LCK_CLUSTER_VG ? "C" : "",
flags);
/* Send a message to the cluster manager */
@@ -479,7 +477,7 @@ void reset_locking(void)
_clvmd_sock = _open_local_sock();
if (_clvmd_sock == -1)
stack;
stack;
}
#ifdef CLUSTER_LOCKING_INTERNAL

View File

@@ -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.
@@ -73,10 +73,8 @@ int init_external_locking(struct locking_type *locking, struct cmd_context *cmd)
libname = find_config_tree_str(cmd, "global/locking_library",
DEFAULT_LOCKING_LIB);
if (!(_locking_lib = load_shared_library(cmd, libname, "locking", 1))) {
stack;
return 0;
}
if (!(_locking_lib = load_shared_library(cmd, libname, "locking", 1)))
return_0;
/* Get the functions we need */
if (!(_init_fn = dlsym(_locking_lib, "locking_init")) ||

View File

@@ -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.
@@ -210,10 +210,15 @@ static int _file_lock_resource(struct cmd_context *cmd, const char *resource,
switch (flags & LCK_SCOPE_MASK) {
case LCK_VG:
if (!*resource) /* FIXME Deprecated */
dm_snprintf(lockfile, sizeof(lockfile),
"%s/P_orphans", _lock_dir);
else if (*resource == '#')
/* Skip cache refresh for VG_GLOBAL - the caller handles it */
if (strcmp(resource, VG_GLOBAL))
lvmcache_drop_metadata(resource);
/* LCK_CACHE does not require a real lock */
if (flags & LCK_CACHE)
break;
if (*resource == '#')
dm_snprintf(lockfile, sizeof(lockfile),
"%s/P_%s", _lock_dir, resource + 1);
else
@@ -221,17 +226,7 @@ static int _file_lock_resource(struct cmd_context *cmd, const char *resource,
"%s/V_%s", _lock_dir, resource);
if (!_lock_file(lockfile, flags))
return 0;
switch (flags & LCK_TYPE_MASK) {
case LCK_UNLOCK:
lvmcache_unlock_vgname(resource);
break;
default:
lvmcache_lock_vgname(resource,
(flags & LCK_TYPE_MASK) ==
LCK_READ);
}
return_0;
break;
case LCK_LV:
switch (flags & LCK_TYPE_MASK) {

View File

@@ -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,6 +21,7 @@
#include "toolcontext.h"
#include "memlock.h"
#include "defaults.h"
#include "lvmcache.h"
#include <signal.h>
#include <sys/stat.h>
@@ -253,7 +254,7 @@ int init_locking(int type, struct cmd_context *cmd)
}
if ((type == 2 || type == 3) &&
find_config_tree_int(cmd, "locking/fallback_to_local_locking",
find_config_tree_int(cmd, "locking/fallback_to_local_locking",
DEFAULT_FALLBACK_TO_LOCAL_LOCKING)) {
log_warn("WARNING: Falling back to local file-based locking.");
log_warn("Volume Groups with the clustered attribute will "
@@ -291,6 +292,10 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname)
if (is_orphan_vg(vgname))
return 1;
/* LVM1 is only present in 2.4 kernels. */
if (strncmp(cmd->kernel_vsn, "2.4.", 4))
return 1;
if (dm_snprintf(path, sizeof(path), "%s/lvm/VGs/%s", cmd->proc_dir,
vgname) < 0) {
log_error("LVM1 proc VG pathname too long for %s", vgname);
@@ -315,22 +320,40 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname)
*/
static int _lock_vol(struct cmd_context *cmd, const char *resource, uint32_t flags)
{
int ret = 0;
_block_signals(flags);
_lock_memory(flags);
assert(resource);
if (!(_locking.lock_resource(cmd, resource, flags))) {
_unlock_memory(flags);
_unblock_signals();
if (!*resource) {
log_error("Internal error: Use of P_orphans is deprecated.");
return 0;
}
_update_vg_lock_count(flags);
if (*resource == '#' && (flags & LCK_CACHE)) {
log_error("Internal error: P_%s referenced", resource);
return 0;
}
if ((ret = _locking.lock_resource(cmd, resource, flags))) {
if ((flags & LCK_SCOPE_MASK) == LCK_VG &&
!(flags & LCK_CACHE)) {
if ((flags & LCK_TYPE_MASK) == LCK_UNLOCK)
lvmcache_unlock_vgname(resource);
else
lvmcache_lock_vgname(resource, (flags & LCK_TYPE_MASK)
== LCK_READ);
}
_update_vg_lock_count(flags);
}
_unlock_memory(flags);
_unblock_signals();
return 1;
return ret;
}
int lock_vol(struct cmd_context *cmd, const char *vol, uint32_t flags)
@@ -361,8 +384,12 @@ int lock_vol(struct cmd_context *cmd, const char *vol, uint32_t flags)
if (!_lock_vol(cmd, resource, flags))
return 0;
/* Perform immediate unlock unless LCK_HOLD set */
if (!(flags & LCK_HOLD) && ((flags & LCK_TYPE_MASK) != LCK_UNLOCK)) {
/*
* If a real lock was acquired (i.e. not LCK_CACHE),
* perform an immediate unlock unless LCK_HOLD was requested.
*/
if (!(flags & LCK_CACHE) && !(flags & LCK_HOLD) &&
((flags & LCK_TYPE_MASK) != LCK_UNLOCK)) {
if (!_lock_vol(cmd, resource,
(flags & ~LCK_TYPE_MASK) | LCK_UNLOCK))
return 0;
@@ -404,19 +431,23 @@ int suspend_lvs(struct cmd_context *cmd, struct list *lvs)
}
/* Lock a list of LVs */
int activate_lvs_excl(struct cmd_context *cmd, struct list *lvs)
int activate_lvs(struct cmd_context *cmd, struct list *lvs, unsigned exclusive)
{
struct list *lvh;
struct lv_list *lvl;
list_iterate_items(lvl, lvs) {
if (!activate_lv_excl(cmd, lvl->lv)) {
if (!exclusive) {
if (!activate_lv(cmd, lvl->lv)) {
log_error("Failed to activate %s", lvl->lv->name);
return 0;
}
} else if (!activate_lv_excl(cmd, lvl->lv)) {
log_error("Failed to activate %s", lvl->lv->name);
list_uniterate(lvh, lvs, &lvl->list) {
lvl = list_item(lvh, struct lv_list);
activate_lv(cmd, lvl->lv);
}
return 0;
}
}

View File

@@ -27,9 +27,11 @@ int locking_is_clustered(void);
/*
* LCK_VG:
* Lock/unlock on-disk volume group data
* Use VG_ORPHANS to lock orphan PVs
* char *vol holds volume group name
* Lock/unlock on-disk volume group data.
* Use VG_ORPHANS to lock all orphan PVs.
* Use VG_GLOBAL as a global lock and to wipe the internal cache.
* char *vol holds volume group name.
* Set the LCK_CACHE flag to invalidate 'vol' in the internal cache.
*
* LCK_LV:
* Lock/unlock an individual logical volume
@@ -37,6 +39,13 @@ int locking_is_clustered(void);
*/
int lock_vol(struct cmd_context *cmd, const char *vol, uint32_t flags);
/*
* Internal locking representation.
* LCK_VG: Uses prefix V_ unless the vol begins with # (i.e. #global or #orphans)
* or the LCK_CACHE flag is set when it uses the prefix P_.
* If LCK_CACHE is set, we do not take out a real lock.
*/
/*
* Does the LVM1 driver have this VG active?
*/
@@ -69,11 +78,11 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
#define LCK_HOLD 0x00000020U /* Hold lock when lock_vol returns? */
#define LCK_LOCAL 0x00000040U /* Don't propagate to other nodes */
#define LCK_CLUSTER_VG 0x00000080U /* VG is clustered */
#define LCK_CACHE 0x00000100U /* Operation on cache only using P_ lock */
/*
* Additional lock bits for cluster communication
*/
#define LCK_PARTIAL_MODE 0x00000001U /* Running in partial mode */
#define LCK_MIRROR_NOSYNC_MODE 0x00000002U /* Mirrors don't require sync */
#define LCK_DMEVENTD_MONITOR_MODE 0x00000004U /* Register with dmeventd */
@@ -91,6 +100,7 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
#define LCK_VG_READ (LCK_VG | LCK_READ | LCK_HOLD)
#define LCK_VG_WRITE (LCK_VG | LCK_WRITE | LCK_HOLD)
#define LCK_VG_UNLOCK (LCK_VG | LCK_UNLOCK)
#define LCK_VG_DROP_CACHE (LCK_VG | LCK_WRITE | LCK_CACHE)
#define LCK_LV_EXCLUSIVE (LCK_LV | LCK_EXCL | LCK_NONBLOCK)
#define LCK_LV_SUSPEND (LCK_LV | LCK_WRITE | LCK_NONBLOCK)
@@ -99,7 +109,7 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
#define LCK_LV_DEACTIVATE (LCK_LV | LCK_NULL | LCK_NONBLOCK)
#define LCK_LV_CLUSTERED(lv) \
(((lv)->vg->status & CLUSTERED) ? LCK_CLUSTER_VG : 0)
(vg_is_clustered((lv)->vg) ? LCK_CLUSTER_VG : 0)
#define lock_lv_vol(cmd, lv, flags) \
lock_vol(cmd, (lv)->lvid.s, flags | LCK_LV_CLUSTERED(lv))
@@ -116,11 +126,13 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
lock_lv_vol(cmd, lv, LCK_LV_ACTIVATE | LCK_HOLD | LCK_LOCAL)
#define deactivate_lv_local(cmd, lv) \
lock_lv_vol(cmd, lv, LCK_LV_DEACTIVATE | LCK_LOCAL)
#define drop_cached_metadata(vg) \
lock_vol((vg)->cmd, (vg)->name, LCK_VG_DROP_CACHE)
/* Process list of LVs */
int suspend_lvs(struct cmd_context *cmd, struct list *lvs);
int resume_lvs(struct cmd_context *cmd, struct list *lvs);
int activate_lvs_excl(struct cmd_context *cmd, struct list *lvs);
int activate_lvs(struct cmd_context *cmd, struct list *lvs, unsigned exclusive);
/* Interrupt handling */
void sigint_clear(void);

View File

@@ -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,7 +18,6 @@
#include "locking_types.h"
#include "lvm-string.h"
#include "activate.h"
#include "lvmcache.h"
#include <signal.h>
@@ -41,15 +40,6 @@ static int _no_lock_resource(struct cmd_context *cmd, const char *resource,
{
switch (flags & LCK_SCOPE_MASK) {
case LCK_VG:
switch (flags & LCK_TYPE_MASK) {
case LCK_UNLOCK:
lvmcache_unlock_vgname(resource);
break;
default:
lvmcache_lock_vgname(resource,
(flags & LCK_TYPE_MASK) ==
LCK_READ);
}
break;
case LCK_LV:
switch (flags & LCK_TYPE_MASK) {

View File

@@ -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.
@@ -29,7 +29,6 @@ static struct str_list _log_dev_alias;
static int _verbose_level = VERBOSE_BASE_LEVEL;
static int _test = 0;
static int _partial = 0;
static int _md_filtering = 0;
static int _pvmove = 0;
static int _full_scan_done = 0; /* Restrict to one full scan during each cmd */
@@ -51,6 +50,7 @@ static int _already_logging = 0;
static int _mirror_in_sync = 0;
static int _dmeventd_monitor = DEFAULT_DMEVENTD_MONITOR;
static int _ignore_suspended_devices = 0;
static int _error_message_produced = 0;
static lvm2_log_fn_t _lvm2_log_fn = NULL;
@@ -153,11 +153,6 @@ void init_test(int level)
_test = level;
}
void init_partial(int level)
{
_partial = level;
}
void init_md_filtering(int level)
{
_md_filtering = level;
@@ -215,12 +210,18 @@ void init_cmd_name(int status)
void set_cmd_name(const char *cmd)
{
if (!_log_cmd_name)
return;
strncpy(_cmd_name, cmd, sizeof(_cmd_name));
_cmd_name[sizeof(_cmd_name) - 1] = '\0';
}
static const char *_command_name()
{
if (!_log_cmd_name)
return "";
return _cmd_name;
}
void init_msg_prefix(const char *prefix)
{
strncpy(_msg_prefix, prefix, sizeof(_msg_prefix));
@@ -232,16 +233,21 @@ void init_indent(int indent)
_indent = indent;
}
void init_error_message_produced(int value)
{
_error_message_produced = value;
}
int error_message_produced(void)
{
return _error_message_produced;
}
int test_mode()
{
return _test;
}
int partial_mode()
{
return _partial;
}
int md_filtering()
{
return _md_filtering;
@@ -316,6 +322,9 @@ void print_log(int level, const char *file, int line, const char *format, ...)
if (_log_suppress == 2)
return;
if (level <= _LOG_ERR)
_error_message_produced = 1;
trformat = _(format);
if (_lvm2_log_fn) {
@@ -352,7 +361,7 @@ void print_log(int level, const char *file, int line, const char *format, ...)
_verbose_level <= _LOG_DEBUG)
break;
if (_verbose_level >= _LOG_DEBUG) {
fprintf(stderr, "%s%s%s", locn, _cmd_name,
fprintf(stderr, "%s%s%s", locn, _command_name(),
_msg_prefix);
if (_indent)
fprintf(stderr, " ");
@@ -363,7 +372,7 @@ void print_log(int level, const char *file, int line, const char *format, ...)
case _LOG_INFO:
if (_verbose_level >= _LOG_INFO) {
fprintf(stderr, "%s%s%s", locn, _cmd_name,
fprintf(stderr, "%s%s%s", locn, _command_name(),
_msg_prefix);
if (_indent)
fprintf(stderr, " ");
@@ -373,7 +382,7 @@ void print_log(int level, const char *file, int line, const char *format, ...)
break;
case _LOG_NOTICE:
if (_verbose_level >= _LOG_NOTICE) {
fprintf(stderr, "%s%s%s", locn, _cmd_name,
fprintf(stderr, "%s%s%s", locn, _command_name(),
_msg_prefix);
if (_indent)
fprintf(stderr, " ");
@@ -383,14 +392,15 @@ void print_log(int level, const char *file, int line, const char *format, ...)
break;
case _LOG_WARN:
if (_verbose_level >= _LOG_WARN) {
fprintf(use_stderr ? stderr : stdout, "%s%s", _cmd_name, _msg_prefix);
fprintf(use_stderr ? stderr : stdout, "%s%s",
_command_name(), _msg_prefix);
vfprintf(use_stderr ? stderr : stdout, trformat, ap);
fputc('\n', use_stderr ? stderr : stdout);
}
break;
case _LOG_ERR:
if (_verbose_level >= _LOG_ERR) {
fprintf(stderr, "%s%s%s", locn, _cmd_name,
fprintf(stderr, "%s%s%s", locn, _command_name(),
_msg_prefix);
vfprintf(stderr, trformat, ap);
fputc('\n', stderr);
@@ -399,7 +409,7 @@ void print_log(int level, const char *file, int line, const char *format, ...)
case _LOG_FATAL:
default:
if (_verbose_level >= _LOG_FATAL) {
fprintf(stderr, "%s%s%s", locn, _cmd_name,
fprintf(stderr, "%s%s%s", locn, _command_name(),
_msg_prefix);
vfprintf(stderr, trformat, ap);
fputc('\n', stderr);
@@ -413,7 +423,7 @@ void print_log(int level, const char *file, int line, const char *format, ...)
return;
if (_log_to_file && (_log_while_suspended || !memlock())) {
fprintf(_log_file, "%s:%d %s%s", file, line, _cmd_name,
fprintf(_log_file, "%s:%d %s%s", file, line, _command_name(),
_msg_prefix);
va_start(ap, format);
@@ -436,7 +446,7 @@ void print_log(int level, const char *file, int line, const char *format, ...)
memset(&buf, ' ', sizeof(buf));
bufused = 0;
if ((n = dm_snprintf(buf, sizeof(buf) - bufused - 1,
"%s:%d %s%s", file, line, _cmd_name,
"%s:%d %s%s", file, line, _command_name(),
_msg_prefix)) == -1)
goto done;

View File

@@ -64,7 +64,6 @@ void fin_syslog(void);
void init_verbose(int level);
void init_test(int level);
void init_partial(int level);
void init_md_filtering(int level);
void init_pvmove(int level);
void init_full_scan_done(int level);
@@ -79,11 +78,11 @@ void init_security_level(int level);
void init_mirror_in_sync(int in_sync);
void init_dmeventd_monitor(int reg);
void init_ignore_suspended_devices(int ignore);
void init_error_message_produced(int error_message_produced);
void set_cmd_name(const char *cmd_name);
int test_mode(void);
int partial_mode(void);
int md_filtering(void);
int pvmove_mode(void);
int full_scan_done(void);
@@ -94,6 +93,7 @@ int lockingfailed(void);
int security_level(void);
int mirror_in_sync(void);
int ignore_suspended_devices(void);
int error_message_produced(void);
#define DMEVENTD_MONITOR_IGNORE -1
int dmeventd_monitor_mode(void);

View File

@@ -33,9 +33,9 @@ struct lv_segment *alloc_snapshot_seg(struct logical_volume *lv,
int set_lv_segment_area_pv(struct lv_segment *seg, uint32_t area_num,
struct physical_volume *pv, uint32_t pe);
void set_lv_segment_area_lv(struct lv_segment *seg, uint32_t area_num,
struct logical_volume *lv, uint32_t le,
uint32_t flags);
int set_lv_segment_area_lv(struct lv_segment *seg, uint32_t area_num,
struct logical_volume *lv, uint32_t le,
uint32_t flags);
int move_lv_segment_area(struct lv_segment *seg_to, uint32_t area_to,
struct lv_segment *seg_from, uint32_t area_from);
void release_lv_segment_area(struct lv_segment *seg, uint32_t s,
@@ -57,27 +57,21 @@ int lv_add_segment(struct alloc_handle *ah,
struct logical_volume *lv,
const struct segment_type *segtype,
uint32_t stripe_size,
struct physical_volume *mirrored_pv,
uint32_t mirrored_pe,
uint32_t status,
uint32_t region_size,
struct logical_volume *log_lv);
int lv_add_mirror_areas(struct alloc_handle *ah,
struct logical_volume *lv, uint32_t le,
uint32_t region_size);
int lv_add_mirror_lvs(struct logical_volume *lv,
struct logical_volume **sub_lvs,
uint32_t num_extra_areas,
uint32_t status, uint32_t region_size);
int lv_add_log_segment(struct alloc_handle *ah, struct logical_volume *log_lv);
int lv_add_virtual_segment(struct logical_volume *lv, uint32_t status,
uint32_t extents, const struct segment_type *segtype);
int lv_add_mirror_segment(struct alloc_handle *ah,
struct logical_volume *lv,
struct logical_volume **sub_lvs,
uint32_t mirrors,
const struct segment_type *segtype,
uint32_t status,
uint32_t region_size,
struct logical_volume *log_lv);
int lv_add_more_mirrored_areas(struct logical_volume *lv,
struct logical_volume **sub_lvs,
uint32_t new_area_count,
uint32_t status);
void alloc_destroy(struct alloc_handle *ah);

Some files were not shown because too many files have changed in this diff Show More