1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-12-25 20:23:49 +03:00

Compare commits

..

309 Commits

Author SHA1 Message Date
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
227 changed files with 12275 additions and 7497 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.32-cvs (2008-01-29)
2.02.40-cvs (2008-06-27)

198
WHATS_NEW
View File

@@ -1,3 +1,201 @@
Version 2.02.40 -
================================
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.

View File

@@ -1,5 +1,36 @@
Version 1.02.25 -
====================================
Version 1.02.29 -
=====================================
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-/)
@@ -35,7 +66,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
================================
@@ -323,4 +354,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
;;

9204
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,63 @@ 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_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 +93,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 +113,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 +125,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 +150,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 +269,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 +305,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 +319,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,6 +368,11 @@ 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
@@ -376,33 +389,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 +427,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 +450,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 +486,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 +514,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 +530,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 +554,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.
@@ -585,51 +622,56 @@ 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])
################################################################################
@@ -638,22 +680,22 @@ dnl -- keep utility scripts running properly
AC_CONFIG_FILES([
Makefile
make.tmpl
include/Makefile
lib/Makefile
man/Makefile
po/Makefile
dmeventd/Makefile
daemons/Makefile
daemons/clvmd/Makefile
dmeventd/Makefile
dmeventd/mirror/Makefile
dmeventd/snapshot/Makefile
doc/Makefile
include/Makefile
lib/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

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,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,94 @@ 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%s)", flags,
flags & LCK_PARTIAL_MODE ? "PARTIAL " : "",
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,13 +400,13 @@ 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;
@@ -391,8 +479,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 +499,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 +525,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 +558,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 +588,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 +611,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

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

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

View File

@@ -54,8 +54,10 @@ struct snap_status {
*/
static pthread_mutex_t _event_mutex = PTHREAD_MUTEX_INITIALIZER;
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);
@@ -115,7 +117,8 @@ fail:
dm_event_handler_destroy(dmevh);
}
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 **private)
{
void *next = NULL;
@@ -161,8 +164,11 @@ out:
pthread_mutex_unlock(&_event_mutex);
}
int register_device(const char *device, const char *uuid, int major, int minor,
void **private)
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;
@@ -201,8 +207,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

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

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

View File

@@ -54,8 +54,10 @@ struct snap_status {
*/
static pthread_mutex_t _event_mutex = PTHREAD_MUTEX_INITIALIZER;
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);
@@ -115,7 +117,8 @@ fail:
dm_event_handler_destroy(dmevh);
}
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 **private)
{
void *next = NULL;
@@ -161,8 +164,11 @@ out:
pthread_mutex_unlock(&_event_mutex);
}
int register_device(const char *device, const char *uuid, int major, int minor,
void **private)
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;
@@ -201,8 +207,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

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

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
@@ -666,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.
@@ -679,6 +718,7 @@ int monitor_dev_for_events(struct cmd_context *cmd,
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)
@@ -715,6 +755,19 @@ int monitor_dev_for_events(struct cmd_context *cmd,
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;

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.
@@ -100,10 +100,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 +125,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 +156,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 +186,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 +255,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 +342,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 +379,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 +392,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 +434,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;
@@ -509,10 +498,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 +531,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 +628,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,31 +676,25 @@ 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;
}
@@ -843,7 +822,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 +835,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,8 +927,8 @@ 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) {
@@ -987,10 +966,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;
@@ -1010,11 +989,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;
@@ -1039,10 +1021,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.
@@ -282,10 +282,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 +299,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 +379,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 +392,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 +413,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,7 +529,7 @@ 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",
@@ -694,10 +681,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 +721,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 +755,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 +791,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 "
@@ -998,12 +997,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 +1063,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 +1105,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 +1129,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;
@@ -94,5 +95,6 @@ struct cmd_context *create_toolcontext(struct arg *the_args, unsigned is_static,
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

@@ -101,7 +101,10 @@
#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,convert_lv"

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

@@ -48,18 +48,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 +82,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 +104,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;

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

@@ -94,11 +94,6 @@ 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); */
int is_partitioned_dev(struct device *dev);
#endif

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,6 +574,8 @@ 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)
@@ -605,13 +604,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,6 +659,8 @@ 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)));
@@ -663,6 +669,10 @@ void vgdisplay_colons(const struct volume_group *vg)
else
active_pvs = vg->pv_count;
list_iterate_items(lvl, &vg->lvs)
if (lv_is_visible(lvl->lv) && !(lvl->lv->status & SNAPSHOT))
lv_count++;
switch (vg->status & (LVM_READ | LVM_WRITE)) {
case LVM_READ | LVM_WRITE:
access = "r/w";
@@ -698,7 +708,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

@@ -236,21 +236,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 +278,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;
}

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;
@@ -358,7 +356,7 @@ static struct disk_list *__read_disk(const struct format_type *fmt,
list_init(&dl->lvds);
if (!_read_pvd(dev, &dl->pvd))
goto_bad;
goto bad;
/*
* is it an orphan ?
@@ -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

@@ -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,13 +18,10 @@
#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)
{
@@ -168,7 +165,6 @@ static struct volume_group *_build_vg(struct format_instance *fid,
return vg;
bad:
stack;
dm_pool_free(mem, vg);
return NULL;
}
@@ -182,10 +178,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 +203,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 +216,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 +232,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 +241,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 +254,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 +263,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 +278,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 +321,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 +365,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 +379,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 +441,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 +463,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 +513,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;
@@ -117,10 +118,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 +148,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 +164,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 +179,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 &&
@@ -227,20 +218,14 @@ int import_vg(struct dm_pool *mem,
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';
@@ -286,7 +271,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 +284,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 +300,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;
@@ -457,15 +440,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);
@@ -483,17 +462,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++;
@@ -512,10 +487,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;
}
}
@@ -533,49 +506,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;
@@ -658,7 +619,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;
@@ -675,10 +636,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);
@@ -723,10 +682,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;
@@ -91,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,
@@ -167,7 +165,8 @@ 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;
@@ -178,10 +177,8 @@ int import_pool_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;
}
@@ -216,12 +213,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))) {
@@ -230,10 +225,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));
@@ -254,10 +247,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;
@@ -274,10 +265,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;
@@ -302,15 +291,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);
@@ -196,10 +190,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 +219,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 +297,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 +316,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 +331,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);
}

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,48 +25,49 @@
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},
{PARTIAL_VG, "PARTIAL", STATUS_FLAG},
{PVMOVE, "PVMOVE", STATUS_FLAG},
{LVM_READ, "READ", STATUS_FLAG},
{LVM_WRITE, "WRITE", STATUS_FLAG},
{CLUSTERED, "CLUSTERED", STATUS_FLAG},
{SHARED, "SHARED", STATUS_FLAG},
{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},
{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},
{CONVERTING, 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},
{0, NULL, 0}
};
static struct flag *_get_flags(int type)
{
switch (type) {
switch (type & ~STATUS_FLAG) {
case VG_FLAGS:
return _vg_flags;
@@ -91,10 +92,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;
@@ -103,6 +102,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;
@@ -135,10 +137,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;
@@ -155,7 +155,7 @@ int read_flags(uint32_t *status, int type, struct config_value *cv)
break;
}
if (!flags[f].description) {
if (!flags[f].description && (type & STATUS_FLAG)) {
log_err("Unknown status flag '%s'.", cv->v.str);
return 0;
}
@@ -164,6 +164,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),
@@ -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);
@@ -589,10 +569,8 @@ 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,
@@ -602,11 +580,9 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
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,
@@ -652,10 +628,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 +668,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 +734,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 +751,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 +773,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 +1008,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 +1035,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 +1082,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 +1136,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);
}
}
@@ -1328,10 +1294,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,7 +1331,7 @@ 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();
list_iterate_items(mda, &info->mdas) {
@@ -1384,15 +1348,11 @@ static int _text_pv_write(const struct format_type *fmt, struct physical_volume
}
}
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 +1360,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 +1399,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 +1456,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 +1578,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 +1610,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 +1651,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 +1693,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 +1710,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 +1724,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 +1739,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 +1749,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 +1781,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 +1896,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.
@@ -125,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)),
@@ -136,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;
@@ -147,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.");
@@ -180,19 +201,12 @@ static int _read_pv(struct format_instance *fid, struct dm_pool *mem,
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;
}
@@ -231,30 +245,28 @@ static int _read_pv(struct format_instance *fid, struct dm_pool *mem,
pv->pe_alloc_count = 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);
@@ -316,16 +328,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,
@@ -335,10 +343,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")) &&
@@ -403,10 +409,8 @@ 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))) {
if (!set_lv_segment_area_lv(seg, s, lv1,
(uint32_t) cv->next->v.i,
@@ -447,10 +451,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++;
}
@@ -475,18 +477,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;
}
@@ -502,30 +500,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;
}
@@ -538,10 +528,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))
@@ -552,7 +540,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:
@@ -611,10 +599,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;
@@ -664,10 +650,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;
@@ -689,10 +673,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 */
@@ -726,14 +708,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;
}
@@ -770,10 +746,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;
}
/*
@@ -862,7 +836,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;
@@ -870,7 +844,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 */
@@ -891,18 +865,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;
}
@@ -330,7 +330,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 +387,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 +437,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 +480,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,6 +78,7 @@ 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
@@ -91,6 +101,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 +110,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 +127,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.
@@ -51,6 +51,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;
@@ -215,12 +216,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,6 +239,16 @@ 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;
@@ -316,6 +333,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 +372,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 +383,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 +393,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 +403,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 +420,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 +434,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 +457,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

@@ -79,6 +79,7 @@ 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);
@@ -94,6 +95,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

@@ -178,15 +178,12 @@ struct lv_segment *alloc_lv_segment(struct dm_pool *mem,
struct lv_segment *seg;
uint32_t areas_sz = area_count * sizeof(*seg->areas);
if (!(seg = dm_pool_zalloc(mem, sizeof(*seg)))) {
stack;
return NULL;
}
if (!(seg = dm_pool_zalloc(mem, sizeof(*seg))))
return_NULL;
if (!(seg->areas = dm_pool_zalloc(mem, areas_sz))) {
dm_pool_free(mem, seg);
stack;
return NULL;
return_NULL;
}
if (!segtype) {
@@ -290,10 +287,8 @@ int move_lv_segment_area(struct lv_segment *seg_to, uint32_t area_to,
seg_from->area_len);
release_lv_segment_area(seg_to, area_to, seg_to->area_len);
if (!set_lv_segment_area_pv(seg_to, area_to, pv, pe)) {
stack;
return 0;
}
if (!set_lv_segment_area_pv(seg_to, area_to, pv, pe))
return_0;
break;
@@ -326,10 +321,8 @@ int set_lv_segment_area_pv(struct lv_segment *seg, uint32_t area_num,
seg->areas[area_num].type = AREA_PV;
if (!(seg_pvseg(seg, area_num) =
assign_peg_to_lvseg(pv, pe, seg->area_len, seg, area_num))) {
stack;
return 0;
}
assign_peg_to_lvseg(pv, pe, seg->area_len, seg, area_num)))
return_0;
return 1;
}
@@ -365,10 +358,8 @@ static int _lv_segment_add_areas(struct logical_volume *lv,
struct lv_segment_area *newareas;
uint32_t areas_sz = new_area_count * sizeof(*newareas);
if (!(newareas = dm_pool_zalloc(lv->vg->cmd->mem, areas_sz))) {
stack;
return 0;
}
if (!(newareas = dm_pool_zalloc(lv->vg->cmd->mem, areas_sz)))
return_0;
memcpy(newareas, seg->areas, seg->area_count * sizeof(*seg->areas));
@@ -423,19 +414,15 @@ static int _lv_reduce(struct logical_volume *lv, uint32_t extents, int delete)
if (seg->len <= count) {
/* remove this segment completely */
/* FIXME Check this is safe */
if (seg->log_lv && !lv_remove(seg->log_lv)) {
stack;
return 0;
}
if (seg->log_lv && !lv_remove(seg->log_lv))
return_0;
list_del(&seg->list);
reduction = seg->len;
} else
reduction = count;
if (!_lv_segment_reduce(seg, reduction)) {
stack;
return 0;
}
if (!_lv_segment_reduce(seg, reduction))
return_0;
count -= reduction;
}
@@ -447,19 +434,16 @@ static int _lv_reduce(struct logical_volume *lv, uint32_t extents, int delete)
/* Remove the LV if it is now empty */
if (!lv->le_count) {
if (!(lvl = find_lv_in_vg(lv->vg, lv->name))) {
stack;
return 0;
}
if (!(lvl = find_lv_in_vg(lv->vg, lv->name)))
return_0;
list_del(&lvl->list);
lv->vg->lv_count--;
if (!(lv->status & SNAPSHOT))
lv->vg->lv_count--;
} else if (lv->vg->fid->fmt->ops->lv_setup &&
!lv->vg->fid->fmt->ops->lv_setup(lv->vg->fid, lv)) {
stack;
return 0;
}
!lv->vg->fid->fmt->ops->lv_setup(lv->vg->fid, lv))
return_0;
return 1;
}
@@ -504,10 +488,8 @@ int lv_reduce(struct logical_volume *lv, uint32_t extents)
int lv_remove(struct logical_volume *lv)
{
if (!lv_reduce(lv, lv->le_count)) {
stack;
return 0;
}
if (!lv_reduce(lv, lv->le_count))
return_0;
return 1;
}
@@ -684,12 +666,9 @@ static int _setup_alloced_segment(struct logical_volume *lv, uint32_t status,
return 0;
}
for (s = 0; s < area_count; s++) {
if (!set_lv_segment_area_pv(seg, s, aa[s].pv, aa[s].pe)) {
stack;
return 0;
}
}
for (s = 0; s < area_count; s++)
if (!set_lv_segment_area_pv(seg, s, aa[s].pv, aa[s].pe))
return_0;
list_add(&lv->segments, &seg->list);
@@ -717,10 +696,8 @@ static int _setup_alloced_segments(struct logical_volume *lv,
list_iterate_items(aa, &alloced_areas[0]) {
if (!_setup_alloced_segment(lv, status, area_count,
stripe_size, segtype, aa,
region_size, log_lv)) {
stack;
return 0;
}
region_size, log_lv))
return_0;
}
return 1;
@@ -1142,10 +1119,8 @@ static int _find_parallel_space(struct alloc_handle *ah, alloc_policy_t alloc,
allocated,
(ah->log_count && !ah->log_area.len) ?
*(areas + ix_offset + ix - 1) :
NULL)) {
stack;
return 0;
}
NULL))
return_0;
} while (!contiguous && *allocated != needed && can_split);
@@ -1187,10 +1162,8 @@ static int _allocate(struct alloc_handle *ah,
/*
* Build the sets of available areas on the pv's.
*/
if (!(pvms = create_pv_maps(ah->mem, vg, allocatable_pvs))) {
stack;
return 0;
}
if (!(pvms = create_pv_maps(ah->mem, vg, allocatable_pvs)))
return_0;
if (!_log_parallel_areas(ah->mem, ah->parallel_areas))
stack;
@@ -1315,9 +1288,8 @@ struct alloc_handle *allocate_extents(struct volume_group *vg,
if (!segtype_is_virtual(segtype) &&
!_allocate(ah, vg, lv, (lv ? lv->le_count : 0) + extents,
1, allocatable_pvs)) {
stack;
alloc_destroy(ah);
return NULL;
return_NULL;
}
return ah;
@@ -1348,10 +1320,8 @@ int lv_add_segment(struct alloc_handle *ah,
if (!_setup_alloced_segments(lv, &ah->alloced_areas[first_area],
num_areas, status,
stripe_size, segtype,
region_size, log_lv)) {
stack;
return 0;
}
region_size, log_lv))
return_0;
if ((segtype->flags & SEG_CAN_SPLIT) && !lv_merge_segments(lv)) {
log_err("Couldn't merge segments after extending "
@@ -1360,10 +1330,8 @@ int lv_add_segment(struct alloc_handle *ah,
}
if (lv->vg->fid->fmt->ops->lv_setup &&
!lv->vg->fid->fmt->ops->lv_setup(lv->vg->fid, lv)) {
stack;
return 0;
}
!lv->vg->fid->fmt->ops->lv_setup(lv->vg->fid, lv))
return_0;
return 1;
}
@@ -1615,10 +1583,8 @@ int lv_extend(struct logical_volume *lv,
if (mirrors < 2) {
if (!lv_add_segment(ah, 0, ah->area_count, lv, segtype, stripe_size,
status, 0, NULL)) {
stack;
goto out;
}
status, 0, NULL))
goto_out;
} else {
if (!_lv_extend_mirror(ah, lv, extents, 0))
return_0;
@@ -1714,8 +1680,8 @@ static int _rename_cb(struct cmd_context *cmd, struct logical_volume *lv,
*/
static int _for_each_sub_lv(struct cmd_context *cmd, struct logical_volume *lv,
int (*func)(struct cmd_context *cmd,
struct logical_volume *lv,
void *data),
struct logical_volume *lv,
void *data),
void *data)
{
struct lv_segment *seg;
@@ -1890,10 +1856,9 @@ struct logical_volume *lv_create_empty(const char *name,
lv->lvid = *lvid;
if (fi->fmt->ops->lv_setup && !fi->fmt->ops->lv_setup(fi, lv)) {
stack;
if (ll)
dm_pool_free(cmd->mem, ll);
return NULL;
return_NULL;
}
if (!import)
@@ -1911,8 +1876,7 @@ static int _add_pvs(struct cmd_context *cmd, struct pv_segment *peg,
struct pv_list *pvl;
/* Don't add again if it's already on list. */
list_iterate_items(pvl, &spvs->pvs)
if (pvl->pv == peg->pv)
if (find_pv_in_pv_list(&spvs->pvs, peg->pv))
return 1;
if (!(pvl = dm_pool_alloc(cmd->mem, sizeof(*pvl)))) {
@@ -1960,10 +1924,8 @@ struct list *build_parallel_areas_from_lv(struct cmd_context *cmd,
/* Find next segment end */
/* FIXME Unnecessary nesting! */
if (!_for_each_pv(cmd, lv, current_le, spvs->len, &spvs->len,
0, 0, -1, 0, _add_pvs, (void *) spvs)) {
stack;
return NULL;
}
0, 0, -1, 0, _add_pvs, (void *) spvs))
return_NULL;
current_le = spvs->le + spvs->len;
} while (current_le < lv->le_count);
@@ -2022,7 +1984,7 @@ int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv,
* 1) Clustered VG, and some remote nodes have the LV active
* 2) Non-clustered VG, but LV active locally
*/
if ((vg_status(vg) & CLUSTERED) && !activate_lv_excl(cmd, lv) &&
if (vg_is_clustered(vg) && !activate_lv_excl(cmd, lv) &&
(force == PROMPT)) {
if (yes_no_prompt("Logical volume \"%s\" is active on other "
"cluster nodes. Really remove? [y/n]: ",
@@ -2055,10 +2017,8 @@ int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv,
if (lv_is_cow(lv)) {
origin = origin_from_cow(lv);
log_verbose("Removing snapshot %s", lv->name);
if (!vg_remove_snapshot(lv)) {
stack;
return 0;
}
if (!vg_remove_snapshot(lv))
return_0;
}
log_verbose("Releasing logical volume \"%s\"", lv->name);
@@ -2088,6 +2048,27 @@ int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv,
return 1;
}
/*
* remove LVs with its dependencies - LV leaf nodes should be removed first
*/
int lv_remove_with_dependencies(struct cmd_context *cmd, struct logical_volume *lv,
const force_t force)
{
struct list *snh, *snht;
if (lv_is_origin(lv)) {
/* remove snapshot LVs first */
list_iterate_safe(snh, snht, &lv->snapshot_segs) {
if (!lv_remove_with_dependencies(cmd, list_struct_base(snh, struct lv_segment,
origin_list)->cow,
force))
return 0;
}
}
return lv_remove_single(cmd, lv, force);
}
/*
* insert_layer_for_segments_on_pv() inserts a layer segment for a segment area.
* However, layer modification could split the underlying layer segment.
@@ -2348,6 +2329,9 @@ int remove_layer_from_lv(struct logical_volume *lv,
parent->le_count != layer_lv->le_count)
return_0;
if (!lv_empty(parent))
return_0;
if (!_move_lv_segments(parent, layer_lv, 0, 0))
return_0;

View File

@@ -24,7 +24,7 @@
/*
* Attempt to merge two adjacent segments.
* Currently only supports striped segments on AREA_PV.
* Returns success if successful, in which case 'first'
* Returns success if successful, in which case 'first'
* gets adjusted to contain both areas.
*/
static int _merge(struct lv_segment *first, struct lv_segment *second)
@@ -76,7 +76,7 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
r = 0;
}
area_multiplier = segtype_is_striped(seg->segtype) ?
area_multiplier = segtype_is_striped(seg->segtype) ?
seg->area_count : 1;
if (seg->area_len * area_multiplier != seg->len) {
@@ -224,6 +224,20 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
seg->le + seg->len - 1, seg_found);
r = 0;
}
seg_found = 0;
list_iterate_items(seg2, &seg->lv->segments)
if (sl->seg == seg2) {
seg_found++;
break;
}
if (!seg_found) {
log_error("LV segment %s:%" PRIu32 "-%" PRIu32
"is incorrectly listed as being used by LV %s",
seg->lv->name, seg->le, seg->le + seg->len - 1,
lv->name);
r = 0;
}
}
if (le != lv->le_count) {
@@ -305,10 +319,8 @@ static int _lv_split_segment(struct logical_volume *lv, struct lv_segment *seg,
seg->area_len,
seg_pvseg(seg, s)->len -
seg->area_len,
split_seg, s))) {
stack;
return 0;
}
split_seg, s)))
return_0;
log_debug("Split %s:%u[%u] at %u: %s PE %u", lv->name,
seg->le, s, le,
dev_name(seg_dev(seg, s)),
@@ -344,15 +356,11 @@ int lv_split_segment(struct logical_volume *lv, uint32_t le)
if (le == seg->le)
return 1;
if (!_lv_split_segment(lv, seg, le)) {
stack;
return 0;
}
if (!_lv_split_segment(lv, seg, le))
return_0;
if (!vg_validate(lv->vg)) {
stack;
return 0;
}
if (!vg_validate(lv->vg))
return_0;
return 1;
}

View File

@@ -133,6 +133,7 @@ struct format_type {
struct labeller *labeller;
const char *name;
const char *alias;
const char *orphan_vg_name;
uint32_t features;
void *library;
void *private;
@@ -150,6 +151,8 @@ struct pv_segment {
uint32_t lv_area; /* Index to area in LV segment */
};
#define pvseg_is_allocated(pvseg) ((pvseg)->lvseg)
struct physical_volume {
struct id id;
struct device *dev;
@@ -199,7 +202,23 @@ struct volume_group {
uint32_t pv_count;
struct list pvs;
/* logical volumes */
/*
* logical volumes
* The following relationship should always hold:
* list_size(lvs) = lv_count + 2 * snapshot_count
*
* Snapshots consist of 2 instances of "struct logical_volume":
* - cow (lv_name is visible to the user)
* - snapshot (lv_name is 'snapshotN')
* Neither of these instances is reflected in lv_count, but we
* multiply the snapshot_count by 2.
*
* Mirrors consist of multiple instances of "struct logical_volume":
* - one for the mirror log
* - one for each mirror leg
* - one for the user-visible mirror LV
* all of the instances are reflected in lv_count.
*/
uint32_t lv_count;
uint32_t snapshot_count;
struct list lvs;
@@ -317,7 +336,7 @@ int pv_write(struct cmd_context *cmd, struct physical_volume *pv,
struct list *mdas, int64_t label_sector);
int is_pv(pv_t *pv);
int is_orphan_vg(const char *vg_name);
int is_orphan(pv_t *pv);
int is_orphan(const pv_t *pv);
int vgs_are_compatible(struct cmd_context *cmd,
struct volume_group *vg_from,
struct volume_group *vg_to);
@@ -328,7 +347,7 @@ vg_t *vg_lock_and_read(struct cmd_context *cmd, const char *vg_name,
/* pe_start and pe_end relate to any existing data so that new metadata
* areas can avoid overlap */
pv_t *pv_create(const struct format_type *fmt,
pv_t *pv_create(const struct cmd_context *cmd,
struct device *dev,
struct id *id,
uint64_t size,
@@ -397,6 +416,9 @@ int lv_remove(struct logical_volume *lv);
int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv,
force_t force);
int lv_remove_with_dependencies(struct cmd_context *cmd, struct logical_volume *lv,
force_t force);
int lv_rename(struct cmd_context *cmd, struct logical_volume *lv,
const char *new_name);
@@ -427,14 +449,18 @@ struct logical_volume *insert_layer_for_lv(struct cmd_context *cmd,
const char *layer_suffix);
/* Find a PV within a given VG */
struct pv_list *find_pv_in_vg(struct volume_group *vg, const char *pv_name);
pv_t *find_pv_in_vg_by_uuid(struct volume_group *vg, struct id *id);
struct pv_list *find_pv_in_vg(const struct volume_group *vg,
const char *pv_name);
pv_t *find_pv_in_vg_by_uuid(const struct volume_group *vg,
const struct id *id);
/* Find an LV within a given VG */
struct lv_list *find_lv_in_vg(struct volume_group *vg, const char *lv_name);
struct lv_list *find_lv_in_vg(const struct volume_group *vg,
const char *lv_name);
/* FIXME Merge these functions with ones above */
struct logical_volume *find_lv(struct volume_group *vg, const char *lv_name);
struct logical_volume *find_lv(const struct volume_group *vg,
const char *lv_name);
struct physical_volume *find_pv_by_name(struct cmd_context *cmd,
const char *pv_name);
@@ -506,6 +532,7 @@ int add_mirror_log(struct cmd_context *cmd, struct logical_volume *lv,
int reconfigure_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors,
struct list *removable_pvs, unsigned remove_log);
int collapse_mirrored_lv(struct logical_volume *lv);
int shift_mirror_images(struct lv_segment *mirrored_seg, unsigned mimage);
struct logical_volume *find_pvmove_lv(struct volume_group *vg,
struct device *dev, uint32_t lv_type);
@@ -537,6 +564,7 @@ uint32_t pv_pe_count(const pv_t *pv);
uint32_t pv_pe_alloc_count(const pv_t *pv);
uint32_t vg_status(const vg_t *vg);
#define vg_is_clustered(vg) (vg_status((vg)) & CLUSTERED)
struct vgcreate_params {
char *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.
@@ -36,9 +36,9 @@
#define pv_field(handle, field) \
(((const struct physical_volume *)(handle))->field)
static struct physical_volume *_pv_read(struct cmd_context *cmd,
static struct physical_volume *_pv_read(struct cmd_context *cmd,
const char *pv_name,
struct list *mdas,
struct list *mdas,
uint64_t *label_sector,
int warnings);
@@ -51,17 +51,18 @@ static struct physical_volume *_pv_create(const struct format_type *fmt,
int pvmetadatacopies,
uint64_t pvmetadatasize, struct list *mdas);
static int _pv_write(struct cmd_context *cmd __attribute((unused)),
static int _pv_write(struct cmd_context *cmd __attribute((unused)),
struct physical_volume *pv,
struct list *mdas, int64_t label_sector);
static struct physical_volume *_find_pv_by_name(struct cmd_context *cmd,
const char *pv_name);
static struct pv_list *_find_pv_in_vg(struct volume_group *vg, const char *pv_name);
static struct pv_list *_find_pv_in_vg(const struct volume_group *vg,
const char *pv_name);
static struct physical_volume *_find_pv_in_vg_by_uuid(struct volume_group *vg,
struct id *id);
static struct physical_volume *_find_pv_in_vg_by_uuid(const struct volume_group *vg,
const struct id *id);
unsigned long pe_align(void)
{
@@ -154,10 +155,8 @@ int add_pv_to_vg(struct volume_group *vg, const char *pv_name,
return 0;
}
if (!alloc_pv_segment_whole_pv(mem, pv)) {
stack;
return 0;
}
if (!alloc_pv_segment_whole_pv(mem, pv))
return_0;
pvl->pv = pv;
list_add(&vg->pvs, &pvl->list);
@@ -189,10 +188,8 @@ static int _copy_pv(struct physical_volume *pv_to,
}
if (!peg_dup(pv_to->fmt->cmd->mem, &pv_to->segments,
&pv_from->segments)) {
stack;
return 0;
}
&pv_from->segments))
return_0;
return 1;
}
@@ -217,10 +214,8 @@ int get_pv_from_vg_by_id(const struct format_type *fmt, const char *vg_name,
list_iterate_items(pvl, &vg->pvs) {
if (id_equal(&pvl->pv->id, (const struct id *) pvid)) {
if (!_copy_pv(pv, pvl->pv)) {
stack;
return 0;
}
if (!_copy_pv(pv, pvl->pv))
return_0;
return 1;
}
}
@@ -301,11 +296,14 @@ static int remove_lvs_in_vg(struct cmd_context *cmd,
struct volume_group *vg,
force_t force)
{
struct list *lst;
struct lv_list *lvl;
list_iterate_items(lvl, &vg->lvs)
if (!lv_remove_single(cmd, lvl->lv, force))
return 0;
while ((lst = list_first(&vg->lvs))) {
lvl = list_item(lst, struct lv_list);
if (!lv_remove_with_dependencies(cmd, lvl->lv, force))
return 0;
}
return 1;
}
@@ -362,7 +360,7 @@ int vg_remove_single(struct cmd_context *cmd, const char *vg_name,
pv = pvl->pv;
log_verbose("Removing physical volume \"%s\" from "
"volume group \"%s\"", pv_dev_name(pv), vg_name);
pv->vg_name = ORPHAN;
pv->vg_name = vg->fid->fmt->orphan_vg_name;
pv->status = ALLOCATABLE_PV;
if (!dev_get_size(pv_dev(pv), &pv->size)) {
@@ -475,10 +473,8 @@ struct volume_group *vg_create(struct cmd_context *cmd, const char *vg_name,
int consistent = 0;
int old_partial;
if (!(vg = dm_pool_zalloc(mem, sizeof(*vg)))) {
stack;
return NULL;
}
if (!(vg = dm_pool_zalloc(mem, sizeof(*vg))))
return_NULL;
/* is this vg name already in use ? */
old_partial = partial_mode();
@@ -499,10 +495,8 @@ struct volume_group *vg_create(struct cmd_context *cmd, const char *vg_name,
vg->cmd = cmd;
if (!(vg->name = dm_pool_strdup(mem, vg_name))) {
stack;
goto bad;
}
if (!(vg->name = dm_pool_strdup(mem, vg_name)))
goto_bad;
vg->seqno = 0;
@@ -595,22 +589,16 @@ int vg_change_pesize(struct cmd_context *cmd __attribute((unused)),
vg->extent_size = new_size;
if (vg->fid->fmt->ops->vg_setup &&
!vg->fid->fmt->ops->vg_setup(vg->fid, vg)) {
stack;
return 0;
}
!vg->fid->fmt->ops->vg_setup(vg->fid, vg))
return_0;
if (!_recalc_extents(&vg->extent_count, vg->name, "", old_size,
new_size)) {
stack;
return 0;
}
new_size))
return_0;
if (!_recalc_extents(&vg->free_count, vg->name, " free space",
old_size, new_size)) {
stack;
return 0;
}
old_size, new_size))
return_0;
/* foreach PV */
list_iterate_items(pvl, &vg->pvs) {
@@ -618,34 +606,26 @@ int vg_change_pesize(struct cmd_context *cmd __attribute((unused)),
pv->pe_size = new_size;
if (!_recalc_extents(&pv->pe_count, pv_dev_name(pv), "",
old_size, new_size)) {
stack;
return 0;
}
old_size, new_size))
return_0;
if (!_recalc_extents(&pv->pe_alloc_count, pv_dev_name(pv),
" allocated space", old_size, new_size)) {
stack;
return 0;
}
" allocated space", old_size, new_size))
return_0;
/* foreach free PV Segment */
list_iterate_items(pvseg, &pv->segments) {
if (pvseg->lvseg)
if (pvseg_is_allocated(pvseg))
continue;
if (!_recalc_extents(&pvseg->pe, pv_dev_name(pv),
" PV segment start", old_size,
new_size)) {
stack;
return 0;
}
new_size))
return_0;
if (!_recalc_extents(&pvseg->len, pv_dev_name(pv),
" PV segment length", old_size,
new_size)) {
stack;
return 0;
}
new_size))
return_0;
}
}
@@ -654,39 +634,29 @@ int vg_change_pesize(struct cmd_context *cmd __attribute((unused)),
lv = lvl->lv;
if (!_recalc_extents(&lv->le_count, lv->name, "", old_size,
new_size)) {
stack;
return 0;
}
new_size))
return_0;
list_iterate_items(seg, &lv->segments) {
if (!_recalc_extents(&seg->le, lv->name,
" segment start", old_size,
new_size)) {
stack;
return 0;
}
new_size))
return_0;
if (!_recalc_extents(&seg->len, lv->name,
" segment length", old_size,
new_size)) {
stack;
return 0;
}
new_size))
return_0;
if (!_recalc_extents(&seg->area_len, lv->name,
" area length", old_size,
new_size)) {
stack;
return 0;
}
new_size))
return_0;
if (!_recalc_extents(&seg->extents_copied, lv->name,
" extents moved", old_size,
new_size)) {
stack;
return 0;
}
new_size))
return_0;
/* foreach area */
for (s = 0; s < seg->area_count; s++) {
@@ -696,27 +666,21 @@ int vg_change_pesize(struct cmd_context *cmd __attribute((unused)),
(&seg_pe(seg, s),
lv->name,
" pvseg start", old_size,
new_size)) {
stack;
return 0;
}
new_size))
return_0;
if (!_recalc_extents
(&seg_pvseg(seg, s)->len,
lv->name,
" pvseg length", old_size,
new_size)) {
stack;
return 0;
}
new_size))
return_0;
break;
case AREA_LV:
if (!_recalc_extents
(&seg_le(seg, s), lv->name,
" area start", old_size,
new_size)) {
stack;
return 0;
}
new_size))
return_0;
break;
case AREA_UNASSIGNED:
log_error("Unassigned area %u found in "
@@ -731,6 +695,10 @@ int vg_change_pesize(struct cmd_context *cmd __attribute((unused)),
return 1;
}
/*
* Separate metadata areas after splitting a VG.
* Also accepts orphan VG as destination (for vgreduce).
*/
int vg_split_mdas(struct cmd_context *cmd __attribute((unused)),
struct volume_group *vg_from, struct volume_group *vg_to)
{
@@ -748,12 +716,15 @@ int vg_split_mdas(struct cmd_context *cmd __attribute((unused)),
}
if (!mda->ops->mda_in_vg(vg_from->fid, vg_from, mda)) {
list_del(&mda->list);
list_add(mdas_to, &mda->list);
if (is_orphan_vg(vg_to->name))
list_del(&mda->list);
else
list_move(mdas_to, &mda->list);
}
}
if (list_empty(mdas_from) || list_empty(mdas_to))
if (list_empty(mdas_from) ||
(!is_orphan_vg(vg_to->name) && list_empty(mdas_to)))
return common_mda;
return 1;
@@ -779,7 +750,7 @@ int vg_split_mdas(struct cmd_context *cmd __attribute((unused)),
* Note:
* FIXME - liblvm todo - tidy up arguments for external use (fmt, mdas, etc)
*/
pv_t *pv_create(const struct format_type *fmt,
pv_t *pv_create(const struct cmd_context *cmd,
struct device *dev,
struct id *id, uint64_t size,
uint64_t pe_start,
@@ -788,7 +759,7 @@ pv_t *pv_create(const struct format_type *fmt,
int pvmetadatacopies,
uint64_t pvmetadatasize, struct list *mdas)
{
return _pv_create(fmt, dev, id, size, pe_start,
return _pv_create(cmd->fmt, dev, id, size, pe_start,
existing_extent_count,
existing_extent_size,
pvmetadatacopies,
@@ -804,10 +775,8 @@ static struct physical_volume *_alloc_pv(struct dm_pool *mem)
{
struct physical_volume *pv = dm_pool_zalloc(mem, sizeof(*pv));
if (!pv) {
stack;
return NULL;
}
if (!pv)
return_NULL;
if (!(pv->vg_name = dm_pool_zalloc(mem, NAME_LEN))) {
dm_pool_free(mem, pv);
@@ -875,6 +844,7 @@ static struct physical_volume *_pv_create(const struct format_type *fmt,
}
pv->fmt = fmt;
pv->vg_name = fmt->orphan_vg_name;
if (!fmt->ops->pv_setup(fmt, pe_start, existing_extent_count,
existing_extent_size,
@@ -892,12 +862,14 @@ static struct physical_volume *_pv_create(const struct format_type *fmt,
}
/* FIXME: liblvm todo - make into function that returns handle */
struct pv_list *find_pv_in_vg(struct volume_group *vg, const char *pv_name)
struct pv_list *find_pv_in_vg(const struct volume_group *vg,
const char *pv_name)
{
return _find_pv_in_vg(vg, pv_name);
}
static struct pv_list *_find_pv_in_vg(struct volume_group *vg, const char *pv_name)
static struct pv_list *_find_pv_in_vg(const struct volume_group *vg,
const char *pv_name)
{
struct pv_list *pvl;
@@ -908,6 +880,18 @@ static struct pv_list *_find_pv_in_vg(struct volume_group *vg, const char *pv_na
return NULL;
}
struct pv_list *find_pv_in_pv_list(const struct list *pl,
const struct physical_volume *pv)
{
struct pv_list *pvl;
list_iterate_items(pvl, pl)
if (pvl->pv == pv)
return pvl;
return NULL;
}
int pv_is_in_vg(struct volume_group *vg, struct physical_volume *pv)
{
struct pv_list *pvl;
@@ -931,14 +915,15 @@ int pv_is_in_vg(struct volume_group *vg, struct physical_volume *pv)
* Note
* FIXME - liblvm todo - make into function that takes VG handle
*/
pv_t *find_pv_in_vg_by_uuid(struct volume_group *vg, struct id *id)
pv_t *find_pv_in_vg_by_uuid(const struct volume_group *vg,
const struct id *id)
{
return _find_pv_in_vg_by_uuid(vg, id);
}
static struct physical_volume *_find_pv_in_vg_by_uuid(struct volume_group *vg,
struct id *id)
static struct physical_volume *_find_pv_in_vg_by_uuid(const struct volume_group *vg,
const struct id *id)
{
struct pv_list *pvl;
@@ -949,7 +934,8 @@ static struct physical_volume *_find_pv_in_vg_by_uuid(struct volume_group *vg,
return NULL;
}
struct lv_list *find_lv_in_vg(struct volume_group *vg, const char *lv_name)
struct lv_list *find_lv_in_vg(const struct volume_group *vg,
const char *lv_name)
{
struct lv_list *lvl;
const char *ptr;
@@ -967,6 +953,18 @@ struct lv_list *find_lv_in_vg(struct volume_group *vg, const char *lv_name)
return NULL;
}
struct lv_list *find_lv_in_lv_list(const struct list *ll,
const struct logical_volume *lv)
{
struct lv_list *lvl;
list_iterate_items(lvl, ll)
if (lvl->lv == lv)
return lvl;
return NULL;
}
struct lv_list *find_lv_in_vg_by_lvid(struct volume_group *vg,
const union lvid *lvid)
{
@@ -979,7 +977,8 @@ struct lv_list *find_lv_in_vg_by_lvid(struct volume_group *vg,
return NULL;
}
struct logical_volume *find_lv(struct volume_group *vg, const char *lv_name)
struct logical_volume *find_lv(const struct volume_group *vg,
const char *lv_name)
{
struct lv_list *lvl = find_lv_in_vg(vg, lv_name);
return lvl ? lvl->lv : NULL;
@@ -1074,10 +1073,8 @@ int vg_remove(struct volume_group *vg)
/* Remove each copy of the metadata */
list_iterate_items(mda, &vg->fid->metadata_areas) {
if (mda->ops->vg_remove &&
!mda->ops->vg_remove(vg->fid, vg, mda)) {
stack;
return 0;
}
!mda->ops->vg_remove(vg->fid, vg, mda))
return_0;
}
return 1;
@@ -1132,7 +1129,7 @@ int vgs_are_compatible(struct cmd_context *cmd __attribute((unused)),
}
/* Clustering attribute must be the same */
if ((vg_to->status & CLUSTERED) != (vg_from->status & CLUSTERED)) {
if (vg_is_clustered(vg_to) != vg_is_clustered(vg_from)) {
log_error("Clustered attribute differs for \"%s\" and \"%s\"",
vg_to->name, vg_from->name);
return 0;
@@ -1183,6 +1180,7 @@ int vg_validate(struct volume_group *vg)
struct lv_list *lvl, *lvl2;
char uuid[64] __attribute((aligned(8)));
int r = 1;
uint32_t lv_count;
/* FIXME Also check there's no data/metadata overlap */
@@ -1216,6 +1214,15 @@ int vg_validate(struct volume_group *vg)
r = 0;
}
if ((lv_count = (uint32_t) list_size(&vg->lvs)) !=
vg->lv_count + 2 * vg->snapshot_count) {
log_error("Internal error: #internal LVs (%u) != #LVs (%"
PRIu32 ") + 2 * #snapshots (%" PRIu32 ") in VG %s",
list_size(&vg->lvs), vg->lv_count,
vg->snapshot_count, vg->name);
r = 0;
}
list_iterate_items(lvl, &vg->lvs) {
list_iterate_items(lvl2, &vg->lvs) {
if (lvl == lvl2)
@@ -1248,6 +1255,13 @@ int vg_validate(struct volume_group *vg)
}
}
if (!(vg->fid->fmt->features & FMT_UNLIMITED_VOLS) &&
(!vg->max_lv || !vg->max_pv)) {
log_error("Internal error: Volume group %s has limited PV/LV count"
" but limit is not set.", vg->name);
r = 0;
}
return r;
}
@@ -1260,10 +1274,8 @@ int vg_write(struct volume_group *vg)
struct list *mdah;
struct metadata_area *mda;
if (!vg_validate(vg)) {
stack;
return 0;
}
if (!vg_validate(vg))
return_0;
if (vg->status & PARTIAL_VG) {
log_error("Cannot change metadata for partial volume group %s",
@@ -1276,6 +1288,11 @@ int vg_write(struct volume_group *vg)
return 0;
}
if (!drop_cached_metadata(vg)) {
log_error("Unable to drop cached metadata for VG %s.", vg->name);
return 0;
}
vg->seqno++;
/* Write to each copy of the metadata area */
@@ -1335,6 +1352,12 @@ int vg_commit(struct volume_group *vg)
int cache_updated = 0;
int failed = 0;
if (!vgname_is_locked(vg->name)) {
log_error("Internal error: Attempt to write new VG metadata "
"without locking %s", vg->name);
return cache_updated;
}
/* Commit to each copy of the metadata area */
list_iterate_items(mda, &vg->fid->metadata_areas) {
failed = 0;
@@ -1345,11 +1368,16 @@ int vg_commit(struct volume_group *vg)
}
/* Update cache first time we succeed */
if (!failed && !cache_updated) {
lvmcache_update_vg(vg);
lvmcache_update_vg(vg, 0);
cache_updated = 1;
}
}
/* If update failed, remove any cached precommitted metadata. */
if (!cache_updated && !drop_cached_metadata(vg))
log_error("Attempt to drop cached metadata failed "
"after commit for VG %s.", vg->name);
/* If at least one mda commit succeeded, it was committed */
return cache_updated;
}
@@ -1366,11 +1394,16 @@ int vg_revert(struct volume_group *vg)
}
}
if (!drop_cached_metadata(vg))
log_error("Attempt to drop cached metadata failed "
"after reverted update for VG %s.", vg->name);
return 1;
}
/* Make orphan PVs look like a VG */
static struct volume_group *_vg_read_orphans(struct cmd_context *cmd)
static struct volume_group *_vg_read_orphans(struct cmd_context *cmd,
const char *orphan_vgname)
{
struct lvmcache_vginfo *vginfo;
struct lvmcache_info *info;
@@ -1378,10 +1411,10 @@ static struct volume_group *_vg_read_orphans(struct cmd_context *cmd)
struct volume_group *vg;
struct physical_volume *pv;
if (!(vginfo = vginfo_from_vgname(ORPHAN, NULL))) {
stack;
return NULL;
}
lvmcache_label_scan(cmd, 0);
if (!(vginfo = vginfo_from_vgname(orphan_vgname, NULL)))
return_NULL;
if (!(vg = dm_pool_zalloc(cmd->mem, sizeof(*vg)))) {
log_error("vg allocation failed");
@@ -1391,11 +1424,20 @@ static struct volume_group *_vg_read_orphans(struct cmd_context *cmd)
list_init(&vg->lvs);
list_init(&vg->tags);
vg->cmd = cmd;
if (!(vg->name = dm_pool_strdup(cmd->mem, ORPHAN))) {
if (!(vg->name = dm_pool_strdup(cmd->mem, orphan_vgname))) {
log_error("vg name allocation failed");
return NULL;
}
/* create format instance with appropriate metadata area */
if (!(vg->fid = vginfo->fmt->ops->create_instance(vginfo->fmt,
orphan_vgname, NULL,
NULL))) {
log_error("Failed to create format instance");
dm_pool_free(cmd->mem, vg);
return NULL;
}
list_iterate_items(info, &vginfo->infos) {
if (!(pv = _pv_read(cmd, dev_name(info->dev), NULL, NULL, 1))) {
continue;
@@ -1440,23 +1482,27 @@ static int _update_pv_list(struct list *all_pvs, struct volume_group *vg)
* inconsistent metadata on disk (i.e. the VG write lock is held).
* This guarantees only consistent metadata is returned unless PARTIAL_VG.
* If consistent is 0, caller must check whether consistent == 1 on return
* and take appropriate action if it isn't (e.g. abort; get write lock
* and take appropriate action if it isn't (e.g. abort; get write lock
* and call vg_read again).
*
* If precommitted is set, use precommitted metadata if present.
*
* Either of vgname or vgid may be NULL.
*/
static struct volume_group *_vg_read(struct cmd_context *cmd,
const char *vgname,
const char *vgid,
int *consistent, int precommitted)
int *consistent, unsigned precommitted)
{
struct format_instance *fid;
const struct format_type *fmt;
struct volume_group *vg, *correct_vg = NULL;
struct metadata_area *mda;
struct lvmcache_info *info;
int inconsistent = 0;
int inconsistent_vgid = 0;
int use_precommitted = precommitted;
int inconsistent_pvs = 0;
unsigned use_precommitted = precommitted;
struct list *pvids;
struct pv_list *pvl, *pvl2;
struct list all_pvs;
@@ -1469,7 +1515,12 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
return NULL;
}
*consistent = 1;
return _vg_read_orphans(cmd);
return _vg_read_orphans(cmd, vgname);
}
if ((correct_vg = lvmcache_get_vg(vgid, precommitted))) {
*consistent = 1;
return correct_vg;
}
/* Find the vgname in the cache */
@@ -1477,33 +1528,31 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
if (!(fmt = fmt_from_vgname(vgname, vgid))) {
lvmcache_label_scan(cmd, 0);
if (!(fmt = fmt_from_vgname(vgname, vgid))) {
if (memlock()) {
stack;
return NULL;
}
if (memlock())
return_NULL;
lvmcache_label_scan(cmd, 2);
if (!(fmt = fmt_from_vgname(vgname, vgid))) {
stack;
return NULL;
}
if (!(fmt = fmt_from_vgname(vgname, vgid)))
return_NULL;
}
}
/* Now determine the correct vgname if none was supplied */
if (!vgname && !(vgname = vgname_from_vgid(cmd->mem, vgid)))
return_NULL;
if (use_precommitted && !(fmt->features & FMT_PRECOMMIT))
use_precommitted = 0;
/* Store pvids for later so we can check if any are missing */
if (!(pvids = lvmcache_get_pvids(cmd, vgname, vgid))) {
stack;
return NULL;
}
/* create format instance with appropriate metadata area */
if (!(fid = fmt->ops->create_instance(fmt, vgname, vgid, NULL))) {
log_error("Failed to create format instance");
return NULL;
}
/* Store pvids for later so we can check if any are missing */
if (!(pvids = lvmcache_get_pvids(cmd, vgname, vgid)))
return_NULL;
/* Ensure contents of all metadata areas match - else do recovery */
list_iterate_items(mda, &fid->metadata_areas) {
if ((use_precommitted &&
@@ -1527,6 +1576,44 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
/* Ensure every PV in the VG was in the cache */
if (correct_vg) {
/*
* If the VG has PVs without mdas, they may still be
* orphans in the cache: update the cache state here.
*/
if (!inconsistent &&
list_size(&correct_vg->pvs) > list_size(pvids)) {
list_iterate_items(pvl, &correct_vg->pvs) {
if (!pvl->pv->dev) {
inconsistent_pvs = 1;
break;
}
if (str_list_match_item(pvids, pvl->pv->dev->pvid))
continue;
/*
* PV not marked as belonging to this VG in cache.
* Check it's an orphan without metadata area.
*/
if (!(info = info_from_pvid(pvl->pv->dev->pvid, 1)) ||
!info->vginfo || !is_orphan_vg(info->vginfo->vgname) ||
list_size(&info->mdas)) {
inconsistent_pvs = 1;
break;
}
}
/* If the check passed, let's update VG and recalculate pvids */
if (!inconsistent_pvs) {
log_debug("Updating cache for PVs without mdas "
"in VG %s.", vgname);
lvmcache_update_vg(correct_vg, use_precommitted);
if (!(pvids = lvmcache_get_pvids(cmd, vgname, vgid)))
return_NULL;
}
}
if (list_size(&correct_vg->pvs) != list_size(pvids)) {
log_debug("Cached VG %s had incorrect PV list",
vgname);
@@ -1551,15 +1638,11 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
if (!correct_vg) {
inconsistent = 0;
if (memlock()) {
stack;
return NULL;
}
if (memlock())
return_NULL;
lvmcache_label_scan(cmd, 2);
if (!(fmt = fmt_from_vgname(vgname, vgid))) {
stack;
return NULL;
}
if (!(fmt = fmt_from_vgname(vgname, vgid)))
return_NULL;
if (precommitted && !(fmt->features & FMT_PRECOMMIT))
use_precommitted = 0;
@@ -1605,13 +1688,11 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
}
/* Give up looking */
if (!correct_vg) {
stack;
return NULL;
}
if (!correct_vg)
return_NULL;
}
lvmcache_update_vg(correct_vg);
lvmcache_update_vg(correct_vg, use_precommitted);
if (inconsistent) {
/* FIXME Test should be if we're *using* precommitted metadata not if we were searching for it */
@@ -1709,13 +1790,13 @@ struct volume_group *vg_read(struct cmd_context *cmd, const char *vgname,
return vg;
}
/* This is only called by lv_from_lvid, which is only called from
* activate.c so we know the appropriate VG lock is already held and
/* This is only called by lv_from_lvid, which is only called from
* activate.c so we know the appropriate VG lock is already held and
* the vg_read is therefore safe.
*/
static struct volume_group *_vg_read_by_vgid(struct cmd_context *cmd,
const char *vgid,
int precommitted)
unsigned precommitted)
{
const char *vgname;
struct list *vgnames;
@@ -1727,12 +1808,12 @@ static struct volume_group *_vg_read_by_vgid(struct cmd_context *cmd,
/* Is corresponding vgname already cached? */
if ((vginfo = vginfo_from_vgid(vgid)) &&
vginfo->vgname && !is_orphan_vg(vginfo->vgname)) {
if ((vg = _vg_read(cmd, vginfo->vgname, vgid,
if ((vg = _vg_read(cmd, NULL, vgid,
&consistent, precommitted)) &&
!strncmp((char *)vg->id.uuid, vgid, ID_LEN)) {
if (!consistent) {
log_error("Volume group %s metadata is "
"inconsistent", vginfo->vgname);
"inconsistent", vg->name);
if (!partial_mode())
return NULL;
}
@@ -1748,7 +1829,7 @@ static struct volume_group *_vg_read_by_vgid(struct cmd_context *cmd,
/* FIXME Disabled vgrenames while active for now because we aren't
* allowed to do a full scan here any more. */
// The slow way - full scan required to cope with vgrename
// The slow way - full scan required to cope with vgrename
if (!(vgnames = get_vgs(cmd, 2))) {
log_error("vg_read_by_vgid: get_vgs failed");
return NULL;
@@ -1757,7 +1838,7 @@ static struct volume_group *_vg_read_by_vgid(struct cmd_context *cmd,
list_iterate_items(strl, vgnames) {
vgname = strl->str;
if (!vgname || is_orphan_vg(vgname))
continue; // FIXME Unnecessary?
continue; // FIXME Unnecessary?
consistent = 0;
if ((vg = _vg_read(cmd, vgname, vgid, &consistent,
precommitted)) &&
@@ -1776,7 +1857,7 @@ static struct volume_group *_vg_read_by_vgid(struct cmd_context *cmd,
/* Only called by activate.c */
struct logical_volume *lv_from_lvid(struct cmd_context *cmd, const char *lvid_s,
int precommitted)
unsigned precommitted)
{
struct lv_list *lvl;
struct volume_group *vg;
@@ -1826,9 +1907,9 @@ struct physical_volume *pv_read(struct cmd_context *cmd, const char *pv_name,
}
/* FIXME Use label functions instead of PV functions */
static struct physical_volume *_pv_read(struct cmd_context *cmd,
static struct physical_volume *_pv_read(struct cmd_context *cmd,
const char *pv_name,
struct list *mdas,
struct list *mdas,
uint64_t *label_sector,
int warnings)
{
@@ -1837,10 +1918,8 @@ static struct physical_volume *_pv_read(struct cmd_context *cmd,
struct lvmcache_info *info;
struct device *dev;
if (!(dev = dev_cache_get(pv_name, cmd->filter))) {
stack;
return NULL;
}
if (!(dev = dev_cache_get(pv_name, cmd->filter)))
return_NULL;
if (!(label_read(dev, &label, UINT64_C(0)))) {
if (warnings)
@@ -1871,10 +1950,8 @@ static struct physical_volume *_pv_read(struct cmd_context *cmd,
if (!pv->size)
return NULL;
if (!alloc_pv_segment_whole_pv(cmd->mem, pv)) {
stack;
return NULL;
}
if (!alloc_pv_segment_whole_pv(cmd->mem, pv))
return_NULL;
return pv;
}
@@ -1893,7 +1970,7 @@ struct list *get_vgids(struct cmd_context *cmd, int full_scan)
static int _get_pvs(struct cmd_context *cmd, struct list **pvslist)
{
struct str_list *strl;
struct list *results;
struct list * uninitialized_var(results);
const char *vgname, *vgid;
struct list *pvh, *tmp;
struct list *vgids;
@@ -1981,7 +2058,7 @@ int pv_write(struct cmd_context *cmd __attribute((unused)),
return _pv_write(cmd, pv, mdas, label_sector);
}
static int _pv_write(struct cmd_context *cmd __attribute((unused)),
static int _pv_write(struct cmd_context *cmd __attribute((unused)),
struct physical_volume *pv,
struct list *mdas, int64_t label_sector)
{
@@ -1996,10 +2073,8 @@ static int _pv_write(struct cmd_context *cmd __attribute((unused)),
return 0;
}
if (!pv->fmt->ops->pv_write(pv->fmt, pv, mdas, label_sector)) {
stack;
return 0;
}
if (!pv->fmt->ops->pv_write(pv->fmt, pv, mdas, label_sector))
return_0;
return 1;
}
@@ -2008,7 +2083,7 @@ int pv_write_orphan(struct cmd_context *cmd, struct physical_volume *pv)
{
const char *old_vg_name = pv->vg_name;
pv->vg_name = ORPHAN;
pv->vg_name = cmd->fmt->orphan_vg_name;
pv->status = ALLOCATABLE_PV;
if (!dev_get_size(pv->dev, &pv->size)) {
@@ -2032,14 +2107,14 @@ int pv_write_orphan(struct cmd_context *cmd, struct physical_volume *pv)
*/
int is_orphan_vg(const char *vg_name)
{
return (!strcmp(vg_name, ORPHAN) ? 1 : 0);
return (vg_name && vg_name[0] == ORPHAN_PREFIX[0]) ? 1 : 0;
}
/**
* is_orphan - Determine whether a pv is an orphan based on its vg_name
* @pv: handle to the physical volume
*/
int is_orphan(pv_t *pv)
int is_orphan(const pv_t *pv)
{
return is_orphan_vg(pv_field(pv, vg_name));
}
@@ -2109,7 +2184,7 @@ int pv_analyze(struct cmd_context *cmd, const char *pv_name,
int vg_check_status(const struct volume_group *vg, uint32_t status)
{
if ((status & CLUSTERED) &&
(vg->status & CLUSTERED) && !locking_is_clustered() &&
(vg_is_clustered(vg)) && !locking_is_clustered() &&
!lockingfailed()) {
log_error("Skipping clustered volume group %s", vg->name);
return 0;
@@ -2247,7 +2322,6 @@ uint32_t vg_status(const vg_t *vg)
return vg->status;
}
/**
* pv_by_path - Given a device path return a PV handle if it is a PV
* @cmd - handle to the LVM command instance

View File

@@ -257,6 +257,9 @@ int get_pv_from_vg_by_id(const struct format_type *fmt, const char *vg_name,
struct lv_list *find_lv_in_vg_by_lvid(struct volume_group *vg,
const union lvid *lvid);
struct lv_list *find_lv_in_lv_list(const struct list *ll,
const struct logical_volume *lv);
/* Return the VG that contains a given LV (based on path given in lv_name) */
/* or environment var */
struct volume_group *find_vg_with_lv(const char *lv_name);
@@ -264,11 +267,14 @@ struct volume_group *find_vg_with_lv(const char *lv_name);
/* Find LV with given lvid (used during activation) */
struct logical_volume *lv_from_lvid(struct cmd_context *cmd,
const char *lvid_s,
int precommitted);
unsigned precommitted);
/* FIXME Merge these functions with ones above */
struct physical_volume *find_pv(struct volume_group *vg, struct device *dev);
struct pv_list *find_pv_in_pv_list(const struct list *pl,
const struct physical_volume *pv);
/* Find LV segment containing given LE */
struct lv_segment *find_seg_by_le(const struct logical_volume *lv, uint32_t le);
@@ -306,6 +312,13 @@ int add_seg_to_segs_using_this_lv(struct logical_volume *lv, struct lv_segment *
int remove_seg_from_segs_using_this_lv(struct logical_volume *lv, struct lv_segment *seg);
struct lv_segment *get_only_segment_using_this_lv(struct logical_volume *lv);
/*
* For internal metadata caching.
*/
int export_vg_to_buffer(struct volume_group *vg, char **buf);
struct volume_group *import_vg_from_buffer(char *buf,
struct format_instance *fid);
/*
* Mirroring functions
*/

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
* Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -33,8 +33,8 @@
#define MIRROR_DISK_VERSION 2
/* These are the flags that represent the mirror failure restoration policies */
#define MIRROR_REMOVE 0
#define MIRROR_ALLOCATE 1
#define MIRROR_REMOVE 0
#define MIRROR_ALLOCATE 1
#define MIRROR_ALLOCATE_ANYWHERE 2
/*
@@ -135,6 +135,53 @@ uint32_t adjusted_mirror_region_size(uint32_t extent_size, uint32_t extents,
return region_size;
}
/*
* shift_mirror_images
* @mirrored_seg
* @mimage: The position (index) of the image to move to the end
*
* When dealing with removal of legs, we often move a 'removable leg'
* to the back of the 'areas' array. It is critically important not
* to simply swap it for the last area in the array. This would have
* the affect of reordering the remaining legs - altering position of
* the primary. So, we must shuffle all of the areas in the array
* to maintain their relative position before moving the 'removable
* leg' to the end.
*
* Short illustration of the problem:
* - Mirror consists of legs A, B, C and we want to remove A
* - We swap A and C and then remove A, leaving C, B
* This scenario is problematic in failure cases where A dies, because
* B becomes the primary. If the above happens, we effectively throw
* away any changes made between the time of failure and the time of
* restructuring the mirror.
*
* So, any time we want to move areas to the end to be removed, use
* this function.
*/
int shift_mirror_images(struct lv_segment *mirrored_seg, unsigned mimage)
{
int i;
struct lv_segment_area area;
if (mimage >= mirrored_seg->area_count) {
log_error("Invalid index (%u) of mirror image supplied "
"to shift_mirror_images()", mimage);
return 0;
}
area = mirrored_seg->areas[mimage];
/* Shift remaining images down to fill the hole */
for (i = mimage + 1; i < mirrored_seg->area_count; i++)
mirrored_seg->areas[i-1] = mirrored_seg->areas[i];
/* Place this one at the end */
mirrored_seg->areas[i-1] = area;
return 0;
}
/*
* This function writes a new header to the mirror log header to the lv
*
@@ -469,13 +516,12 @@ static int _remove_mirror_images(struct logical_volume *lv,
for (s = 0; s < mirrored_seg->area_count &&
old_area_count - new_area_count < num_removed; s++) {
sub_lv = seg_lv(mirrored_seg, s);
if (!is_temporary_mirror_layer(sub_lv) &&
_is_mirror_image_removable(sub_lv, removable_pvs)) {
/* Swap segment to end */
if (!shift_mirror_images(mirrored_seg, s))
return_0;
new_area_count--;
area = mirrored_seg->areas[new_area_count];
mirrored_seg->areas[new_area_count] = mirrored_seg->areas[s];
mirrored_seg->areas[s] = area;
}
}
if (num_removed && old_area_count == new_area_count)
@@ -504,6 +550,8 @@ static int _remove_mirror_images(struct logical_volume *lv,
* to remove the layer. */
if (new_area_count == 1 && !is_temporary_mirror_layer(lv)) {
lv1 = seg_lv(mirrored_seg, 0);
lv1->status &= ~MIRROR_IMAGE;
lv1->status |= VISIBLE_LV;
detached_log_lv = detach_mirror_log(mirrored_seg);
if (!remove_layer_from_lv(lv, lv1))
return_0;
@@ -550,6 +598,17 @@ static int _remove_mirror_images(struct logical_volume *lv,
log_very_verbose("Updating \"%s\" in kernel", mirrored_seg->lv->name);
/*
* Avoid having same mirror target loaded twice simultaneouly by first
* activating the removed LV which now contains an error segment.
* As it's now detached from mirrored_seg->lv we must activate it
* explicitly.
*/
if (lv1 && !activate_lv(lv1->vg->cmd, lv1)) {
log_error("Problem reactivating removed %s", lv1->name);
return 0;
}
if (!resume_lv(mirrored_seg->lv->vg->cmd, mirrored_seg->lv)) {
log_error("Problem reactivating %s", mirrored_seg->lv->name);
return 0;
@@ -1002,10 +1061,8 @@ struct logical_volume *find_pvmove_lv_from_pvname(struct cmd_context *cmd,
{
struct physical_volume *pv;
if (!(pv = find_pv_by_name(cmd, name))) {
stack;
return NULL;
}
if (!(pv = find_pv_by_name(cmd, name)))
return_NULL;
return find_pvmove_lv(vg, pv->dev, lv_type);
}
@@ -1140,6 +1197,8 @@ int remove_mirror_log(struct cmd_context *cmd,
struct list *removable_pvs)
{
float sync_percent;
struct lvinfo info;
struct volume_group *vg = lv->vg;
/* Unimplemented features */
if (list_size(&lv->segments) != 1) {
@@ -1148,10 +1207,21 @@ int remove_mirror_log(struct cmd_context *cmd,
}
/* Had disk log, switch to core. */
if (!lv_mirror_percent(cmd, lv, 0, &sync_percent, NULL)) {
log_error("Unable to determine mirror sync status.");
if (lv_info(cmd, lv, &info, 0, 0) && info.exists) {
if (!lv_mirror_percent(cmd, lv, 0, &sync_percent, NULL)) {
log_error("Unable to determine mirror sync status.");
return 0;
}
} else if (vg_is_clustered(vg)) {
log_error("Unable to convert the log of inactive "
"cluster mirror %s", lv->name);
return 0;
} else if (yes_no_prompt("Full resync required to convert "
"inactive mirror %s to core log. "
"Proceed? [y/n]: "))
sync_percent = 0;
else
return 0;
}
if (sync_percent >= 100.0)
init_mirror_in_sync(1);
@@ -1184,7 +1254,7 @@ static struct logical_volume *_create_mirror_log(struct logical_volume *lv,
return NULL;
}
if (dm_snprintf(log_name, len, "%s%s", lv->name, suffix) < 0) {
if (dm_snprintf(log_name, len, "%s%s", lv_name, suffix) < 0) {
log_error("log_name allocation failed.");
return NULL;
}
@@ -1209,7 +1279,9 @@ static struct logical_volume *_set_up_mirror_log(struct cmd_context *cmd,
int in_sync)
{
struct logical_volume *log_lv;
const char *suffix;
const char *suffix, *c;
char *lv_name;
size_t len;
struct lv_segment *seg;
init_mirror_in_sync(in_sync);
@@ -1219,15 +1291,34 @@ static struct logical_volume *_set_up_mirror_log(struct cmd_context *cmd,
return NULL;
}
/* Check if the log is for temporary sync layer. */
/* Mirror log name is lv_name + suffix, determined as the following:
* 1. suffix is:
* o "_mlog" for the original mirror LV.
* o "_mlogtmp_%d" for temporary mirror LV,
* 2. lv_name is:
* o lv->name, if the log is temporary
* o otherwise, the top-level LV name
*/
seg = first_seg(lv);
if (seg_type(seg, 0) == AREA_LV &&
strstr(seg_lv(seg, 0)->name, MIRROR_SYNC_LAYER))
strstr(seg_lv(seg, 0)->name, MIRROR_SYNC_LAYER)) {
lv_name = lv->name;
suffix = "_mlogtmp_%d";
else
} else if ((c = strstr(lv->name, MIRROR_SYNC_LAYER))) {
len = c - lv->name + 1;
if (!(lv_name = alloca(len)) ||
!dm_snprintf(lv_name, len, "%s", lv->name)) {
log_error("mirror log name allocation failed");
return 0;
}
suffix = "_mlog";
} else {
lv_name = lv->name;
suffix = "_mlog";
}
if (!(log_lv = _create_mirror_log(lv, ah, alloc, lv->name, suffix))) {
if (!(log_lv = _create_mirror_log(lv, ah, alloc,
(const char *) lv_name, suffix))) {
log_error("Failed to create mirror log.");
return NULL;
}
@@ -1248,12 +1339,9 @@ int attach_mirror_log(struct lv_segment *seg, struct logical_volume *log_lv)
return add_seg_to_segs_using_this_lv(log_lv, seg);
}
int add_mirror_log(struct cmd_context *cmd,
struct logical_volume *lv,
uint32_t log_count,
uint32_t region_size,
struct list *allocatable_pvs,
alloc_policy_t alloc)
int add_mirror_log(struct cmd_context *cmd, struct logical_volume *lv,
uint32_t log_count, uint32_t region_size,
struct list *allocatable_pvs, alloc_policy_t alloc)
{
struct alloc_handle *ah;
const struct segment_type *segtype;
@@ -1261,17 +1349,31 @@ int add_mirror_log(struct cmd_context *cmd,
float sync_percent;
int in_sync;
struct logical_volume *log_lv;
struct lvinfo info;
/* Unimplemented features */
if (log_count > 1) {
log_error("log_count > 1 is not supported");
return 0;
}
if (list_size(&lv->segments) != 1) {
log_error("Multiple-segment mirror is not supported");
return 0;
}
/*
* We are unable to convert the log of inactive cluster mirrors
* due to the inability to detect whether the mirror is active
* on remote nodes (even though it is inactive on this node)
*/
if (vg_is_clustered(lv->vg) &&
!(lv_info(cmd, lv, &info, 0, 0) && info.exists)) {
log_error("Unable to convert the log of inactive "
"cluster mirror %s", lv->name);
return 0;
}
if (!(parallel_areas = build_parallel_areas_from_lv(cmd, lv)))
return_0;
@@ -1279,7 +1381,7 @@ int add_mirror_log(struct cmd_context *cmd,
return_0;
if (activation() && segtype->ops->target_present &&
!segtype->ops->target_present(NULL)) {
!segtype->ops->target_present(NULL, NULL)) {
log_error("%s: Required device-mapper target(s) not "
"detected in your kernel", segtype->name);
return 0;
@@ -1323,7 +1425,8 @@ int add_mirror_images(struct cmd_context *cmd, struct logical_volume *lv,
struct alloc_handle *ah;
const struct segment_type *segtype;
struct list *parallel_areas;
struct logical_volume **img_lvs, *log_lv;
struct logical_volume **img_lvs;
struct logical_volume *log_lv = NULL;
if (stripes > 1) {
log_error("stripes > 1 is not supported");
@@ -1395,8 +1498,8 @@ int add_mirror_images(struct cmd_context *cmd, struct logical_volume *lv,
return 1;
out_remove_log:
if (!lv_remove(log_lv) || !vg_write(log_lv->vg) ||
(backup(log_lv->vg), !vg_commit(log_lv->vg)))
if (log_lv && (!lv_remove(log_lv) || !vg_write(log_lv->vg) ||
(backup(log_lv->vg), !vg_commit(log_lv->vg))))
log_error("Manual intervention may be required to remove "
"abandoned log LV before retrying.");

View File

@@ -53,10 +53,8 @@ int alloc_pv_segment_whole_pv(struct dm_pool *mem, struct physical_volume *pv)
return 1;
/* FIXME Cope with holes in PVs */
if (!(peg = _alloc_pv_segment(mem, pv, 0, pv->pe_count, NULL, 0))) {
stack;
return 0;
}
if (!(peg = _alloc_pv_segment(mem, pv, 0, pv->pe_count, NULL, 0)))
return_0;
list_add(&pv->segments, &peg->list);
@@ -72,10 +70,8 @@ int peg_dup(struct dm_pool *mem, struct list *peg_new, struct list *peg_old)
list_iterate_items(pego, peg_old) {
if (!(peg = _alloc_pv_segment(mem, pego->pv, pego->pe,
pego->len, pego->lvseg,
pego->lv_area))) {
stack;
return 0;
}
pego->lv_area)))
return_0;
list_add(peg_new, &peg->list);
}
@@ -93,10 +89,8 @@ static int _pv_split_segment(struct physical_volume *pv, struct pv_segment *peg,
if (!(peg_new = _alloc_pv_segment(pv->fmt->cmd->mem, peg->pv, pe,
peg->len + peg->pe - pe,
NULL, 0))) {
stack;
return 0;
}
NULL, 0)))
return_0;
peg->len = peg->len - peg_new->len;
@@ -130,10 +124,8 @@ int pv_split_segment(struct physical_volume *pv, uint32_t pe)
if (pe == peg->pe)
return 1;
if (!_pv_split_segment(pv, peg, pe)) {
stack;
return 0;
}
if (!_pv_split_segment(pv, peg, pe))
return_0;
return 1;
}
@@ -154,11 +146,9 @@ struct pv_segment *assign_peg_to_lvseg(struct physical_volume *pv,
if (!pv)
return &null_pv_segment;
if (!pv_split_segment(pv, pe) ||
!pv_split_segment(pv, pe + area_len)) {
stack;
return NULL;
}
if (!pv_split_segment(pv, pe) ||
!pv_split_segment(pv, pe + area_len))
return_NULL;
if (!(peg = find_peg_by_pe(pv, pe))) {
log_error("Missing PV segment on %s at %u.",
@@ -196,10 +186,8 @@ int release_pv_segment(struct pv_segment *peg, uint32_t area_reduction)
}
if (!pv_split_segment(peg->pv, peg->pe + peg->lvseg->area_len -
area_reduction)) {
stack;
return 0;
}
area_reduction))
return_0;
return 1;
}
@@ -245,7 +233,7 @@ uint32_t pv_list_extents_free(const struct list *pvh)
list_iterate_items(pvl, pvh) {
list_iterate_items(per, pvl->pe_ranges) {
list_iterate_items(pvseg, &pvl->pv->segments) {
if (!pvseg->lvseg) /* free space */
if (!pvseg_is_allocated(pvseg))
extents += _overlap_pe(pvseg, per);
}
}
@@ -371,10 +359,8 @@ static int _reduce_pv(struct physical_volume *pv, struct volume_group *vg, uint3
}
}
if (!pv_split_segment(pv, new_pe_count)) {
stack;
return 0;
}
if (!pv_split_segment(pv, new_pe_count))
return_0;
list_iterate_items_safe(peg, pegt, &pv->segments) {
if (peg->pe + peg->len > new_pe_count)

View File

@@ -40,10 +40,8 @@ static int _create_single_area(struct dm_pool *mem, struct pv_map *pvm,
{
struct pv_area *pva;
if (!(pva = dm_pool_zalloc(mem, sizeof(*pva)))) {
stack;
return 0;
}
if (!(pva = dm_pool_zalloc(mem, sizeof(*pva))))
return_0;
log_debug("Allowing allocation on %s start PE %" PRIu32 " length %"
PRIu32, pv_dev_name(pvm->pv), start, length);
@@ -58,7 +56,7 @@ static int _create_single_area(struct dm_pool *mem, struct pv_map *pvm,
static int _create_alloc_areas_for_pv(struct dm_pool *mem, struct pv_map *pvm,
uint32_t start, uint32_t count)
{
struct pv_segment *peg;
struct pv_segment *peg;
uint32_t pe, end, area_len;
/* Only select extents from start to end inclusive */
@@ -69,7 +67,7 @@ static int _create_alloc_areas_for_pv(struct dm_pool *mem, struct pv_map *pvm,
pe = start;
/* Walk through complete ordered list of device segments */
list_iterate_items(peg, &pvm->pv->segments) {
list_iterate_items(peg, &pvm->pv->segments) {
/* pe holds the next extent we want to check */
/* Beyond the range we're interested in? */
@@ -88,14 +86,12 @@ static int _create_alloc_areas_for_pv(struct dm_pool *mem, struct pv_map *pvm,
area_len = (end >= peg->pe + peg->len - 1) ?
peg->len - (pe - peg->pe) : end - pe + 1;
if (!_create_single_area(mem, pvm, pe, area_len)) {
stack;
return 0;
}
if (!_create_single_area(mem, pvm, pe, area_len))
return_0;
next:
pe = peg->pe + peg->len;
}
}
return 1;
}
@@ -108,20 +104,16 @@ static int _create_all_areas_for_pv(struct dm_pool *mem, struct pv_map *pvm,
if (!pe_ranges) {
/* Use whole PV */
if (!_create_alloc_areas_for_pv(mem, pvm, UINT32_C(0),
pvm->pv->pe_count)) {
stack;
return 0;
}
pvm->pv->pe_count))
return_0;
return 1;
}
list_iterate_items(aa, pe_ranges) {
if (!_create_alloc_areas_for_pv(mem, pvm, aa->start,
aa->count)) {
stack;
return 0;
}
aa->count))
return_0;
}
return 1;
@@ -145,20 +137,16 @@ static int _create_maps(struct dm_pool *mem, struct list *pvs, struct list *pvms
}
if (!pvm) {
if (!(pvm = dm_pool_zalloc(mem, sizeof(*pvm)))) {
stack;
return 0;
}
if (!(pvm = dm_pool_zalloc(mem, sizeof(*pvm))))
return_0;
pvm->pv = pvl->pv;
list_init(&pvm->areas);
list_add(pvms, &pvm->list);
}
if (!_create_all_areas_for_pv(mem, pvm, pvl->pe_ranges)) {
stack;
return 0;
}
if (!_create_all_areas_for_pv(mem, pvm, pvl->pe_ranges))
return_0;
}
return 1;

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 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.

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