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

Compare commits

..

123 Commits

Author SHA1 Message Date
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
94 changed files with 3112 additions and 1852 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,8 +36,8 @@ 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
endif

View File

@@ -1 +1 @@
2.02.34-cvs (2008-04-10)
2.02.39-cvs (2008-06-11)

View File

@@ -1,5 +1,89 @@
Version 2.02.39 -
================================
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.
Fix 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 to not activate mirror leg and log 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.

View File

@@ -1,5 +1,22 @@
Version 1.02.26 -
=================================
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
=================================

2609
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,41 +28,45 @@ 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
@@ -75,14 +75,15 @@ 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 +92,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 +112,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 +124,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 +149,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)
@@ -260,31 +267,14 @@ if test x$MIRRORS = xinternal; then
AC_DEFINE([MIRRORED_INTERNAL], 1, [Define to 1 to include built-in support for mirrors.])
fi
################################################################################
dnl -- Enables staticly-linked tools
AC_MSG_CHECKING(whether to use static linking)
AC_ARG_ENABLE(static_link, [ --enable-static_link Use this to link the tools to their libraries
statically. Default is dynamic linking], STATIC_LINK=$enableval, STATIC_LINK=no)
AC_MSG_RESULT($STATIC_LINK)
################################################################################
dnl -- Enable readline
AC_MSG_CHECKING(whether to enable readline)
AC_ARG_ENABLE(readline, [ --enable-readline Enable readline support],
READLINE=$enableval, READLINE=no)
AC_ARG_ENABLE([readline],
[ --enable-readline Enable readline support],
[READLINE=$enableval], [READLINE=no])
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 +304,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,7 +318,7 @@ 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)
@@ -360,6 +350,10 @@ 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 $CMDLIB=yes \
&& LVM2CMD_LIB=-llvm2cmd \
|| LVM2CMD_LIB=
################################################################################
dnl -- Enable fsadm
@@ -386,18 +380,11 @@ 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
@@ -436,12 +423,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 +459,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,7 +487,7 @@ 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)
@@ -497,7 +502,11 @@ 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.]))
AC_CHECK_FUNC([rl_completion_matches],
AC_DEFINE([HAVE_RL_COMPLETION_MATCHES], 1,
[Define to 1 if rl_completion_matches() is available.]))
AC_DEFINE([READLINE_SUPPORT], 1,
[Define to 1 to include the LVM readline shell.])
fi
################################################################################
@@ -517,25 +526,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 +594,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 +652,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, sizeof(int) * 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);
}
}
@@ -332,16 +331,6 @@ static void get_members()
if (nodes[i].cn_nodeid > high_nodeid)
high_nodeid = nodes[i].cn_nodeid;
}
if (node_updown == NULL) {
size_t buf_len;
if (high_nodeid >= max_updown_nodes)
max_updown_nodes = high_nodeid + 1;
buf_len = sizeof(int) * max_updown_nodes;
node_updown = malloc(buf_len);
if (node_updown)
memset(node_updown, 0, buf_len);
}
}

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

@@ -182,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);
@@ -191,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;
@@ -530,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;
@@ -541,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);
}
@@ -985,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)) {
@@ -1056,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;
@@ -1167,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) {
@@ -1439,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;

View File

@@ -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,8 +400,8 @@ 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)) {
@@ -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);
@@ -472,7 +560,8 @@ static void drop_vg_locks()
popen
("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...

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

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

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

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

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

@@ -25,9 +25,8 @@ devices {
# list of regular expressions in turn and the first match is used.
preferred_names = [ ]
# If device-mapper multipath is used, more descriptive names might
# be preferred over the dm-N names:
# preferred_names = [ "^/dev/mapper/mpath" ]
# 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

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

View File

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

@@ -928,8 +928,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) {
@@ -995,6 +995,9 @@ static int _remove_lv_symlinks(struct dev_manager *dm, struct dm_tree_node *root
continue;
}
if (!*vgname)
continue;
/* only top level layer has symlinks */
if (*layer)
continue;

236
lib/cache/lvmcache.c vendored
View File

@@ -22,12 +22,16 @@
#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? */
@@ -63,7 +67,6 @@ static void _free_cached_vgmetadata(struct lvmcache_vginfo *vginfo)
dm_free(vginfo->vgmetadata);
vginfo->vgmetadata = NULL;
vginfo->fid = NULL;
log_debug("Metadata cache: VG %s wiped.", vginfo->vgname);
}
@@ -81,7 +84,6 @@ static void _store_metadata(struct lvmcache_vginfo *vginfo,
return;
}
vginfo->fid = vg->fid;
vginfo->precommitted = precommitted;
log_debug("Metadata cache: VG %s stored (%d bytes%s).", vginfo->vgname,
@@ -132,6 +134,42 @@ static void _update_cache_lock_state(const char *vgname, int locked)
_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
_drop_metadata(vgname);
}
void lvmcache_lock_vgname(const char *vgname, int read_only __attribute((unused)))
{
if (!_lock_hash && !lvmcache_init()) {
@@ -148,7 +186,8 @@ void lvmcache_lock_vgname(const char *vgname, int read_only __attribute((unused)
_update_cache_lock_state(vgname, 1);
_vgs_locked++;
if (strcmp(vgname, VG_GLOBAL))
_vgs_locked++;
}
int vgname_is_locked(const char *vgname)
@@ -170,7 +209,7 @@ void lvmcache_unlock_vgname(const char *vgname)
dm_hash_remove(_lock_hash, vgname);
/* FIXME Do this per-VG */
if (!--_vgs_locked)
if (strcmp(vgname, VG_GLOBAL) && !--_vgs_locked)
dev_close_all();
}
@@ -179,11 +218,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;
@@ -298,6 +360,7 @@ 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;
@@ -305,6 +368,18 @@ static int _vginfo_is_valid(struct lvmcache_vginfo *vginfo)
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.
@@ -351,7 +426,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! */
@@ -400,6 +474,7 @@ 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;
@@ -407,17 +482,35 @@ struct volume_group *lvmcache_get_vg(const char *vgid, unsigned precommitted)
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))
(!precommitted && vginfo->precommitted && !memlock()))
return NULL;
if (!(vg = import_vg_from_buffer(vginfo->vgmetadata, vginfo->fid)) ||
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 metadata for VG %s.", vginfo->vgname);
log_debug("Using cached %smetadata for VG %s.",
vginfo->precommitted ? "pre-committed" : "", vginfo->vgname);
return vg;
}
@@ -536,38 +629,62 @@ struct device *device_from_pvid(struct cmd_context *cmd, struct id *pvid)
return NULL;
}
static int _free_vginfo(struct lvmcache_vginfo *vginfo)
{
struct lvmcache_vginfo *primary_vginfo, *vginfo2;
int r = 1;
_free_cached_vgmetadata(vginfo);
vginfo2 = primary_vginfo = vginfo_from_vgname(vginfo->vgname, 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 && !list_empty(&info->list)) {
list_del(&info->list);
list_init(&info->list);
}
if (vginfo && !is_orphan_vg(vginfo->vgname) && list_empty(&vginfo->infos)) {
dm_hash_remove(_vgname_hash, vginfo->vgname);
if (vginfo->next) {
if (!dm_hash_insert(_vgname_hash, vginfo->vgname, vginfo->next)) {
log_error("vg hash re-insertion failed: %s",
vginfo->vgname);
return 0;
}
}
if (vginfo->vgname)
dm_free(vginfo->vgname);
if (vginfo->creation_host)
dm_free(vginfo->creation_host);
if (*vginfo->vgid)
dm_hash_remove(_vgid_hash, vginfo->vgid);
list_del(&vginfo->list);
dm_free(info->vginfo);
}
if (info)
info->vginfo = NULL;
_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;
}
@@ -726,7 +843,8 @@ static int _lvmcache_update_vgname(struct lvmcache_info *info,
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;
// struct lvmcache_vginfo *old_vginfo, *next;
if (!vgname || (info && info->vginfo && !strcmp(info->vginfo->vgname, vgname)))
@@ -785,7 +903,24 @@ 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);
log_debug("lvmcache: %s: now in VG %s%s%s%s",
dev_name(info2->dev),
vgname, orphan_vginfo->vgid[0] ? " (" : "",
orphan_vginfo->vgid[0] ? orphan_vginfo->vgid : "",
orphan_vginfo->vgid[0] ? ")" : "");
}
if (!_insert_vginfo(vginfo, vgid, vgstatus, creation_host,
primary_vginfo)) {
dm_free(vginfo->vgname);
@@ -802,10 +937,9 @@ static int _lvmcache_update_vgname(struct lvmcache_info *info,
***/
}
if (info) {
info->vginfo = vginfo;
list_add(&vginfo->infos, &info->list);
} else if (!_lvmcache_update_vgid(info, vginfo, vgid)) /* Orphans */
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));
@@ -881,6 +1015,15 @@ int lvmcache_update_vgname_and_id(struct lvmcache_info *info,
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, info->fmt) ||
!_lvmcache_update_vgid(info, info->vginfo, vgid) ||
@@ -1027,8 +1170,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);
@@ -1040,12 +1182,8 @@ 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);
_free_cached_vgmetadata(vginfo);
dm_free(vginfo);
if (!_free_vginfo(vginfo))
stack;
} while ((vginfo = next));
}
@@ -1097,6 +1235,8 @@ void lvmcache_destroy(struct cmd_context *cmd, int retain_orphans)
_lock_hash = NULL;
}
if (!list_empty(&_vginfos))
log_error("Internal error: _vginfos list should be empty");
list_init(&_vginfos);
if (retain_orphans)

View File

@@ -45,7 +45,6 @@ struct lvmcache_vginfo {
struct lvmcache_vginfo *next; /* Another VG with same name? */
char *creation_host;
char *vgmetadata; /* Copy of VG metadata as format_text string */
struct format_instance *fid; /* fid associated with vgmetadata */
unsigned precommitted; /* Is vgmetadata live or precommitted? */
};
@@ -82,7 +81,6 @@ 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, unsigned precommitted);
void lvmcache_drop_vg(const char *vgname);
void lvmcache_lock_vgname(const char *vgname, int read_only);
void lvmcache_unlock_vgname(const char *vgname);
@@ -112,5 +110,6 @@ struct list *lvmcache_get_pvids(struct cmd_context *cmd, const char *vgname,
/* 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

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

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

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

@@ -55,14 +55,9 @@ void list_add_h(struct list *head, struct list *elem);
void list_del(struct list *elem);
/*
* Move an element from an existing list to list 'head'.
* Insert the element before 'head'.
* Remove an element from existing list and insert before 'head'.
*/
static inline void list_move(struct list *item, struct list *head)
{
list_del(item);
list_add(head, item);
}
void list_move(struct list *head, struct list *elem);
/*
* Is the list empty?

View File

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

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

@@ -670,7 +670,7 @@ void vgdisplay_colons(const struct volume_group *vg)
active_pvs = vg->pv_count;
list_iterate_items(lvl, &vg->lvs)
if (lv_is_visible(lvl->lv) || (lvl->lv->status & SNAPSHOT))
if (lv_is_visible(lvl->lv) && !(lvl->lv->status & SNAPSHOT))
lv_count++;
switch (vg->status & (LVM_READ | LVM_WRITE)) {

View File

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

View File

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

View File

@@ -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,8 +437,10 @@ 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);
}

View File

@@ -21,6 +21,7 @@
#include "defaults.h"
#include "lvm-file.h"
#include "lvm-string.h"
#include "lvmcache.h"
#include <limits.h>
#include <unistd.h>
@@ -209,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

View File

@@ -323,8 +323,19 @@ static int _lock_vol(struct cmd_context *cmd, const char *resource, uint32_t fla
assert(resource);
if (!*resource) {
log_error("Internal error: Use of P_orphans is deprecated.");
return 0;
}
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) {
if ((flags & LCK_SCOPE_MASK) == LCK_VG &&
!(flags & LCK_CACHE)) {
if ((flags & LCK_TYPE_MASK) == LCK_UNLOCK)
lvmcache_unlock_vgname(resource);
else
@@ -369,8 +380,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;

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)
@@ -116,6 +127,8 @@ 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);

View File

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

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

@@ -439,7 +439,8 @@ static int _lv_reduce(struct logical_volume *lv, uint32_t extents, int delete)
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))
return_0;

View File

@@ -202,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;
@@ -331,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,

View File

@@ -716,7 +716,7 @@ int vg_split_mdas(struct cmd_context *cmd __attribute((unused)),
if (is_orphan_vg(vg_to->name))
list_del(&mda->list);
else
list_move(&mda->list, mdas_to);
list_move(mdas_to, &mda->list);
}
}
@@ -747,7 +747,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,
@@ -756,7 +756,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,
@@ -885,6 +885,7 @@ struct pv_list *find_pv_in_pv_list(const struct list *pl,
list_iterate_items(pvl, pl)
if (pvl->pv == pv)
return pvl;
return NULL;
}
@@ -957,6 +958,7 @@ struct lv_list *find_lv_in_lv_list(const struct list *ll,
list_iterate_items(lvl, ll)
if (lvl->lv == lv)
return lvl;
return NULL;
}
@@ -1175,6 +1177,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 */
@@ -1208,6 +1211,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)
@@ -1266,6 +1278,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 */
@@ -1346,6 +1363,11 @@ int vg_commit(struct volume_group *vg)
}
}
/* 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;
}
@@ -1362,6 +1384,10 @@ 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;
}
@@ -1450,6 +1476,8 @@ static int _update_pv_list(struct list *all_pvs, struct volume_group *vg)
* 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,
@@ -1496,19 +1524,23 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
}
}
/* 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)))
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 &&
@@ -1726,12 +1758,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;
}
@@ -1888,7 +1920,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;

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) 2004-2008 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -1344,7 +1344,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");
@@ -1416,8 +1417,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

@@ -373,7 +373,7 @@ static int _mirrored_target_present(const struct lv_segment *seg __attribute((un
/*
* Check only for modules if atttributes requested and no previous check.
* FIXME: need better check
* FIXME: Fails incorrectly if cmirror was built into kernel.
*/
if (attributes) {
if (!_mirror_attributes && module_present("cmirror"))

View File

@@ -36,8 +36,7 @@
/* Define to 1 if you have the <ctype.h> header file. */
#undef HAVE_CTYPE_H
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
*/
/* Define to 1 if you have the <dirent.h> header file. */
#undef HAVE_DIRENT_H
/* Define to 1 if you have the <dlfcn.h> header file. */
@@ -49,6 +48,9 @@
/* Define to 1 if you have the `dup2' function. */
#undef HAVE_DUP2
/* Define to 1 if you have the <errno.h> header file. */
#undef HAVE_ERRNO_H
/* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
@@ -61,7 +63,7 @@
/* Define to 1 if you have the `getmntent' function. */
#undef HAVE_GETMNTENT
/* Define to 1 to if getopt_long is available. */
/* Define to 1 if getopt_long is available. */
#undef HAVE_GETOPTLONG
/* Define to 1 if you have the <getopt.h> header file. */
@@ -171,6 +173,9 @@
/* Define to 1 if you have the <selinux/selinux.h> header file. */
#undef HAVE_SELINUX_SELINUX_H
/* Define to 1 if sepol_check_context is available. */
#undef HAVE_SEPOL
/* Define to 1 if you have the `setlocale' function. */
#undef HAVE_SETLOCALE
@@ -184,6 +189,9 @@
zero-length file name argument. */
#undef HAVE_STAT_EMPTY_STRING_BUG
/* Define to 1 if you have the <stdarg.h> header file. */
#undef HAVE_STDARG_H
/* Define to 1 if you have the <stddef.h> header file. */
#undef HAVE_STDDEF_H
@@ -270,6 +278,9 @@
/* Define to 1 if you have the <sys/socket.h> header file. */
#undef HAVE_SYS_SOCKET_H
/* Define to 1 if you have the <sys/statvfs.h> header file. */
#undef HAVE_SYS_STATVFS_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
@@ -291,6 +302,9 @@
/* Define to 1 if you have the <sys/wait.h> header file. */
#undef HAVE_SYS_WAIT_H
/* Define to 1 if you have the <termios.h> header file. */
#undef HAVE_TERMIOS_H
/* Define to 1 if you have the <time.h> header file. */
#undef HAVE_TIME_H

View File

@@ -25,4 +25,6 @@
(void) (&_a == &_b); \
_a > _b ? _a : _b; })
#define uninitialized_var(x) x = x
#endif

View File

@@ -105,7 +105,7 @@ static void _lock_mem(void)
log_sys_error("getpriority", "");
else
if (setpriority(PRIO_PROCESS, 0, _default_priority))
log_error("setpriority %u failed: %s",
log_error("setpriority %d failed: %s",
_default_priority, strerror(errno));
}

View File

@@ -386,7 +386,7 @@ static int _pvstatus_disp(struct dm_report *rh __attribute((unused)), struct dm_
const uint32_t status = *(const uint32_t *) data;
char *repstr;
if (!(repstr = dm_pool_zalloc(mem, 4))) {
if (!(repstr = dm_pool_zalloc(mem, 3))) {
log_error("dm_pool_alloc failed");
return 0;
}
@@ -1077,9 +1077,11 @@ static struct dm_report_field_type _fields[] = {
void *report_init(struct cmd_context *cmd, const char *format, const char *keys,
report_type_t *report_type, const char *separator,
int aligned, int buffered, int headings)
int aligned, int buffered, int headings, int field_prefixes,
int quoted, int columns_as_rows)
{
uint32_t report_flags = 0;
void *rh;
if (aligned)
report_flags |= DM_REPORT_OUTPUT_ALIGNED;
@@ -1090,8 +1092,22 @@ void *report_init(struct cmd_context *cmd, const char *format, const char *keys,
if (headings)
report_flags |= DM_REPORT_OUTPUT_HEADINGS;
return dm_report_init(report_type, _report_types, _fields, format,
separator, report_flags, keys, cmd);
if (field_prefixes)
report_flags |= DM_REPORT_OUTPUT_FIELD_NAME_PREFIX;
if (!quoted)
report_flags |= DM_REPORT_OUTPUT_FIELD_UNQUOTED;
if (columns_as_rows)
report_flags |= DM_REPORT_OUTPUT_COLUMNS_AS_ROWS;
rh = dm_report_init(report_type, _report_types, _fields, format,
separator, report_flags, keys, cmd);
if (field_prefixes)
dm_report_set_output_field_name_prefix(rh, "lvm2_");
return rh;
}
/*

View File

@@ -28,7 +28,8 @@ typedef int (*field_report_fn) (struct report_handle * dh, struct field * field,
void *report_init(struct cmd_context *cmd, const char *format, const char *keys,
report_type_t *report_type, const char *separator,
int aligned, int buffered, int headings);
int aligned, int buffered, int headings, int field_prefixes,
int quoted, int columns_as_rows);
void report_free(void *handle);
int report_object(void *handle, struct volume_group *vg,
struct logical_volume *lv, struct physical_volume *pv,

View File

@@ -132,5 +132,6 @@ dm_report_field_int32
dm_report_field_uint32
dm_report_field_uint64
dm_report_field_set_value
dm_report_set_output_field_name_prefix
dm_regex_create
dm_regex_match

View File

@@ -43,8 +43,8 @@ else
endif
VERSIONED_SHLIB = libdevmapper.$(LIB_SUFFIX).$(LIB_VERSION)
DEFS += -DDEVICE_UID=@DEVICE_UID@ -DDEVICE_GID=@DEVICE_GID@ \
-DDEVICE_MODE=@DEVICE_MODE@
DEFS += -DDM_DEVICE_UID=@DM_DEVICE_UID@ -DDM_DEVICE_GID=@DM_DEVICE_GID@ \
-DDM_DEVICE_MODE=@DM_DEVICE_MODE@
include ../make.tmpl

View File

@@ -215,12 +215,14 @@ unsigned dm_hash_get_num_entries(struct dm_hash_table *t)
void dm_hash_iter(struct dm_hash_table *t, dm_hash_iterate_fn f)
{
struct dm_hash_node *c;
struct dm_hash_node *c, *n;
unsigned i;
for (i = 0; i < t->num_slots; i++)
for (c = t->slots[i]; c; c = c->next)
for (c = t->slots[i]; c; c = n) {
n = c->next;
f(c->data);
}
}
void dm_hash_wipe(struct dm_hash_table *t)

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

@@ -55,14 +55,9 @@ void list_add_h(struct list *head, struct list *elem);
void list_del(struct list *elem);
/*
* Move an element from an existing list to list 'head'.
* Insert the element before 'head'.
* Remove an element from existing list and insert before 'head'.
*/
static inline void list_move(struct list *item, struct list *head)
{
list_del(item);
list_add(head, item);
}
void list_move(struct list *head, struct list *elem);
/*
* Is the list empty?

View File

@@ -1690,8 +1690,10 @@ repeat_ioctl:
switch (dmt->type) {
case DM_DEVICE_CREATE:
add_dev_node(dmt->dev_name, MAJOR(dmi->dev), MINOR(dmi->dev),
dmt->uid, dmt->gid, dmt->mode);
if (dmt->dev_name && *dmt->dev_name)
add_dev_node(dmt->dev_name, MAJOR(dmi->dev),
MINOR(dmi->dev), dmt->uid, dmt->gid,
dmt->mode);
break;
case DM_DEVICE_REMOVE:

View File

@@ -500,7 +500,7 @@ void dm_pool_free(struct dm_pool *p, void *ptr);
*
* for (i = 0; i < 50; i++) {
* snprintf(buffer, sizeof(buffer), "%d, ", i);
* if (!dm_pool_grow_object(mem, buffer, strlen(buffer)))
* if (!dm_pool_grow_object(mem, buffer, 0))
* goto bad;
* }
*
@@ -524,6 +524,7 @@ void dm_pool_free(struct dm_pool *p, void *ptr);
* dm_pool_grow_object. Finally get your object with
* a call to dm_pool_end_object.
*
* Setting delta to 0 means it will use strlen(extra).
*/
int dm_pool_begin_object(struct dm_pool *p, size_t hint);
int dm_pool_grow_object(struct dm_pool *p, const void *extra, size_t delta);
@@ -734,10 +735,13 @@ struct dm_report_field_type {
/*
* dm_report_init output_flags
*/
#define DM_REPORT_OUTPUT_MASK 0x000000FF
#define DM_REPORT_OUTPUT_ALIGNED 0x00000001
#define DM_REPORT_OUTPUT_BUFFERED 0x00000002
#define DM_REPORT_OUTPUT_HEADINGS 0x00000004
#define DM_REPORT_OUTPUT_MASK 0x000000FF
#define DM_REPORT_OUTPUT_ALIGNED 0x00000001
#define DM_REPORT_OUTPUT_BUFFERED 0x00000002
#define DM_REPORT_OUTPUT_HEADINGS 0x00000004
#define DM_REPORT_OUTPUT_FIELD_NAME_PREFIX 0x00000008
#define DM_REPORT_OUTPUT_FIELD_UNQUOTED 0x00000010
#define DM_REPORT_OUTPUT_COLUMNS_AS_ROWS 0x00000020
struct dm_report *dm_report_init(uint32_t *report_types,
const struct dm_report_object_type *types,
@@ -751,6 +755,12 @@ int dm_report_object(struct dm_report *rh, void *object);
int dm_report_output(struct dm_report *rh);
void dm_report_free(struct dm_report *rh);
/*
* Prefix added to each field name with DM_REPORT_OUTPUT_FIELD_NAME_PREFIX
*/
int dm_report_set_output_field_name_prefix(struct dm_report *rh,
const char *report_prefix);
/*
* Report functions are provided for simple data types.
* They take care of allocating copies of the data.

View File

@@ -120,9 +120,9 @@ struct dm_task *dm_task_create(int type)
dmt->type = type;
dmt->minor = -1;
dmt->major = -1;
dmt->uid = DEVICE_UID;
dmt->gid = DEVICE_GID;
dmt->mode = DEVICE_MODE;
dmt->uid = DM_DEVICE_UID;
dmt->gid = DM_DEVICE_GID;
dmt->mode = DM_DEVICE_MODE;
dmt->no_open_count = 0;
dmt->read_ahead = DM_READ_AHEAD_AUTO;
dmt->read_ahead_flags = 0;

View File

@@ -937,7 +937,7 @@ static int _suspend_node(const char *name, uint32_t major, uint32_t minor,
log_verbose("Suspending %s (%" PRIu32 ":%" PRIu32 ")%s%s",
name, major, minor,
skip_lockfs ? "" : " with filesystem sync",
no_flush ? "" : " without device flush");
no_flush ? "" : " with device flush");
if (!(dmt = dm_task_create(DM_DEVICE_SUSPEND))) {
log_error("Suspend dm_task creation failed for %s", name);
@@ -1276,7 +1276,6 @@ static int _emit_segment_line(struct dm_task *dmt, struct load_segment *seg, uin
switch(seg->type) {
case SEG_ERROR:
case SEG_ZERO:
params[0] = '\0';
case SEG_LINEAR:
break;
case SEG_MIRRORED:
@@ -1434,6 +1433,7 @@ static int _emit_segment(struct dm_task *dmt, struct load_segment *seg,
return 0;
}
params[0] = '\0';
ret = _emit_segment_line(dmt, seg, seg_start, params, paramsize);
dm_free(params);

View File

@@ -17,6 +17,8 @@
#include "list.h"
#include "log.h"
#include <ctype.h>
/*
* Internal flags
*/
@@ -27,6 +29,7 @@ struct dm_report {
struct dm_pool *mem;
uint32_t report_types;
const char *output_field_name_prefix;
const char *field_prefix;
uint32_t flags;
const char *separator;
@@ -510,6 +513,14 @@ struct dm_report *dm_report_init(uint32_t *report_types,
rh->flags |= output_flags & DM_REPORT_OUTPUT_MASK;
/* With columns_as_rows we must buffer and not align. */
if (output_flags & DM_REPORT_OUTPUT_COLUMNS_AS_ROWS) {
if (!(output_flags & DM_REPORT_OUTPUT_BUFFERED))
rh->flags |= DM_REPORT_OUTPUT_BUFFERED;
if (output_flags & DM_REPORT_OUTPUT_ALIGNED)
rh->flags &= ~DM_REPORT_OUTPUT_ALIGNED;
}
if (output_flags & DM_REPORT_OUTPUT_BUFFERED)
rh->flags |= RH_SORT_REQUIRED;
@@ -551,6 +562,31 @@ void dm_report_free(struct dm_report *rh)
dm_free(rh);
}
static char *_toupperstr(char *str)
{
char *u = str;
do
*u = toupper(*u);
while (*u++);
return str;
}
int dm_report_set_output_field_name_prefix(struct dm_report *rh, const char *output_field_name_prefix)
{
char *prefix;
if (!(prefix = dm_pool_strdup(rh->mem, output_field_name_prefix))) {
log_error("dm_report_set_output_field_name_prefix: dm_pool_strdup failed");
return 0;
}
rh->output_field_name_prefix = _toupperstr(prefix);
return 1;
}
/*
* Create a row of data for an object
*/
@@ -668,15 +704,13 @@ static int _report_headings(struct dm_report *rh)
log_error("dm_report: Failed to generate report headings for printing");
goto bad;
}
} else if (!dm_pool_grow_object(rh->mem, heading,
strlen(heading))) {
} else if (!dm_pool_grow_object(rh->mem, heading, 0)) {
log_error("dm_report: Failed to generate report headings for printing");
goto bad;
}
if (!list_end(&rh->field_props, &fp->list))
if (!dm_pool_grow_object(rh->mem, rh->separator,
strlen(rh->separator))) {
if (!dm_pool_grow_object(rh->mem, rh->separator, 0)) {
log_error("dm_report: Failed to generate report headings for printing");
goto bad;
}
@@ -767,22 +801,152 @@ static int _sort_rows(struct dm_report *rh)
/*
* Produce report output
*/
int dm_report_output(struct dm_report *rh)
static int _output_field(struct dm_report *rh, struct dm_report_field *field)
{
char *field_id;
int32_t width;
uint32_t align;
const char *repstr;
char buf[4096];
if (rh->flags & DM_REPORT_OUTPUT_FIELD_NAME_PREFIX) {
if (!(field_id = strdup(rh->fields[field->props->field_num].id))) {
log_error("dm_report: Failed to copy field name");
return 0;
}
if (!dm_pool_grow_object(rh->mem, rh->output_field_name_prefix, 0)) {
log_error("dm_report: Unable to extend output line");
return 0;
}
if (!dm_pool_grow_object(rh->mem, _toupperstr(field_id), 0)) {
log_error("dm_report: Unable to extend output line");
return 0;
}
free(field_id);
if (!dm_pool_grow_object(rh->mem, "=", 1)) {
log_error("dm_report: Unable to extend output line");
return 0;
}
if (!(rh->flags & DM_REPORT_OUTPUT_FIELD_UNQUOTED) &&
!dm_pool_grow_object(rh->mem, "\'", 1)) {
log_error("dm_report: Unable to extend output line");
return 0;
}
}
repstr = field->report_string;
width = field->props->width;
if (!(rh->flags & DM_REPORT_OUTPUT_ALIGNED)) {
if (!dm_pool_grow_object(rh->mem, repstr, 0)) {
log_error("dm_report: Unable to extend output line");
return 0;
}
} else {
if (!(align = field->props->flags & DM_REPORT_FIELD_ALIGN_MASK))
align = (field->props->flags & DM_REPORT_FIELD_TYPE_NUMBER) ?
DM_REPORT_FIELD_ALIGN_RIGHT : DM_REPORT_FIELD_ALIGN_LEFT;
if (align & DM_REPORT_FIELD_ALIGN_LEFT) {
if (dm_snprintf(buf, sizeof(buf), "%-*.*s",
width, width, repstr) < 0) {
log_error("dm_report: left-aligned snprintf() failed");
return 0;
}
if (!dm_pool_grow_object(rh->mem, buf, width)) {
log_error("dm_report: Unable to extend output line");
return 0;
}
} else if (align & DM_REPORT_FIELD_ALIGN_RIGHT) {
if (dm_snprintf(buf, sizeof(buf), "%*.*s",
width, width, repstr) < 0) {
log_error("dm_report: right-aligned snprintf() failed");
return 0;
}
if (!dm_pool_grow_object(rh->mem, buf, width)) {
log_error("dm_report: Unable to extend output line");
return 0;
}
}
}
if ((rh->flags & DM_REPORT_OUTPUT_FIELD_NAME_PREFIX) &&
!(rh->flags & DM_REPORT_OUTPUT_FIELD_UNQUOTED))
if (!dm_pool_grow_object(rh->mem, "\'", 1)) {
log_error("dm_report: Unable to extend output line");
return 0;
}
return 1;
}
static int _output_as_rows(struct dm_report *rh)
{
struct field_properties *fp;
struct dm_report_field *field;
struct row *row;
if (!dm_pool_begin_object(rh->mem, 512)) {
log_error("dm_report: Unable to allocate output line");
return 0;
}
list_iterate_items(fp, &rh->field_props) {
if (fp->flags & FLD_HIDDEN) {
list_iterate_items(row, &rh->rows) {
field = list_item(list_first(&row->fields), struct dm_report_field);
list_del(&field->list);
}
continue;
}
if ((rh->flags & DM_REPORT_OUTPUT_HEADINGS)) {
if (!dm_pool_grow_object(rh->mem, rh->fields[fp->field_num].heading, 0)) {
log_error("dm_report: Failed to extend row for field name");
goto bad;
}
if (!dm_pool_grow_object(rh->mem, rh->separator, 0)) {
log_error("dm_report: Failed to extend row with separator");
goto bad;
}
}
list_iterate_items(row, &rh->rows) {
if ((field = list_item(list_first(&row->fields), struct dm_report_field))) {
if (!_output_field(rh, field))
goto bad;
list_del(&field->list);
}
if (!list_end(&rh->rows, &row->list))
if (!dm_pool_grow_object(rh->mem, rh->separator, 0)) {
log_error("dm_report: Unable to extend output line");
goto bad;
}
}
if (!dm_pool_grow_object(rh->mem, "\0", 1)) {
log_error("dm_report: Failed to terminate row");
goto bad;
}
log_print("%s", (char *) dm_pool_end_object(rh->mem));
}
return 1;
bad:
dm_pool_abandon_object(rh->mem);
return 0;
}
static int _output_as_columns(struct dm_report *rh)
{
struct list *fh, *rowh, *ftmp, *rtmp;
struct row *row = NULL;
struct dm_report_field *field;
const char *repstr;
char buf[4096];
int32_t width;
uint32_t align;
if (list_empty(&rh->rows))
return 1;
/* Sort rows */
if ((rh->flags & RH_SORT_REQUIRED))
_sort_rows(rh);
/* If headings not printed yet, calculate field widths and print them */
if (!(rh->flags & RH_HEADINGS_PRINTED))
@@ -800,47 +964,15 @@ int dm_report_output(struct dm_report *rh)
if (field->props->flags & FLD_HIDDEN)
continue;
repstr = field->report_string;
width = field->props->width;
if (!(rh->flags & DM_REPORT_OUTPUT_ALIGNED)) {
if (!dm_pool_grow_object(rh->mem, repstr,
strlen(repstr))) {
log_error("dm_report: Unable to extend output line");
goto bad;
}
} else {
if (!(align = field->props->flags & DM_REPORT_FIELD_ALIGN_MASK))
align = (field->props->flags & DM_REPORT_FIELD_TYPE_NUMBER) ?
DM_REPORT_FIELD_ALIGN_RIGHT : DM_REPORT_FIELD_ALIGN_LEFT;
if (align & DM_REPORT_FIELD_ALIGN_LEFT) {
if (dm_snprintf(buf, sizeof(buf), "%-*.*s",
width, width, repstr) < 0) {
log_error("dm_report: left-aligned snprintf() failed");
goto bad;
}
if (!dm_pool_grow_object(rh->mem, buf, width)) {
log_error("dm_report: Unable to extend output line");
goto bad;
}
} else if (align & DM_REPORT_FIELD_ALIGN_RIGHT) {
if (dm_snprintf(buf, sizeof(buf), "%*.*s",
width, width, repstr) < 0) {
log_error("dm_report: right-aligned snprintf() failed");
goto bad;
}
if (!dm_pool_grow_object(rh->mem, buf, width)) {
log_error("dm_report: Unable to extend output line");
goto bad;
}
}
}
if (!_output_field(rh, field))
goto bad;
if (!list_end(&row->fields, fh))
if (!dm_pool_grow_object(rh->mem, rh->separator,
strlen(rh->separator))) {
if (!dm_pool_grow_object(rh->mem, rh->separator, 0)) {
log_error("dm_report: Unable to extend output line");
goto bad;
}
list_del(&field->list);
}
if (!dm_pool_grow_object(rh->mem, "\0", 1)) {
@@ -860,3 +992,17 @@ int dm_report_output(struct dm_report *rh)
dm_pool_abandon_object(rh->mem);
return 0;
}
int dm_report_output(struct dm_report *rh)
{
if (list_empty(&rh->rows))
return 1;
if ((rh->flags & RH_SORT_REQUIRED))
_sort_rows(rh);
if ((rh->flags & DM_REPORT_OUTPUT_COLUMNS_AS_ROWS))
return _output_as_rows(rh);
else
return _output_as_columns(rh);
}

View File

@@ -40,7 +40,7 @@ struct memblock {
const char *file; /* File that allocated */
int line; /* Line that allocated */
void *magic; /* Address of this block */
};
} __attribute__((aligned(8)));
static struct {
unsigned block_serialno;/* Non-decreasing serialno of block */

View File

@@ -36,7 +36,7 @@ void bounds_check(void);
#else
# define dm_free(p) free(p)
# define dm_free(p) do {if (p) free(p); } while (0)
# define dbg_realloc(p, s) realloc(p, s)
# define dump_memory()
# define bounds_check()

View File

@@ -216,10 +216,10 @@ int dm_pool_begin_object(struct dm_pool *p, size_t init_size)
return 1;
}
int dm_pool_grow_object(struct dm_pool *p, const void *buffer, size_t delta)
int dm_pool_grow_object(struct dm_pool *p, const void *extra, size_t delta)
{
struct block *new;
size_t size = delta;
size_t size = delta ? : strlen(extra);
assert(p->begun);
@@ -238,7 +238,7 @@ int dm_pool_grow_object(struct dm_pool *p, const void *buffer, size_t delta)
}
p->object = new;
memcpy(new->data + size - delta, buffer, delta);
memcpy(new->data + size - delta, extra, delta);
return 1;
}

View File

@@ -162,14 +162,17 @@ int dm_pool_begin_object(struct dm_pool *p, size_t hint)
return 1;
}
int dm_pool_grow_object(struct dm_pool *p, const void *extra, size_t n)
int dm_pool_grow_object(struct dm_pool *p, const void *extra, size_t delta)
{
struct chunk *c = p->chunk, *nc;
if (c->end - (c->begin + p->object_len) < n) {
if (!delta)
delta = strlen(extra);
if (c->end - (c->begin + p->object_len) < delta) {
/* move into a new chunk */
if (p->object_len + n > (p->chunk_size / 2))
nc = _new_chunk(p, (p->object_len + n) * 2);
if (p->object_len + delta > (p->chunk_size / 2))
nc = _new_chunk(p, (p->object_len + delta) * 2);
else
nc = _new_chunk(p, p->chunk_size);
@@ -181,8 +184,8 @@ int dm_pool_grow_object(struct dm_pool *p, const void *extra, size_t n)
c = p->chunk;
}
memcpy(c->begin + p->object_len, extra, n);
p->object_len += n;
memcpy(c->begin + p->object_len, extra, delta);
p->object_len += delta;
return 1;
}

View File

@@ -1,7 +1,7 @@
# @configure_input@
#
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
# Copyright (C) 2004 Red Hat, Inc. All rights reserved.
# Copyright (C) 2004, 2008 Red Hat, Inc. All rights reserved.
#
# This file is part of LVM2.
#

View File

@@ -30,7 +30,7 @@ Communicates with the kernel device-mapper driver via
libdevmapper to activate (-ay) or deactivate (-an) the
logical volumes.
.IP
If clustered locking is enabled, -ae will activate exclusively
If clustered locking is enabled, -aey will activate exclusively
on one node and -aly will activate only on the local node.
To deactivate only on the local node use -aln.
Logical volumes with single-host snapshots are always activated

View File

@@ -11,7 +11,7 @@ lvcreate \- create a logical volume in an existing volume group
{\-l/\-\-extents LogicalExtentsNumber[%{VG|PVS|FREE}] |
\-L/\-\-size LogicalVolumeSize[kKmMgGtT]}
[\-M/\-\-persistent y/n] [\-\-minor minor]
[\-m/\-\-mirrors Mirrors [\-\-nosync] [\-\-mirrorlog {disk|log}] [\-\-corelog]
[\-m/\-\-mirrors Mirrors [\-\-nosync] [\-\-mirrorlog {disk|core}] [\-\-corelog]
[\-R/\-\-regionsize MirrorLogRegionSize]]
[\-n/\-\-name LogicalVolumeName]
[\-p/\-\-permission r/rw] [\-r/\-\-readahead ReadAheadSectors|auto|none]

View File

@@ -84,7 +84,7 @@ Defaults to "/dev".
\fBpreferred_names\fP \(em List of patterns compared in turn against
all the pathnames referencing the same device in in the scanned directories.
The pathname that matches the earliest pattern in the list is the
one used in any output. As an example, if device mapper multipathing
one used in any output. As an example, if device-mapper multipathing
is used, the following will select multipath device names:
.br
\fBdevices { preferred_names = [ "^/dev/mapper/mpath" ] }\fP

View File

@@ -43,7 +43,9 @@ RMDIR=rmdir
BLOCKDEV=blockdev
BLKID=blkid
GREP=grep
CUT=cut
READLINK=readlink
READLINK_E="-e"
FSCK=fsck
XFS_CHECK=xfs_check
@@ -154,9 +156,10 @@ decode_size() {
# dereference device name if it is symbolic link
detect_fs() {
VOLUME=${1#/dev/}
VOLUME=$($READLINK -e -n "/dev/$VOLUME") || error "Cannot get readlink $1"
VOLUME=$($READLINK $READLINK_E -n "/dev/$VOLUME") || error "Cannot get readlink $1"
# use /dev/null as cache file to be sure about the result
FSTYPE=$($BLKID -c /dev/null -o value -s TYPE "$VOLUME") || error "Cannot get FSTYPE of \"$VOLUME\""
# use 'cut' to be compatible with older version of blkid that does not provide option '-o value'
FSTYPE=$($BLKID -c /dev/null -s TYPE "$VOLUME" | $CUT -d \" -f 2) || error "Cannot get FSTYPE of \"$VOLUME\""
verbose "\"$FSTYPE\" filesystem found on \"$VOLUME\""
}
@@ -171,7 +174,15 @@ detect_mounted() {
# get the full size of device in bytes
detect_device_size() {
DEVSIZE=$($BLOCKDEV --getsize64 "$VOLUME") || error "Cannot read device \"$VOLUME\""
# check if blockdev supports getsize64
$BLOCKDEV 2>&1 | $GREP getsize64 >/dev/null
if test $? -eq 0; then
DEVSIZE=$($BLOCKDEV --getsize64 "$VOLUME") || error "Cannot read size of device \"$VOLUME\""
else
DEVSIZE=$($BLOCKDEV --getsize "$VOLUME") || error "Cannot read size of device \"$VOLUME\""
SSSIZE=$($BLOCKDEV --getss "$VOLUME") || error "Cannot block size read device \"$VOLUME\""
DEVSIZE=$(($DEVSIZE * $SSSIZE))
fi
}
# round up $1 / $2
@@ -349,9 +360,10 @@ test -n "$FSADM_RUNNING" && exit 0
test -n "$TUNE_EXT" -a -n "$RESIZE_EXT" -a -n "$TUNE_REISER" -a -n "$RESIZE_REISER" \
-a -n "$TUNE_XFS" -a -n "$RESIZE_XFS" -a -n "$MOUNT" -a -n "$UMOUNT" -a -n "$MKDIR" \
-a -n "$RMDIR" -a -n "$BLOCKDEV" -a -n "$BLKID" -a -n "$GREP" -a -n "$READLINK" \
-a -n "$FSCK" -a -n "$XFS_CHECK" -a -n "LVRESIZE" \
-a -n "$FSCK" -a -n "$XFS_CHECK" -a -n "LVRESIZE" -a -n "$CUT" \
|| error "Required command definitions in the script are missing!"
$($READLINK -e -n / >/dev/null 2>&1) || error "$READLINK does not support options -e -n"
$($READLINK -e -n / >/dev/null 2>&1) || READLINK_E="-f"
TEST64BIT=$(( 1000 * 1000000000000 ))
test $TEST64BIT -eq 1000000000000000 || error "Shell does not handle 64bit arithmetic"
$(echo Y | $GREP Y >/dev/null) || error "Grep does not work properly"

View File

@@ -1,7 +1,7 @@
# Put lvm-related utilities here.
# This file is sourced from test-lib.sh.
# Copyright (C) 2007 Red Hat, Inc. All rights reserved.
# Copyright (C) 2007, 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
@@ -63,7 +63,7 @@ check_vg_field_()
{
if test "$verbose" = "t"
then
echo "check_vg_field_ VG: $1 actual: `vgs --noheadings -o $2 $1` expected $3"
echo "check_vg_field_ VG=$1, field=$2, actual=`vgs --noheadings -o $2 $1`, expected=$3"
fi
return $(test $(vgs --noheadings -o $2 $1) == $3)
}
@@ -72,7 +72,7 @@ check_pv_field_()
{
if test "$verbose" = "t"
then
echo "check_pv_field_ PV: $1 actual: `pvs --noheadings -o $2 $1` expected $3"
echo "check_pv_field_ PV=$1, field=$2, actual=`pvs --noheadings -o $2 $1`, expected=$3"
fi
return $(test $(pvs --noheadings -o $2 $1) == $3)
}
@@ -81,11 +81,23 @@ check_lv_field_()
{
if test "$verbose" = "t"
then
echo "check_lv_field_ LV: $1 actual: `lvs --noheadings -o $2 $1` expected $3"
echo "check_lv_field_ LV=$1, field=$2, actual=`lvs --noheadings -o $2 $1`, expected=$3"
fi
return $(test $(lvs --noheadings -o $2 $1) == $3)
}
vg_validate_pvlv_counts_()
{
local local_vg=$1
local num_pvs=$2
local num_lvs=$3
local num_snaps=$4
check_vg_field_ $local_vg pv_count $num_pvs &&
check_vg_field_ $local_vg lv_count $num_lvs &&
check_vg_field_ $local_vg snap_count $num_snaps
}
dmsetup_has_dm_devdir_support_()
{
# Detect support for the envvar. If it's supported, the
@@ -100,7 +112,7 @@ init_root_dir_()
{
test -n "$test_dir_rand_" \
|| error "Internal error: called init_root_dir_ before" \
" defining $test_dir_rand_"
"defining \$test_dir_rand_"
# Define these two globals.
G_root_=$test_dir_rand_/root

61
test/t-lvmcache-exercise.sh Executable file
View File

@@ -0,0 +1,61 @@
#!/bin/sh
# Copyright (C) 2007 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
# of the GNU General Public License v.2.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
test_description='Test lvmcache operation'
privileges_required_=1
. ./test-lib.sh
cleanup_()
{
test -n "$d1" && losetup -d "$d1"
test -n "$d2" && losetup -d "$d2"
test -n "$d3" && losetup -d "$d3"
test -n "$d4" && losetup -d "$d4"
test -n "$d5" && losetup -d "$d5"
rm -f "$f1" "$f2" "$f3" "$f4" "$f5"
}
# FIXME: paramaterize lvm1 vs lvm2 metadata; most of these tests should run
# fine with lvm1 metadata as well; for now, just add disks 5 and 6 as lvm1
# metadata
test_expect_success \
'set up temp files, loopback devices, PVs, vgnames' \
'f1=$(pwd)/1 && d1=$(loop_setup_ "$f1") &&
f2=$(pwd)/2 && d2=$(loop_setup_ "$f2") &&
f3=$(pwd)/3 && d3=$(loop_setup_ "$f3") &&
f4=$(pwd)/4 && d4=$(loop_setup_ "$f4") &&
f5=$(pwd)/5 && d5=$(loop_setup_ "$f5") &&
vg1=$(this_test_)-test-vg1-$$ &&
vg2=$(this_test_)-test-vg2-$$ &&
lv1=$(this_test_)-test-lv1-$$ &&
lv2=$(this_test_)-test-lv2-$$ &&
lv3=$(this_test_)-test-lv3-$$ &&
pvcreate $d1 $d2 $d3 $d4 $d5'
#
# Duplicate vg name should cause warnings (but not segfault!)
#
test_expect_success \
"Duplicate vg name might cause warnings but should succeed" \
'vgcreate $vg1 $d1 &&
vgcreate $vg2 $d3 &&
losetup -d $d1 &&
vgcreate $vg1 $d2 &&
losetup $d1 $f1 &&
pvs &&
pvs'
test_done
# Local Variables:
# indent-tabs-mode: nil
# End:

View File

@@ -1,5 +1,5 @@
#!/bin/sh
# Copyright (C) 2007 Red Hat, Inc. All rights reserved.
# Copyright (C) 2007-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

View File

@@ -387,6 +387,16 @@ test_expect_success "remove from original mirror (the original becomes linear)"
mirrorlog_is_on_ $vg/$lv1 $(pv_ 3) &&
check_and_cleanup_lvs_'
test_expect_success "rhbz440405: lvconvert -m0 incorrectly fails if all PEs allocated" \
'prepare_lvs_ &&
lvcreate -l`pvs --noheadings -ope_count $(pv_ 1)` -m1 -n $lv1 $vg $(pv_ 1) $(pv_ 2) $(pv_ 3):0 &&
check_mirror_count_ $vg/$lv1 2 &&
check_mirror_log_ $vg/$lv1 &&
lvconvert -m0 $vg/$lv1 $(pv_ 1) &&
check_no_tmplvs_ $vg/$lv1 &&
check_mirror_count_ $vg/$lv1 1 &&
check_and_cleanup_lvs_'
# ---------------------------------------------------------------------
test_done

68
test/t-read-ahead.sh Executable file
View File

@@ -0,0 +1,68 @@
#!/bin/sh
# Copyright (C) 2007 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
# of the GNU General Public License v.2.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# tests basic functionality of read-ahead and ra regressions
#
test_description='Test read-ahead functionality'
privileges_required_=1
. ./test-lib.sh
cleanup_()
{
test -n "$d1" && losetup -d "$d1"
test -n "$d2" && losetup -d "$d2"
test -n "$d3" && losetup -d "$d3"
test -n "$d4" && losetup -d "$d4"
test -n "$d5" && losetup -d "$d5"
rm -f "$f1" "$f2" "$f3" "$f4" "$f5"
}
get_lvs_()
{
case $(lvs --units s --nosuffix --noheadings -o $1_read_ahead "$vg"/"$lv") in
*$2) true ;;
*) false ;;
esac
}
test_expect_success "set up temp files, loopback devices" \
'f1=$(pwd)/1 && d1=$(loop_setup_ "$f1") &&
f2=$(pwd)/2 && d2=$(loop_setup_ "$f2") &&
f3=$(pwd)/3 && d3=$(loop_setup_ "$f3") &&
f4=$(pwd)/4 && d4=$(loop_setup_ "$f4") &&
f5=$(pwd)/5 && d5=$(loop_setup_ "$f5") &&
vg=$(this_test_)-test-vg-$$ &&
lv=$(this_test_)-test-lv-$$'
test_expect_success "test various read ahead settings" \
'pvcreate "$d1" &&
pvcreate "$d2" &&
pvcreate "$d3" &&
pvcreate "$d4" &&
pvcreate "$d5" &&
vgcreate -c n "$vg" "$d1" "$d2" "$d3" "$d4" "$d5" &&
lvcreate -n "$lv" -l 100%FREE -i5 -I256 "$vg" &&
lvdisplay "$vg"/"$lv" &&
lvchange -r auto "$vg"/"$lv" || true | grep auto &&
get_lvs_ lv auto &&
get_lvs_ lv_kernel 5120 &&
lvchange -r 400 "$vg/$lv" &&
get_lvs_ lv 400 &&
vgremove -f "$vg"'
test_done
# Local Variables:
# indent-tabs-mode: nil
# End:

View File

@@ -1,5 +1,5 @@
#!/bin/sh
# Copyright (C) 2007 Red Hat, Inc. All rights reserved.
# Copyright (C) 2007-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
@@ -23,18 +23,6 @@ cleanup_()
rm -f "$f1" "$f2" "$f3" "$f4"
}
vg_validate_pvlv_counts_()
{
local local_vg=$1
local num_pvs=$2
local num_lvs=$3
local num_snaps=$4
check_vg_field_ $local_vg pv_count $num_pvs &&
check_vg_field_ $local_vg lv_count $num_lvs &&
check_vg_field_ $local_vg snap_count $num_snaps
}
test_expect_success \
'set up temp files, loopback devices, PVs, vgnames' \
'f1=$(pwd)/1 && d1=$(loop_setup_ "$f1") &&
@@ -81,10 +69,10 @@ test_expect_success \
lvcreate -l 16 -n $lv1 $vg1 &&
lvcreate -l 4 -s -n $lv2 $vg1/$lv1 &&
vgchange -an $vg1 &&
vg_validate_pvlv_counts_ $vg1 2 1 1 &&
vg_validate_pvlv_counts_ $vg1 2 2 1 &&
vg_validate_pvlv_counts_ $vg2 2 0 0 &&
vgmerge $vg2 $vg1 &&
vg_validate_pvlv_counts_ $vg2 4 1 1 &&
vg_validate_pvlv_counts_ $vg2 4 2 1 &&
lvremove -f $vg2/$lv2 &&
vgremove -f $vg2'
@@ -94,10 +82,10 @@ test_expect_success \
vgcreate $vg2 $d4 &&
lvcreate -l 4 -n $lv1 -m1 $vg1 &&
vgchange -an $vg1 &&
vg_validate_pvlv_counts_ $vg1 3 4 0 &&
vg_validate_pvlv_counts_ $vg1 3 1 0 &&
vg_validate_pvlv_counts_ $vg2 1 0 0 &&
vgmerge $vg2 $vg1 &&
vg_validate_pvlv_counts_ $vg2 4 4 0 &&
vg_validate_pvlv_counts_ $vg2 4 1 0 &&
lvremove -f $vg2/$lv1 &&
vgremove -f $vg2'

View File

@@ -24,18 +24,6 @@ cleanup_()
rm -f "$f1" "$f2" "$f3" "$f4" "$f5"
}
vg_validate_pvlv_counts_()
{
local local_vg=$1
local num_pvs=$2
local num_lvs=$3
local num_snaps=$4
check_vg_field_ $local_vg pv_count $num_pvs &&
check_vg_field_ $local_vg lv_count $num_lvs &&
check_vg_field_ $local_vg snap_count $num_snaps
}
# FIXME: paramaterize lvm1 vs lvm2 metadata; most of these tests should run
# fine with lvm1 metadata as well; for now, just add disks 5 and 6 as lvm1
# metadata
@@ -121,9 +109,9 @@ test_expect_success \
vgsplit -n $lv1 $vg1 $vg2
fi &&
if [ $i == existing ]; then
vg_validate_pvlv_counts_ $vg2 4 4 0
vg_validate_pvlv_counts_ $vg2 4 1 0
else
vg_validate_pvlv_counts_ $vg2 3 4 0
vg_validate_pvlv_counts_ $vg2 3 1 0
fi &&
lvremove -f $vg2/$lv1 &&
vgremove -f $vg2'
@@ -143,9 +131,9 @@ test_expect_success \
vgsplit -n $lv1 $vg1 $vg2
fi &&
if [ $i == existing ]; then
vg_validate_pvlv_counts_ $vg2 4 1 1
vg_validate_pvlv_counts_ $vg2 4 2 1
else
vg_validate_pvlv_counts_ $vg2 2 1 1
vg_validate_pvlv_counts_ $vg2 2 2 1
fi &&
lvremove -f $vg2/$lv2 &&
lvremove -f $vg2/$lv1 &&
@@ -169,10 +157,10 @@ test_expect_success \
fi &&
if [ $i == existing ]; then
vg_validate_pvlv_counts_ $vg2 2 1 0
vg_validate_pvlv_counts_ $vg1 2 1 1
vg_validate_pvlv_counts_ $vg1 2 2 1
else
vg_validate_pvlv_counts_ $vg2 1 1 0
vg_validate_pvlv_counts_ $vg1 2 1 1
vg_validate_pvlv_counts_ $vg1 2 2 1
fi &&
lvremove -f $vg1/$lv2 &&
lvremove -f $vg1/$lv1 &&
@@ -196,10 +184,10 @@ test_expect_success \
vgsplit -n $lv2 $vg1 $vg2
fi &&
if [ $i == existing ]; then
vg_validate_pvlv_counts_ $vg1 3 4 0
vg_validate_pvlv_counts_ $vg1 3 2 0
vg_validate_pvlv_counts_ $vg2 2 1 0
else
vg_validate_pvlv_counts_ $vg1 3 4 0
vg_validate_pvlv_counts_ $vg1 3 2 0
vg_validate_pvlv_counts_ $vg2 1 1 0
fi &&
lvremove -f $vg1/$lv1 &&
@@ -231,7 +219,7 @@ test_expect_success \
lvcreate -l 16 -n $lv1 $vg1 $d1 $d2 &&
lvcreate -l 4 -n $lv2 -s $vg1/$lv1 &&
lvcreate -l 4 -n $lv3 -s $vg1/$lv1 &&
vg_validate_pvlv_counts_ $vg1 4 1 2 &&
vg_validate_pvlv_counts_ $vg1 4 3 2 &&
vgchange -an $vg1 &&
vgsplit -n $lv1 $vg1 $vg2;
status=$?; echo status=$status; test $status = 5 &&
@@ -246,7 +234,7 @@ test_expect_success \
lvcreate -l 16 -n $lv1 $vg1 $d1 $d2 &&
lvcreate -l 4 -n $lv2 -s $vg1/$lv1 &&
lvcreate -l 4 -n $lv3 -s $vg1/$lv1 &&
vg_validate_pvlv_counts_ $vg1 4 1 2 &&
vg_validate_pvlv_counts_ $vg1 4 3 2 &&
vgchange -an $vg1 &&
vgsplit -n $lv2 $vg1 $vg2;
status=$?; echo status=$status; test $status = 5 &&
@@ -270,12 +258,71 @@ test_expect_success \
'vgcreate $vg1 $d1 $d2 $d3 $d4 &&
lvcreate -l 16 -n $lv1 -m1 $vg1 $d1 $d2 $d3 &&
lvcreate -l 16 -n $lv2 -i 2 $vg1 $d3 $d4 &&
vg_validate_pvlv_counts_ $vg1 4 5 0 &&
vg_validate_pvlv_counts_ $vg1 4 2 0 &&
vgchange -an $vg1 &&
vgsplit -n $lv2 $vg1 $vg2 2>err;
status=$?; echo status=$status; test $status = 5 &&
vgremove -ff $vg1'
#
# Verify vgsplit rejects active LVs only when active LVs involved in split
#
test_expect_success \
"vgsplit fails, active mirror involved in split" \
'vgcreate $vg1 $d1 $d2 $d3 $d4 &&
lvcreate -l 16 -n $lv1 -m1 $vg1 $d1 $d2 $d3 &&
lvcreate -l 16 -n $lv2 $vg1 $d4 &&
lvchange -an $vg1/$lv2 &&
vg_validate_pvlv_counts_ $vg1 4 2 0 &&
vgsplit -n $lv1 $vg1 $vg2;
status=$?; echo status=$status; test $status = 5 &&
vg_validate_pvlv_counts_ $vg1 4 2 0 &&
vgremove -ff $vg1'
test_expect_success \
"vgsplit succeeds, active mirror not involved in split" \
'vgcreate $vg1 $d1 $d2 $d3 $d4 &&
lvcreate -l 16 -n $lv1 -m1 $vg1 $d1 $d2 $d3 &&
lvcreate -l 16 -n $lv2 $vg1 $d4 &&
lvchange -an $vg1/$lv2 &&
vg_validate_pvlv_counts_ $vg1 4 2 0 &&
vgsplit -n $lv2 $vg1 $vg2 &&
vg_validate_pvlv_counts_ $vg1 3 1 0 &&
vg_validate_pvlv_counts_ $vg2 1 1 0 &&
vgremove -ff $vg1 &&
vgremove -ff $vg2'
test_expect_success \
"vgsplit fails, active snapshot involved in split" \
'vgcreate $vg1 $d1 $d2 $d3 $d4 &&
lvcreate -l 64 -i 2 -n $lv1 $vg1 $d1 $d2 &&
lvcreate -l 4 -i 2 -s -n $lv2 $vg1/$lv1 &&
lvcreate -l 64 -i 2 -n $lv3 $vg1 $d3 $d4 &&
lvchange -an $vg1/$lv3 &&
vg_validate_pvlv_counts_ $vg1 4 3 1 &&
vgsplit -n $lv2 $vg1 $vg2;
status=$?; echo status=$status; test $status = 5 &&
vg_validate_pvlv_counts_ $vg1 4 3 1 &&
lvremove -f $vg1/$lv2 &&
vgremove -ff $vg1'
test_expect_success \
"vgsplit succeeds, active snapshot not involved in split" \
'vgcreate $vg1 $d1 $d2 $d3 &&
lvcreate -l 64 -i 2 -n $lv1 $vg1 $d1 $d2 &&
lvcreate -l 4 -s -n $lv2 $vg1/$lv1 &&
vgextend $vg1 $d4 &&
lvcreate -l 64 -n $lv3 $vg1 $d4 &&
lvchange -an $vg1/$lv3 &&
vg_validate_pvlv_counts_ $vg1 4 3 1 &&
vgsplit -n $lv3 $vg1 $vg2 &&
vg_validate_pvlv_counts_ $vg1 3 2 1 &&
vg_validate_pvlv_counts_ $vg2 1 1 0 &&
vgchange -an $vg1 &&
lvremove -f $vg1/$lv2 &&
vgremove -ff $vg1 &&
vgremove -ff $vg2'
test_done

View File

@@ -1,5 +1,5 @@
#!/bin/sh
# Copyright (C) 2007 Red Hat, Inc. All rights reserved.
# Copyright (C) 2007-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

View File

@@ -53,6 +53,9 @@ arg(monitor_ARG, '\0', "monitor", yes_no_arg, 0)
arg(config_ARG, '\0', "config", string_arg, 0)
arg(trustcache_ARG, '\0', "trustcache", NULL, 0)
arg(ignoremonitoring_ARG, '\0', "ignoremonitoring", NULL, 0)
arg(nameprefixes_ARG, '\0', "nameprefixes", NULL, 0)
arg(unquoted_ARG, '\0', "unquoted", NULL, 0)
arg(rows_ARG, '\0', "rows", NULL, 0)
/* Allow some variations */
arg(resizable_ARG, '\0', "resizable", yes_no_arg, 0)

View File

@@ -217,6 +217,7 @@ xx(lvextend,
"\t[-A|--autobackup y|n]\n"
"\t[--alloc AllocationPolicy]\n"
"\t[-d|--debug]\n"
"\t[-f|--force]\n"
"\t[-h|--help]\n"
"\t[-i|--stripes Stripes [-I|--stripesize StripeSize]]\n"
"\t{-l|--extents [+]LogicalExtentsNumber[%{VG|PVS|FREE}] |\n"
@@ -230,9 +231,9 @@ xx(lvextend,
"\t[--version]" "\n"
"\tLogicalVolume[Path] [ PhysicalVolumePath... ]\n",
alloc_ARG, autobackup_ARG, extents_ARG, mirrors_ARG, nofsck_ARG,
resizefs_ARG, size_ARG, stripes_ARG, stripesize_ARG, test_ARG,
type_ARG)
alloc_ARG, autobackup_ARG, extents_ARG, force_ARG, mirrors_ARG,
nofsck_ARG, resizefs_ARG, size_ARG, stripes_ARG, stripesize_ARG,
test_ARG, type_ARG)
xx(lvmchange,
"With the device mapper, this is obsolete and does nothing.",
@@ -339,6 +340,7 @@ xx(lvresize,
"\t[-A|--autobackup y|n]\n"
"\t[--alloc AllocationPolicy]\n"
"\t[-d|--debug]\n"
"\t[-f|--force]\n"
"\t[-h|--help]\n"
"\t[-i|--stripes Stripes [-I|--stripesize StripeSize]]\n"
"\t{-l|--extents [+|-]LogicalExtentsNumber[%{VG|LV|PVS|FREE}] |\n"
@@ -351,8 +353,9 @@ xx(lvresize,
"\t[--version]" "\n"
"\tLogicalVolume[Path] [ PhysicalVolumePath... ]\n",
alloc_ARG, autobackup_ARG, extents_ARG, nofsck_ARG, resizefs_ARG,
size_ARG, stripes_ARG, stripesize_ARG, test_ARG, type_ARG)
alloc_ARG, autobackup_ARG, extents_ARG, force_ARG, nofsck_ARG,
resizefs_ARG, size_ARG, stripes_ARG, stripesize_ARG, test_ARG,
type_ARG)
xx(lvs,
"Display information about logical volumes",
@@ -363,23 +366,27 @@ xx(lvs,
"\t[-d|--debug]\n"
"\t[-h|--help]\n"
"\t[--ignorelockingfailure]\n"
"\t[--nameprefixes]\n"
"\t[--noheadings]\n"
"\t[--nosuffix]\n"
"\t[-o|--options [+]Field[,Field]]\n"
"\t[-O|--sort [+|-]key1[,[+|-]key2[,...]]]\n"
"\t[-P|--partial] " "\n"
"\t[--rows]\n"
"\t[--segments]\n"
"\t[--separator Separator]\n"
"\t[--trustcache]\n"
"\t[--unbuffered]\n"
"\t[--units hsbkmgtHKMGT]\n"
"\t[--unquoted]\n"
"\t[-v|--verbose]\n"
"\t[--version]" "\n"
"\t[LogicalVolume[Path] [LogicalVolume[Path]...]]\n",
aligned_ARG, all_ARG, ignorelockingfailure_ARG, noheadings_ARG,
nolocking_ARG, nosuffix_ARG, options_ARG, partial_ARG, segments_ARG,
separator_ARG, sort_ARG, trustcache_ARG, unbuffered_ARG, units_ARG)
aligned_ARG, all_ARG, ignorelockingfailure_ARG, nameprefixes_ARG,
noheadings_ARG, nolocking_ARG, nosuffix_ARG, options_ARG, partial_ARG,
rows_ARG, segments_ARG, separator_ARG, sort_ARG, trustcache_ARG,
unbuffered_ARG, units_ARG, unquoted_ARG)
xx(lvscan,
"List all logical volumes in all volume groups",
@@ -569,24 +576,28 @@ xx(pvs,
"\t[-a|--all]\n"
"\t[-d|--debug]" "\n"
"\t[-h|-?|--help] " "\n"
"\t[--noheadings]\n"
"\t[--ignorelockingfailure]\n"
"\t[--nameprefixes]\n"
"\t[--noheadings]\n"
"\t[--nosuffix]\n"
"\t[-o|--options [+]Field[,Field]]\n"
"\t[-O|--sort [+|-]key1[,[+|-]key2[,...]]]\n"
"\t[-P|--partial] " "\n"
"\t[--rows]\n"
"\t[--segments]\n"
"\t[--separator Separator]\n"
"\t[--trustcache]\n"
"\t[--unbuffered]\n"
"\t[--units hsbkmgtHKMGT]\n"
"\t[--unquoted]\n"
"\t[-v|--verbose]\n"
"\t[--version]\n"
"\t[PhysicalVolume [PhysicalVolume...]]\n",
aligned_ARG, all_ARG, ignorelockingfailure_ARG, noheadings_ARG,
nolocking_ARG, nosuffix_ARG, options_ARG, partial_ARG, segments_ARG,
separator_ARG, sort_ARG, trustcache_ARG, unbuffered_ARG, units_ARG)
aligned_ARG, all_ARG, ignorelockingfailure_ARG, nameprefixes_ARG,
noheadings_ARG, nolocking_ARG, nosuffix_ARG, options_ARG, partial_ARG,
rows_ARG, segments_ARG, separator_ARG, sort_ARG, trustcache_ARG,
unbuffered_ARG, units_ARG, unquoted_ARG)
xx(pvscan,
"List all physical volumes",
@@ -885,22 +896,26 @@ xx(vgs,
"\t[-d|--debug]\n"
"\t[-h|--help]\n"
"\t[--ignorelockingfailure]\n"
"\t[--nameprefixes]\n"
"\t[--noheadings]\n"
"\t[--nosuffix]\n"
"\t[-o|--options [+]Field[,Field]]\n"
"\t[-O|--sort [+|-]key1[,[+|-]key2[,...]]]\n"
"\t[-P|--partial] " "\n"
"\t[--rows]\n"
"\t[--separator Separator]\n"
"\t[--trustcache]\n"
"\t[--unbuffered]\n"
"\t[--units hsbkmgtHKMGT]\n"
"\t[--unquoted]\n"
"\t[-v|--verbose]\n"
"\t[--version]\n"
"\t[VolumeGroupName [VolumeGroupName...]]\n",
aligned_ARG, all_ARG, ignorelockingfailure_ARG, noheadings_ARG,
nolocking_ARG, nosuffix_ARG, options_ARG, partial_ARG, separator_ARG,
sort_ARG, trustcache_ARG, unbuffered_ARG, units_ARG)
aligned_ARG, all_ARG, ignorelockingfailure_ARG, nameprefixes_ARG,
noheadings_ARG, nolocking_ARG, nosuffix_ARG, options_ARG, partial_ARG,
rows_ARG, separator_ARG, sort_ARG, trustcache_ARG, unbuffered_ARG, units_ARG,
unquoted_ARG)
xx(vgscan,
"Search for all volume groups",

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.
* Copyright (C) 2005-2007 NEC Corporation
*
* This file is part of the device-mapper userspace tools.
@@ -114,6 +114,7 @@ enum {
MAJOR_ARG,
MINOR_ARG,
MODE_ARG,
NAMEPREFIXES_ARG,
NOFLUSH_ARG,
NOHEADINGS_ARG,
NOLOCKFS_ARG,
@@ -121,6 +122,7 @@ enum {
NOTABLE_ARG,
OPTIONS_ARG,
READAHEAD_ARG,
ROWS_ARG,
SEPARATOR_ARG,
SHOWKEYS_ARG,
SORT_ARG,
@@ -129,6 +131,7 @@ enum {
TREE_ARG,
UID_ARG,
UNBUFFERED_ARG,
UNQUOTED_ARG,
UUID_ARG,
VERBOSE_ARG,
VERSION_ARG,
@@ -1642,6 +1645,63 @@ static int _dm_info_status_disp(struct dm_report *rh,
return dm_report_field_string(rh, field, &s);
}
static int _dm_info_table_loaded_disp(struct dm_report *rh,
struct dm_pool *mem __attribute((unused)),
struct dm_report_field *field,
const void *data,
void *private __attribute((unused)))
{
const struct dm_info *info = data;
if (info->live_table) {
if (info->inactive_table)
dm_report_field_set_value(field, "Both", NULL);
else
dm_report_field_set_value(field, "Live", NULL);
return 1;
}
if (info->inactive_table)
dm_report_field_set_value(field, "Inactive", NULL);
else
dm_report_field_set_value(field, "None", NULL);
return 1;
}
static int _dm_info_suspended_disp(struct dm_report *rh,
struct dm_pool *mem __attribute((unused)),
struct dm_report_field *field,
const void *data,
void *private __attribute((unused)))
{
const struct dm_info *info = data;
if (info->suspended)
dm_report_field_set_value(field, "Suspended", NULL);
else
dm_report_field_set_value(field, "Active", NULL);
return 1;
}
static int _dm_info_read_only_disp(struct dm_report *rh,
struct dm_pool *mem __attribute((unused)),
struct dm_report_field *field,
const void *data,
void *private __attribute((unused)))
{
const struct dm_info *info = data;
if (info->read_only)
dm_report_field_set_value(field, "Read-only", NULL);
else
dm_report_field_set_value(field, "Writeable", NULL);
return 1;
}
static int _dm_info_devno_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field, const void *data,
void *private)
@@ -1697,7 +1757,7 @@ static int _dm_tree_names(struct dm_report *rh, struct dm_pool *mem,
log_error("dm_pool_grow_object failed");
goto out_abandon;
}
if (!dm_pool_grow_object(mem, name, strlen(name))) {
if (!dm_pool_grow_object(mem, name, 0)) {
log_error("dm_pool_grow_object failed");
goto out_abandon;
}
@@ -1763,7 +1823,7 @@ static int _dm_tree_parents_devs_disp(struct dm_report *rh, struct dm_pool *mem,
log_error("dm_snprintf failed");
goto out_abandon;
}
if (!dm_pool_grow_object(mem, buf, strlen(buf))) {
if (!dm_pool_grow_object(mem, buf, 0)) {
log_error("dm_pool_grow_object failed");
goto out_abandon;
}
@@ -1816,7 +1876,7 @@ static int _dm_deps_disp(struct dm_report *rh, struct dm_pool *mem,
log_error("dm_snprintf failed");
goto out_abandon;
}
if (!dm_pool_grow_object(mem, buf, strlen(buf))) {
if (!dm_pool_grow_object(mem, buf, 0)) {
log_error("dm_pool_grow_object failed");
goto out_abandon;
}
@@ -1869,7 +1929,7 @@ static const struct dm_report_object_type _report_types[] = {
};
/* Column definitions */
#define OFFSET_OF(strct, field) ((unsigned int) &((struct strct *)NULL)->field)
#define OFFSET_OF(strct, field) (((char*)&((struct strct*)0)->field) - (char*)0)
#define STR (DM_REPORT_FIELD_TYPE_STRING)
#define NUM (DM_REPORT_FIELD_TYPE_NUMBER)
#define FIELD_O(type, strct, sorttype, head, field, width, func, id, desc) {DR_ ## type, sorttype, OFFSET_OF(strct, field), width, id, head, &_ ## func ## _disp, desc},
@@ -1884,6 +1944,9 @@ FIELD_F(TASK, STR, "UUID", 32, dm_uuid, "uuid", "Unique (optional) identifier fo
FIELD_F(TASK, NUM, "RAhead", 6, dm_read_ahead, "read_ahead", "Read ahead in sectors.")
FIELD_F(INFO, STR, "Stat", 4, dm_info_status, "attr", "(L)ive, (I)nactive, (s)uspended, (r)ead-only, read-(w)rite.")
FIELD_F(INFO, STR, "Tables", 6, dm_info_table_loaded, "tables_loaded", "Which of the live and inactive table slots are filled.")
FIELD_F(INFO, STR, "Suspended", 9, dm_info_suspended, "suspended", "Whether the device is suspended.")
FIELD_F(INFO, STR, "Read-only", 9, dm_info_read_only, "readonly", "Whether the device is read-only or writeable.")
FIELD_F(INFO, STR, "DevNo", 5, dm_info_devno, "devno", "Device major and minor numbers")
FIELD_O(INFO, dm_info, NUM, "Maj", major, 3, int32, "major", "Block device major number.")
FIELD_O(INFO, dm_info, NUM, "Min", minor, 3, int32, "minor", "Block device minor number.")
@@ -1914,7 +1977,8 @@ static int _report_init(struct command *c)
char *options = (char *) default_report_options;
const char *keys = "";
const char *separator = " ";
int aligned = 1, headings = 1, buffered = 1;
int aligned = 1, headings = 1, buffered = 1, field_prefixes = 0;
int quoted = 1, columns_as_rows = 0;
uint32_t flags = 0;
size_t len = 0;
int r = 0;
@@ -1929,6 +1993,17 @@ static int _report_init(struct command *c)
if (_switches[UNBUFFERED_ARG])
buffered = 0;
if (_switches[ROWS_ARG])
columns_as_rows = 1;
if (_switches[UNQUOTED_ARG])
quoted = 0;
if (_switches[NAMEPREFIXES_ARG]) {
aligned = 0;
field_prefixes = 1;
}
if (_switches[OPTIONS_ARG] && _string_args[OPTIONS_ARG]) {
if (*_string_args[OPTIONS_ARG] != '+')
options = _string_args[OPTIONS_ARG];
@@ -1971,6 +2046,15 @@ static int _report_init(struct command *c)
if (headings)
flags |= DM_REPORT_OUTPUT_HEADINGS;
if (field_prefixes)
flags |= DM_REPORT_OUTPUT_FIELD_NAME_PREFIX;
if (!quoted)
flags |= DM_REPORT_OUTPUT_FIELD_UNQUOTED;
if (columns_as_rows)
flags |= DM_REPORT_OUTPUT_COLUMNS_AS_ROWS;
if (!(_report = dm_report_init(&_report_type,
_report_types, _report_fields,
options, separator, flags, keys, NULL)))
@@ -1981,6 +2065,9 @@ static int _report_init(struct command *c)
goto out;
}
if (field_prefixes)
dm_report_set_output_field_name_prefix(_report, "dm_");
r = 1;
out:
@@ -2047,7 +2134,7 @@ static void _usage(FILE *out)
" [-r|--readonly] [--noopencount] [--nolockfs]\n"
" [--readahead [+]<sectors>|auto|none]\n"
" [-c|-C|--columns] [-o <fields>] [-O|--sort <sort_fields>]\n"
" [--noheadings] [--separator <separator>]\n\n");
" [--nameprefixes] [--noheadings] [--separator <separator>]\n\n");
for (i = 0; _commands[i].name; i++)
fprintf(out, "\t%s %s\n", _commands[i].name, _commands[i].help);
fprintf(out, "\n<device> may be device name or -u <uuid> or "
@@ -2403,6 +2490,7 @@ static int _process_switches(int *argc, char ***argv, const char *dev_dir)
{"major", 1, &ind, MAJOR_ARG},
{"minor", 1, &ind, MINOR_ARG},
{"mode", 1, &ind, MODE_ARG},
{"nameprefixes", 0, &ind, NAMEPREFIXES_ARG},
{"noflush", 0, &ind, NOFLUSH_ARG},
{"noheadings", 0, &ind, NOHEADINGS_ARG},
{"nolockfs", 0, &ind, NOLOCKFS_ARG},
@@ -2410,6 +2498,7 @@ static int _process_switches(int *argc, char ***argv, const char *dev_dir)
{"notable", 0, &ind, NOTABLE_ARG},
{"options", 1, &ind, OPTIONS_ARG},
{"readahead", 1, &ind, READAHEAD_ARG},
{"rows", 0, &ind, ROWS_ARG},
{"separator", 1, &ind, SEPARATOR_ARG},
{"showkeys", 0, &ind, SHOWKEYS_ARG},
{"sort", 1, &ind, SORT_ARG},
@@ -2419,6 +2508,7 @@ static int _process_switches(int *argc, char ***argv, const char *dev_dir)
{"uid", 1, &ind, UID_ARG},
{"uuid", 1, &ind, UUID_ARG},
{"unbuffered", 0, &ind, UNBUFFERED_ARG},
{"unquoted", 0, &ind, UNQUOTED_ARG},
{"verbose", 1, &ind, VERBOSE_ARG},
{"version", 0, &ind, VERSION_ARG},
{0, 0, 0, 0}
@@ -2535,6 +2625,8 @@ static int _process_switches(int *argc, char ***argv, const char *dev_dir)
_switches[TARGET_ARG]++;
_target = optarg;
}
if ((ind == NAMEPREFIXES_ARG))
_switches[NAMEPREFIXES_ARG]++;
if ((ind == NOFLUSH_ARG))
_switches[NOFLUSH_ARG]++;
if ((ind == NOHEADINGS_ARG))
@@ -2563,6 +2655,8 @@ static int _process_switches(int *argc, char ***argv, const char *dev_dir)
}
}
}
if ((ind == ROWS_ARG))
_switches[ROWS_ARG]++;
if ((ind == SHOWKEYS_ARG))
_switches[SHOWKEYS_ARG]++;
if ((ind == TABLE_ARG)) {
@@ -2571,8 +2665,8 @@ static int _process_switches(int *argc, char ***argv, const char *dev_dir)
}
if ((ind == TREE_ARG))
_switches[TREE_ARG]++;
if ((ind == UNBUFFERED_ARG))
_switches[UNBUFFERED_ARG]++;
if ((ind == UNQUOTED_ARG))
_switches[UNQUOTED_ARG]++;
if ((ind == VERSION_ARG))
_switches[VERSION_ARG]++;
}

View File

@@ -178,6 +178,7 @@ static int lvchange_resync(struct cmd_context *cmd,
struct logical_volume *lv)
{
int active = 0;
int monitored;
struct lvinfo info;
struct logical_volume *log_lv;
@@ -221,6 +222,10 @@ static int lvchange_resync(struct cmd_context *cmd,
}
}
/* Activate exclusively to ensure no nodes still have LV active */
monitored = dmeventd_monitor_mode();
init_dmeventd_monitor(0);
if (vg_is_clustered(lv->vg) && !activate_lv_excl(cmd, lv)) {
log_error("Can't get exclusive access to clustered volume %s",
lv->name);
@@ -232,6 +237,8 @@ static int lvchange_resync(struct cmd_context *cmd,
return 0;
}
init_dmeventd_monitor(monitored);
log_lv = first_seg(lv)->log_lv;
log_very_verbose("Starting resync of %s%s%s mirror \"%s\"",
@@ -380,8 +387,11 @@ static int lvchange_readahead(struct cmd_context *cmd,
}
if (lv->read_ahead == read_ahead) {
log_error("Read ahead is already %u for \"%s\"",
read_ahead, lv->name);
if (read_ahead == DM_READ_AHEAD_AUTO)
log_error("Read ahead is already auto for \"%s\"", lv->name);
else
log_error("Read ahead is already %u for \"%s\"",
read_ahead, lv->name);
return 0;
}

View File

@@ -750,7 +750,7 @@ int lvconvert(struct cmd_context * cmd, int argc, char **argv)
if (lp.pv_count) {
if (!(lp.pvh = create_pv_list(cmd->mem, vg, lp.pv_count,
lp.pvs, 1)))
lp.pvs, 0)))
goto_bad;
} else
lp.pvh = &vg->pvs;

View File

@@ -801,7 +801,7 @@ static int _lvcreate(struct cmd_context *cmd, struct volume_group *vg,
if (lp->zero) {
log_error("Aborting. Failed to activate new LV to wipe "
"the start of it.");
goto revert_new_lv;
goto deactivate_and_revert_new_lv;
}
log_error("Failed to activate new LV.");
return 0;

View File

@@ -236,6 +236,10 @@ int lvm_shell(struct cmd_context *cmd, struct cmdline_context *cmdline)
log_error("No such command '%s'. Try 'help'.",
argv[0]);
if ((ret != ECMD_PROCESSED) && !error_message_produced()) {
log_debug("Internal error: Failed command did not use log_error");
log_error("Command failed with status code %d.", ret);
}
_write_history();
}

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.
*
@@ -79,9 +79,10 @@ int lvm2_run(void *handle, const char *cmdline)
}
/* FIXME Temporary - move to libdevmapper */
ret = ECMD_PROCESSED;
if (!strcmp(cmdline, "_memlock_inc"))
memlock_inc();
if (!strcmp(cmdline, "_memlock_dec"))
else if (!strcmp(cmdline, "_memlock_dec"))
memlock_dec();
else
ret = lvm_run_command(cmd, argc, argv);

View File

@@ -875,6 +875,8 @@ int lvm_run_command(struct cmd_context *cmd, int argc, char **argv)
int ret = 0;
int locking_type;
init_error_message_produced(0);
/* each command should start out with sigint flag cleared */
sigint_clear();
@@ -1096,7 +1098,14 @@ static int _run_script(struct cmd_context *cmd, int argc, char **argv)
continue;
if (!strcmp(argv[0], "quit") || !strcmp(argv[0], "exit"))
break;
lvm_run_command(cmd, argc, argv);
ret = lvm_run_command(cmd, argc, argv);
if (ret != ECMD_PROCESSED) {
if (!error_message_produced()) {
log_debug("Internal error: Failed command did not use log_error");
log_error("Command failed with status code %d.", ret);
}
break;
}
}
if (fclose(script))
@@ -1218,6 +1227,11 @@ int lvm2_main(int argc, char **argv, unsigned is_static)
if (ret == ENO_SUCH_CMD)
log_error("No such command. Try 'help'.");
if ((ret != ECMD_PROCESSED) && !error_message_produced()) {
log_debug("Internal error: Failed command did not use log_error");
log_error("Command failed with status code %d.", ret);
}
out:
lvm_fin(cmd);
if (ret == ECMD_PROCESSED)

View File

@@ -229,8 +229,8 @@ static int _lvresize_params(struct cmd_context *cmd, int argc, char **argv,
argv++;
argc--;
if (!(lp->lv_name = skip_dev_dir(cmd, lp->lv_name, &dev_dir_found))
|| (!(lp->vg_name = extract_vgname(cmd, lp->lv_name)))) {
if (!(lp->lv_name = skip_dev_dir(cmd, lp->lv_name, &dev_dir_found)) ||
!(lp->vg_name = extract_vgname(cmd, lp->lv_name))) {
log_error("Please provide a volume group name");
return 0;
}
@@ -269,6 +269,7 @@ static int _lvresize(struct cmd_context *cmd, struct volume_group *vg,
uint32_t sz, str;
struct list *pvh = NULL;
char size_buf[SIZE_BUF];
char lv_path[PATH_MAX];
/* does LV exist? */
if (!(lvl = find_lv_in_vg(vg, lp->lv_name))) {
@@ -623,14 +624,17 @@ static int _lvresize(struct cmd_context *cmd, struct volume_group *vg,
log_print("Logical volume %s successfully resized", lp->lv_name);
if (lp->resizefs && (lp->resize == LV_EXTEND)) {
char lv_path[PATH_MAX];
if (dm_snprintf(lv_path, PATH_MAX, "%s%s/%s", cmd->dev_dir,
lp->vg_name, lp->lv_name) < 0) {
log_error("Couldn't create LV path for %s",
lp->lv_name);
return ECMD_FAILED;
}
if (dm_snprintf(size_buf, SIZE_BUF, "%" PRIu64,
(uint64_t) lp->extents * vg->extent_size / 2) < 0) {
log_error("Couldn't generate new LV size string");
return ECMD_FAILED;
}
if (!exec_cmd("fsadm", "resize", lv_path, size_buf)) {
stack;
return ECMD_FAILED;

View File

@@ -225,7 +225,7 @@ static int pvcreate_single(struct cmd_context *cmd, const char *pv_name,
}
list_init(&mdas);
if (!(pv = pv_create(cmd->fmt, dev, idp, size, pe_start,
if (!(pv = pv_create(cmd, dev, idp, size, pe_start,
extent_count, extent_size,
pvmetadatacopies, pvmetadatasize, &mdas))) {
log_error("Failed to setup physical volume \"%s\"", pv_name);

View File

@@ -158,7 +158,8 @@ static int _report(struct cmd_context *cmd, int argc, char **argv,
char *str;
const char *keys = NULL, *options = NULL, *separator;
int r = ECMD_PROCESSED;
int aligned, buffered, headings;
int aligned, buffered, headings, field_prefixes, quoted;
int columns_as_rows;
unsigned args_are_pvs;
aligned = find_config_tree_int(cmd, "report/aligned",
@@ -169,6 +170,12 @@ static int _report(struct cmd_context *cmd, int argc, char **argv,
DEFAULT_REP_HEADINGS);
separator = find_config_tree_str(cmd, "report/separator",
DEFAULT_REP_SEPARATOR);
field_prefixes = find_config_tree_int(cmd, "report/prefixes",
DEFAULT_REP_PREFIXES);
quoted = find_config_tree_int(cmd, "report/quoted",
DEFAULT_REP_QUOTED);
columns_as_rows = find_config_tree_int(cmd, "report/columns_as_rows",
DEFAULT_REP_COLUMNS_AS_ROWS);
args_are_pvs = (report_type == PVS || report_type == PVSEGS) ? 1 : 0;
@@ -270,10 +277,19 @@ static int _report(struct cmd_context *cmd, int argc, char **argv,
buffered = 0;
if (arg_count(cmd, noheadings_ARG))
headings = 0;
if (arg_count(cmd, nameprefixes_ARG)) {
aligned = 0;
field_prefixes = 1;
}
if (arg_count(cmd, unquoted_ARG))
quoted = 0;
if (arg_count(cmd, rows_ARG))
columns_as_rows = 1;
if (!(report_handle = report_init(cmd, options, keys, &report_type,
separator, aligned, buffered,
headings))) {
headings, field_prefixes, quoted,
columns_as_rows))) {
stack;
return ECMD_FAILED;
}

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.
*
@@ -145,7 +145,7 @@ int process_each_lv_in_vg(struct cmd_context *cmd,
void *handle,
process_single_lv_fn_t process_single)
{
int ret_max = 0;
int ret_max = ECMD_PROCESSED;
int ret = 0;
unsigned process_all = 0;
unsigned process_lv = 0;
@@ -223,7 +223,7 @@ int process_each_lv(struct cmd_context *cmd, int argc, char **argv,
void *handle))
{
int opt = 0;
int ret_max = 0;
int ret_max = ECMD_PROCESSED;
int ret = 0;
int consistent;
@@ -404,7 +404,7 @@ int process_each_lv(struct cmd_context *cmd, int argc, char **argv,
if (ret > ret_max)
ret_max = ret;
if (sigint_caught())
return ret_max;
break;
}
return ret_max;
@@ -421,7 +421,7 @@ int process_each_segment_in_pv(struct cmd_context *cmd,
{
struct pv_segment *pvseg;
const char *vg_name = NULL;
int ret_max = 0;
int ret_max = ECMD_PROCESSED;
int ret;
if (!vg && !is_orphan(pv)) {
@@ -456,7 +456,7 @@ int process_each_segment_in_lv(struct cmd_context *cmd,
void *handle))
{
struct lv_segment *seg;
int ret_max = 0;
int ret_max = ECMD_PROCESSED;
int ret;
list_iterate_items(seg, &lv->segments) {
@@ -464,7 +464,7 @@ int process_each_segment_in_lv(struct cmd_context *cmd,
if (ret > ret_max)
ret_max = ret;
if (sigint_caught())
return ret_max;
break;
}
return ret_max;
@@ -514,9 +514,6 @@ static int _process_one_vg(struct cmd_context *cmd, const char *vg_name,
ret_max = ret;
}
if (sigint_caught())
return ret_max;
unlock_vg(cmd, vg_name);
return ret_max;
@@ -530,7 +527,7 @@ int process_each_vg(struct cmd_context *cmd, int argc, char **argv,
int consistent, void *handle))
{
int opt = 0;
int ret_max = 0;
int ret_max = ECMD_PROCESSED;
struct str_list *sl;
struct list *vgnames, *vgids;
@@ -616,7 +613,7 @@ int process_each_pv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
const struct list *tags, void *handle,
process_single_pv_fn_t process_single)
{
int ret_max = 0;
int ret_max = ECMD_PROCESSED;
int ret = 0;
struct pv_list *pvl;
@@ -645,7 +642,7 @@ static int _process_all_devs(struct cmd_context *cmd, void *handle,
struct dev_iter *iter;
struct device *dev;
int ret_max = 0;
int ret_max = ECMD_PROCESSED;
int ret = 0;
if (!scan_vgs_for_pvs(cmd)) {
@@ -687,7 +684,7 @@ int process_each_pv(struct cmd_context *cmd, int argc, char **argv,
void *handle))
{
int opt = 0;
int ret_max = 0;
int ret_max = ECMD_PROCESSED;
int ret = 0;
struct pv_list *pvl;
@@ -1245,8 +1242,6 @@ int is_reserved_lvname(const char *name)
return rc;
}
/*
* Set members of struct vgcreate_params from cmdline.
* Do preliminary validation with arg_*() interface.

View File

@@ -66,10 +66,14 @@ static int _activate_lvs_in_vg(struct cmd_context *cmd,
if ((lv->status & SNAPSHOT) || lv_is_cow(lv))
continue;
/* Can't deactive a pvmove or log LV */
/* Only request activation of mirror LV */
if ((lv->status & MIRROR_IMAGE) || (lv->status & MIRROR_LOG))
continue;
/* Can't deactivate a pvmove LV */
/* FIXME There needs to be a controlled way of doing this */
if (((activate == CHANGE_AN) || (activate == CHANGE_ALN)) &&
((lv->status & PVMOVE) || (lv->status & MIRROR_LOG)))
((lv->status & PVMOVE) ))
continue;
if (activate == CHANGE_AN) {

View File

@@ -112,7 +112,7 @@ static int vgconvert_single(struct cmd_context *cmd, const char *vg_name,
+ pe_start - 1;
list_init(&mdas);
if (!(pv = pv_create(cmd->fmt, pv_dev(existing_pv),
if (!(pv = pv_create(cmd, pv_dev(existing_pv),
&existing_pv->id, size,
pe_start, pv_pe_count(existing_pv),
pv_pe_size(existing_pv), pvmetadatacopies,

View File

@@ -113,5 +113,5 @@ int vgdisplay(struct cmd_context *cmd, int argc, char **argv)
}
************/
return 0;
return ECMD_PROCESSED;
}

View File

@@ -49,12 +49,14 @@ static int _vgmerge_single(struct cmd_context *cmd, const char *vg_name_to,
if (!archive(vg_from) || !archive(vg_to))
goto_bad;
drop_cached_metadata(vg_from);
/* Merge volume groups */
while (!list_empty(&vg_from->pvs)) {
struct list *pvh = vg_from->pvs.n;
struct physical_volume *pv;
list_move(pvh, &vg_to->pvs);
list_move(&vg_to->pvs, pvh);
pv = list_item(pvh, struct pv_list)->pv;
pv->vg_name = dm_pool_strdup(cmd->mem, vg_to->name);
@@ -89,16 +91,17 @@ static int _vgmerge_single(struct cmd_context *cmd, const char *vg_name_to,
while (!list_empty(&vg_from->lvs)) {
struct list *lvh = vg_from->lvs.n;
list_move(lvh, &vg_to->lvs);
list_move(&vg_to->lvs, lvh);
}
while (!list_empty(&vg_from->fid->metadata_areas)) {
struct list *mdah = vg_from->fid->metadata_areas.n;
list_move(mdah, &vg_to->fid->metadata_areas);
list_move(&vg_to->fid->metadata_areas, mdah);
}
vg_to->lv_count += vg_from->lv_count;
vg_to->snapshot_count += vg_from->snapshot_count;
vg_to->extent_count += vg_from->extent_count;
vg_to->free_count += vg_from->free_count;

View File

@@ -28,7 +28,7 @@ static int vg_rename_path(struct cmd_context *cmd, const char *old_vg_path,
char *vg_name_new;
const char *vgid = NULL, *vg_name, *vg_name_old;
char old_path[NAME_LEN], new_path[NAME_LEN];
struct volume_group *vg_old, *vg_new;
struct volume_group *vg, *vg_new;
vg_name_old = skip_dev_dir(cmd, old_vg_path, NULL);
vg_name_new = skip_dev_dir(cmd, new_vg_path, NULL);
@@ -75,22 +75,22 @@ static int vg_rename_path(struct cmd_context *cmd, const char *old_vg_path,
return 0;
}
if (!(vg_old = vg_read(cmd, vg_name_old, vgid, &consistent)) || !consistent) {
if (!(vg = vg_read(cmd, vg_name_old, vgid, &consistent)) || !consistent) {
log_error("Volume group %s %s%s%snot found.", vg_name_old,
vgid ? "(" : "", vgid ? vgid : "", vgid ? ") " : "");
unlock_vg(cmd, vg_name_old);
return 0;
}
if (!vg_check_status(vg_old, CLUSTERED | LVM_WRITE)) {
if (!vg_check_status(vg, CLUSTERED | LVM_WRITE)) {
unlock_vg(cmd, vg_name_old);
return 0;
}
/* Don't return failure for EXPORTED_VG */
vg_check_status(vg_old, EXPORTED_VG);
vg_check_status(vg, EXPORTED_VG);
if (lvs_in_vg_activated_by_uuid_only(vg_old)) {
if (lvs_in_vg_activated_by_uuid_only(vg)) {
unlock_vg(cmd, vg_name_old);
log_error("Volume group \"%s\" still has active LVs",
vg_name_old);
@@ -113,16 +113,19 @@ static int vg_rename_path(struct cmd_context *cmd, const char *old_vg_path,
goto error;
}
if (!archive(vg_old))
if (!archive(vg))
goto error;
/* Remove references based on old name */
drop_cached_metadata(vg);
/* Change the volume group name */
vg_rename(cmd, vg_old, vg_name_new);
vg_rename(cmd, vg, vg_name_new);
sprintf(old_path, "%s%s", dev_dir, vg_name_old);
sprintf(new_path, "%s%s", dev_dir, vg_name_new);
if (dir_exists(old_path)) {
if (activation() && dir_exists(old_path)) {
log_verbose("Renaming \"%s\" to \"%s\"", old_path, new_path);
if (test_mode())
log_verbose("Test mode: Skipping rename.");
@@ -135,13 +138,13 @@ static int vg_rename_path(struct cmd_context *cmd, const char *old_vg_path,
/* store it on disks */
log_verbose("Writing out updated volume group");
if (!vg_write(vg_old) || !vg_commit(vg_old)) {
if (!vg_write(vg) || !vg_commit(vg)) {
goto error;
}
/******* FIXME Rename any active LVs! *****/
backup(vg_old);
backup(vg);
unlock_vg(cmd, vg_name_new);
unlock_vg(cmd, vg_name_old);

View File

@@ -28,7 +28,7 @@ static int _move_pv(struct volume_group *vg_from, struct volume_group *vg_to,
return 0;
}
list_move(&pvl->list, &vg_to->pvs);
list_move(&vg_to->pvs, &pvl->list);
vg_from->pv_count--;
vg_to->pv_count++;
@@ -94,18 +94,22 @@ static int _lv_is_in_vg(struct volume_group *vg, struct logical_volume *lv)
}
static int _move_one_lv(struct volume_group *vg_from,
struct volume_group *vg_to,
struct list *lvh)
struct volume_group *vg_to,
struct list *lvh)
{
struct logical_volume *lv;
struct logical_volume *lv = list_item(lvh, struct lv_list)->lv;
lv = list_item(lvh, struct lv_list)->lv;
list_move(lvh, &vg_to->lvs);
list_move(&vg_to->lvs, lvh);
if (lv_is_active(lv)) {
log_error("Logical volume \"%s\" must be inactive", lv->name);
return 0;
}
if (lv->status & SNAPSHOT) {
vg_from->snapshot_count--;
vg_to->snapshot_count++;
} else {
} else if (!lv_is_cow(lv)) {
vg_from->lv_count--;
vg_to->lv_count++;
}
@@ -171,7 +175,7 @@ static int _move_lvs(struct volume_group *vg_from, struct volume_group *vg_to)
/* Move this LV */
if (!_move_one_lv(vg_from, vg_to, lvh))
return 0;
return_0;
}
/* FIXME Ensure no LVs contain segs pointing at LVs in the other VG */
@@ -217,7 +221,7 @@ static int _move_snapshots(struct volume_group *vg_from,
if (_lv_is_in_vg(vg_to, seg->cow) &&
_lv_is_in_vg(vg_to, seg->origin)) {
if (!_move_one_lv(vg_from, vg_to, lvh))
return 0;
return_0;
}
}
@@ -259,7 +263,7 @@ static int _move_mirrors(struct volume_group *vg_from,
if (seg_in == seg->area_count && log_in) {
if (!_move_one_lv(vg_from, vg_to, lvh))
return 0;
return_0;
}
}
@@ -284,7 +288,6 @@ int vgsplit(struct cmd_context *cmd, int argc, char **argv)
char *vg_name_from, *vg_name_to;
struct volume_group *vg_to, *vg_from;
int opt;
int active;
int existing_vg;
int consistent;
const char *lv_name;
@@ -323,14 +326,6 @@ int vgsplit(struct cmd_context *cmd, int argc, char **argv)
CORRECT_INCONSISTENT | FAIL_INCONSISTENT)))
return ECMD_FAILED;
if ((active = lvs_in_vg_activated(vg_from))) {
/* FIXME Remove this restriction */
log_error("Logical volumes in \"%s\" must be inactive",
vg_name_from);
unlock_vg(cmd, vg_name_from);
return ECMD_FAILED;
}
log_verbose("Checking for new volume group \"%s\"", vg_name_to);
if (!lock_vol(cmd, vg_name_to, LCK_VG_WRITE | LCK_NONBLOCK)) {
log_error("Can't get lock for %s", vg_name_to);
@@ -344,10 +339,10 @@ int vgsplit(struct cmd_context *cmd, int argc, char **argv)
if (new_vg_option_specified(cmd)) {
log_error("Volume group \"%s\" exists, but new VG "
"option specified", vg_name_to);
goto bad;
goto_bad;
}
if (!vgs_are_compatible(cmd, vg_from,vg_to))
goto bad;
goto_bad;
} else {
existing_vg = 0;
@@ -377,7 +372,7 @@ int vgsplit(struct cmd_context *cmd, int argc, char **argv)
if (!(vg_to = vg_create(cmd, vg_name_to, vp_new.extent_size,
vp_new.max_pv, vp_new.max_lv,
vp_new.alloc, 0, NULL)))
goto bad;
goto_bad;
if (vg_is_clustered(vg_from))
vg_to->status |= CLUSTERED;
@@ -385,41 +380,39 @@ int vgsplit(struct cmd_context *cmd, int argc, char **argv)
/* Archive vg_from before changing it */
if (!archive(vg_from))
goto bad;
goto_bad;
/* Move PVs across to new structure */
for (opt = 0; opt < argc; opt++) {
if (!_move_pv(vg_from, vg_to, argv[opt]))
goto bad;
goto_bad;
}
/* If an LV given on the cmdline, move used_by PVs */
if (lv_name) {
if (!_move_pvs_used_by_lv(vg_from, vg_to, lv_name))
goto bad;
}
if (lv_name && !_move_pvs_used_by_lv(vg_from, vg_to, lv_name))
goto_bad;
/* Move required LVs across, checking consistency */
if (!(_move_lvs(vg_from, vg_to)))
goto bad;
goto_bad;
/* Move required snapshots across */
if (!(_move_snapshots(vg_from, vg_to)))
goto bad;
goto_bad;
/* Move required mirrors across */
if (!(_move_mirrors(vg_from, vg_to)))
goto bad;
goto_bad;
/* Split metadata areas and check if both vgs have at least one area */
if (!(vg_split_mdas(cmd, vg_from, vg_to)) && vg_from->pv_count) {
log_error("Cannot split: Nowhere to store metadata for new Volume Group");
goto bad;
goto_bad;
}
/* Set proper name for all PVs in new VG */
if (!vg_rename(cmd, vg_to, vg_name_to))
goto bad;
goto_bad;
/* store it on disks */
log_verbose("Writing out updated volume groups");
@@ -434,21 +427,21 @@ int vgsplit(struct cmd_context *cmd, int argc, char **argv)
vg_to->status |= EXPORTED_VG;
if (!archive(vg_to))
goto bad;
goto_bad;
if (!vg_write(vg_to) || !vg_commit(vg_to))
goto bad;
goto_bad;
backup(vg_to);
/*
* Next, write out the updated old VG. If we crash after this point,
* recovery is a vgimport on the new VG.
* FIXME: recover automatically or instruct the user the user?
* FIXME: recover automatically or instruct the user?
*/
if (vg_from->pv_count) {
if (!vg_write(vg_from) || !vg_commit(vg_from))
goto bad;
goto_bad;
backup(vg_from);
}
@@ -458,17 +451,17 @@ int vgsplit(struct cmd_context *cmd, int argc, char **argv)
*/
consistent = 1;
if (!test_mode() &&
(!(vg_to = vg_read(cmd, vg_name_to, NULL, &consistent))
|| !consistent)) {
(!(vg_to = vg_read(cmd, vg_name_to, NULL, &consistent)) ||
!consistent)) {
log_error("Volume group \"%s\" became inconsistent: please "
"fix manually", vg_name_to);
goto bad;
goto_bad;
}
vg_to->status &= ~EXPORTED_VG;
if (!vg_write(vg_to) || !vg_commit(vg_to))
goto bad;
goto_bad;
backup(vg_to);