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

Compare commits

...

196 Commits

Author SHA1 Message Date
Alasdair Kergon
075b4bef3f pre-release 2008-04-10 18:19:49 +00:00
Alasdair Kergon
b59fce4393 post-release 2008-04-10 18:04:31 +00:00
Alasdair Kergon
8674a25eb8 pre-release 2008-04-10 18:00:45 +00:00
Alasdair Kergon
10bf8fd2cd Fix vgdisplay 'Cur LV' field to match lvdisplay output.
Fix lv_count report field to exclude hidden LVs.
2008-04-10 17:19:02 +00:00
Dave Wysochanski
57cb22ff3c Add vg_is_clustered() helper function.
Should be no functional change.
2008-04-10 17:09:32 +00:00
Dave Wysochanski
0162abdcae Minor vgsplit cleanups. 2008-04-10 02:15:56 +00:00
Dave Wysochanski
5801171518 Add _move_one_lv() helper function for vgsplit. 2008-04-10 01:30:22 +00:00
Dave Wysochanski
bf1edbd1e2 Fix lvm tool exit code display in some tests. 2008-04-10 01:06:48 +00:00
Dave Wysochanski
a8484d987d Add vgsplit tests to verify mirror is not moved unnecessarily. 2008-04-09 21:10:13 +00:00
Dave Wysochanski
9b2147f608 Fix vgsplit to only move hidden 'snapshotN' LVs when necessary.
This bug has been around for a long time as far as I can tell.
Without this fix, a vgsplit would unconditionally move the
'hidden/internal' snapshot LVs, and result in corrupted metadata
in the following case:
vg1: contains lv1, lv1snap, both on pvset1
vg1: contains lv2, on pvset2

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

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

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

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

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

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

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

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

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

View File

@@ -1 +1 @@
2.02.29-cvs (2007-08-24)
2.02.34-cvs (2008-04-10)

129
WHATS_NEW
View File

@@ -1,5 +1,122 @@
Version 2.02.29 -
==================================
Version 2.02.34 - 10th April 2008
=================================
Fix vgdisplay 'Cur LV' field to match lvdisplay output.
Fix lv_count report field to exclude hidden LVs.
Add vg_is_clustered() helper function.
Fix vgsplit to only move hidden 'snapshotN' LVs when necessary.
Update vgsplit tests for lvnames on the cmdline.
Update vgsplit man page to reflect lvnames on the cmdline.
Update vgsplit to take "-n LogicalVolumeName" on the cmdline.
Use clustered mirror log with pvmove in clustered VGs, if available.
Fix some pvmove error status codes.
Fix vgsplit error paths to release vg_to lock.
Indicate whether or not VG is clustered in vgcreate log message.
Mention default --clustered setting in vgcreate man page.
Add config file overrides to clvmd when it reads the active LVs list.
Fix vgreduce to use vg_split_mdas to check sufficient mdas remain.
Add (empty) orphan VGs to lvmcache during initialisation.
Fix orphan VG name used for format_pool.
Create a fid for internal orphan VGs.
Update lvmcache VG lock state for all locking types now.
Fix output if overriding command_names on cmdline.
Add detection of clustered mirror log capability.
Add check to vg_commit() ensuring VG lock held before writing new VG metadata.
Add validation of LV name to pvmove -n.
Make clvmd refresh the context correctly when lvm.conf is updated.
Add some basic internal VG lock validation.
Add per-command flags to control which commands use the VG metadata cache.
Fix vgsplit locking of new VG (2.02.30).
Avoid erroneous vgsplit error message for new VG. (2.02.29)
Suppress duplicate message when lvresize fails because of invalid vgname.
Cache VG metadata internally while VG lock is held.
Fix redundant lvresize message if vg doesn't exist.
Fix another allocation bug with clvmd and large node IDs.
Add find_lv_in_lv_list() and find_pv_in_pv_list().
Fix uninitialised variable in clvmd that could cause odd hangs.
Add vgmerge tests.
Add pvseg_is_allocated() for identifying a PV segment allocated to a LV.
Add list_move() for moving elements from one list to another.
Add 'is_reserved_lvname()' for identifying hidden LVs.
Correct command name in lvmdiskscan man page.
clvmd no longer crashes if it sees nodeids over 50.
Fix potential deadlock in clvmd thread handling.
Refactor text format initialisation into _init_text_import.
Escape double quotes and backslashes in external metadata and config data.
Add functions for escaping double quotes in strings.
Rename count_chars_len to count_chars.
Use return_0 in a couple more places.
Correct a function name typo in _line_append error message.
Include limits.h in clvmd so it compiles with newer headers.
Add VirtIO disks (virtblk) to filters.
Fix resetting of MIRROR_IMAGE and VISIBLE_LV after removal of LV. (2.02.30)
Fix remove_layer_from_lv to empty the LV before removing it. (2.02.30)
Add missing no-longer-used segs_using_this_lv test to check_lv_segments.
Remove redundant non-NULL tests before calling free in clvmd.c.
Avoid a compiler warning: make is_orphan's parameter const.
Fix lvconvert detection of mirror conversion in progress. (2.02.30)
Avoid automatic lvconvert polldaemon invocation when -R specified. (2.02.30)
Fix 'pvs -a' to detect VGs of PVs without metadata areas.
Divide up internal orphan volume group by format type.
Update usage message for clvmd.
Fix clvmd man page not to print <br> and clarified debug options.
Fix lvresize to support /dev/mapper prefix in the LV name.
Fix unfilled parameter passed to fsadm from lvresize.
Update fsadm to call lvresize if the partition size differs (with option -l).
Fix fsadm to support VG/LV names.
Version 2.02.33 - 31st January 2008
===================================
Fix mirror log name construction during lvconvert. (2.02.30)
Make monitor_dev_for_events recurse through the stack of LVs.
Clean up some more compiler warnings.
Some whitespace tidy-ups.
Use stack return macros throughout.
Rely upon internally-cached PV labels while corresponding VG lock is held.
Version 2.02.32 - 29th January 2008
===================================
Fix two check_lv_segments error messages to show whole segment.
Refactor mirror log attachment code.
Fix internal metadata corruption in lvchange --resync. (2.02.30)
Fix new parameter validation in vgsplit and test mode. (2.02.30)
Remove redundant cnxman-socket.h file from clvmd directory.
Fix pvs, vgs, lvs error exit status on some error paths.
Version 2.02.31 - 19th January 2008
===================================
Fix lvcreate --nosync not to wait for non-happening sync. (2.02.30)
Add very_verbose lvconvert messages.
Avoid readahead error message with default setting of lvcreate -M1. (2.02.29)
Version 2.02.30 - 17th January 2008
===================================
Set default readahead to twice maximium stripe size.
Reinstate VG extent size and stripe size defaults (halved). (2.02.29)
Add lists of stacked LV segments using each LV to the internal metadata.
Change vgsplit -l (for unimplemented --list) into --maxlogicalvolumes.
Fix process_all_pvs to detect non-orphans with no MDAs correctly.
Don't use block_on_error with mirror targets version 1.12 and above.
Update vgsplit to accept vgcreate options when new VG is destination.
Update vgsplit to accept existing VG as destination.
lvconvert waits for completion of initial sync by default.
Refactor vgcreate for parameter validation and add tests.
Add new convert_lv field to lvs output.
Print warning when lvm tools are running as non-root.
Add snapshot dmeventd library (enables dmeventd snapshot monitoring).
Prevent pvcreate from overwriting MDA-less PVs belonging to active VGs.
Fix a segfault if using pvs with --all argument. (2.02.29)
Update --uuid argument description in man pages.
Fix vgreduce PV list processing not to process every PV in the VG. (2.02.29)
Extend lvconvert to use polldaemon.
Add support for stacked mirrors.
Major restructuring of pvmove and lvconvert layer manipulation code.
Replace tools/fsadm with scripts/fsadm.sh.
Append fields to report/pvsegs_cols_verbose.
Permit LV segment fields with PV segment reports.
Add seg_start_pe and seg_pe_ranges to reports.
Version 2.02.29 - 5th December 2007
===================================
Make clvmd backup vg metadata on remote nodes.
Refactor pvmove allocation code.
Decode cluster locking state in log message.
@@ -36,14 +153,16 @@ Version 2.02.29 -
Add const attributes to pv accessor functions.
Refactor vg_add_snapshot() and lv_create_empty().
Handle new sysfs subsystem/block/devices directory structure.
Tests are run with LVM_SYSTEM_DIR pointing to private root and /dev dirs.
Run test with LVM_SYSTEM_DIR pointing to private root and /dev dirs.
Fix a bug in lvm_dump.sh checks for lvm/dmsetup binaries.
Fix underquotations in lvm_dump.sh.
Refactor lvcreate stripe and mirror parameter validation.
All tools: print --help output to stdout, not stderr.
After a diagnostic, suggest --help, rather than printing all --help output.
Print --help output to stdout, not stderr.
After a cmdline processing error, don't print help text but suggest --help.
Add %PVS extents option to lvresize, lvextend, and lvcreate.
Add 'make check' to run tests in new subdirectory 'test'.
Moved the obsolete test subdirectory to old-tests.
Cope with relative paths in configure --with-dmdir.
Remove no-longer-correct restrictions on PV arg count with stripes/mirrors.
Fix strdup memory leak in str_list_dup().
Link with -lpthread when static SELinux libraries require that.

View File

@@ -1,10 +1,27 @@
Version 1.02.26 -
=================================
Version 1.02.25 - 10th April 2008
=================================
Remove redundant if-before-free tests.
Use log_warn for reporting field help text instead of log_print.
Change cluster mirror log type name (s/clustered_/clustered-/)
Version 1.02.24 - 20th December 2007
====================================
Fix deptree to pass new name to _resume_node after a rename.
Suppress other node operations if node is deleted.
Add node operation stack debug messages.
Report error when empty device name passed to readahead functions.
Fix minimum readahead debug message.
Version 1.02.23 - 5th December 2007
===================================
Update dm-ioctl.h after removal of compat code.
Add readahead support to libdevmapper and dmsetup.
Fix double free in a libdevmapper-event error path.
Fix configure --with-dmeventd-path substitution.
Allow a DM_DEV_DIR environment variable to override /dev.
Allow a DM_DEV_DIR environment variable to override /dev in dmsetup.
Create a libdevmapper.so.$LIB_VERSION symlink within the build tree.
Avoid static link failure with some SELinux libraries that require libpthread.
Remove obsolete dmfs code from tree and update INSTALL.
@@ -22,7 +39,7 @@ Version 1.02.22 - 21st August 2007
Version 1.02.21 - 13th July 2007
================================
Introduce _LOG_STDERR to send log_warn() messages to stderr not stdout.
Fix dmsetup -o devno string termination. (1.02.20)
Fix dmsetup -o devno string termination. (1.02.20)
Version 1.02.20 - 15th June 2007
================================
@@ -310,4 +327,3 @@ Version 1.00.08 - 27 Feb 2004
Fixed DESTDIR for make install/install_static_lib.
Updated README/INSTALL to reflect move to sources.redhat.com.
Updated autoconf files to 2003-06-17.

4330
configure vendored

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
##
## Copyright (C) 2000-2004 Sistina Software, Inc. All rights reserved.
## Copyright (C) 2004, 2007 Red Hat, Inc. All rights reserved.
## Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
##
## This file is part of LVM2.
##
@@ -363,7 +363,7 @@ AC_MSG_RESULT($CMDLIB)
################################################################################
dnl -- Enable fsadm
AC_MSG_CHECKING(whether to build fsadm)
AC_MSG_CHECKING(whether to install fsadm)
AC_ARG_ENABLE(fsadm, [ --enable-fsadm Enable fsadm],
FSADM=$enableval)
AC_MSG_RESULT($FSADM)
@@ -558,11 +558,6 @@ if test x$CLVMD != xnone; then
AC_FUNC_SELECT_ARGTYPES
fi
if test x$FSADM = xyes; then
AC_CHECK_HEADERS(fstab.h sys/mount.h sys/vfs.h,,AC_MSG_ERROR(bailing out))
AC_CHECK_FUNCS(memmove,,AC_MSG_ERROR(bailing out))
fi
if test x$CLUSTER != xnone; then
AC_CHECK_HEADERS(sys/socket.h sys/un.h,,AC_MSG_ERROR(bailing out))
AC_CHECK_FUNCS(socket,,AC_MSG_ERROR(bailing out))
@@ -647,6 +642,7 @@ daemons/Makefile
daemons/clvmd/Makefile
dmeventd/Makefile
dmeventd/mirror/Makefile
dmeventd/snapshot/Makefile
doc/Makefile
include/Makefile
lib/Makefile
@@ -661,7 +657,6 @@ po/Makefile
scripts/Makefile
tools/Makefile
tools/version.h
tools/fsadm/Makefile
])
AC_OUTPUT

View File

@@ -241,7 +241,7 @@ static void _add_up_node(const char *csid)
if (nodeid >= max_updown_nodes) {
int new_size = nodeid + 10;
int *new_updown = realloc(node_updown, new_size);
int *new_updown = realloc(node_updown, sizeof(int) * new_size);
if (new_updown) {
node_updown = new_updown;
@@ -297,6 +297,8 @@ static void get_members()
{
int retnodes;
int status;
int i;
int high_nodeid = 0;
num_nodes = cman_get_node_count(c_handle);
if (num_nodes == -1) {
@@ -325,8 +327,17 @@ static void get_members()
exit(6);
}
/* Get the highest nodeid */
for (i=0; i<retnodes; i++) {
if (nodes[i].cn_nodeid > high_nodeid)
high_nodeid = nodes[i].cn_nodeid;
}
if (node_updown == NULL) {
size_t buf_len = sizeof(int) * max(num_nodes, max_updown_nodes);
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

@@ -37,6 +37,7 @@
#include <getopt.h>
#include <syslog.h>
#include <errno.h>
#include <limits.h>
#include <libdlm.h>
#include "clvmd-comms.h"
@@ -146,8 +147,10 @@ static void usage(char *prog, FILE *file)
fprintf(file, "\n");
fprintf(file, " -V Show version of clvmd\n");
fprintf(file, " -h Show this help information\n");
fprintf(file, " -d Don't fork, run in the foreground\n");
fprintf(file, " -d Set debug level\n");
fprintf(file, " If starting clvmd then don't fork, run in the foreground\n");
fprintf(file, " -R Tell all running clvmds in the cluster to reload their device cache\n");
fprintf(file, " -C Sets debug level (from -d) on all clvmd instances clusterwide\n");
fprintf(file, " -t<secs> Command timeout (default 60 seconds)\n");
fprintf(file, " -T<secs> Startup timeout (default none)\n");
fprintf(file, "\n");
@@ -630,7 +633,7 @@ static void main_loop(int local_sock, int cmd_timeout)
}
if (FD_ISSET(thisfd->fd, &in)) {
struct local_client *newfd;
struct local_client *newfd = NULL;
int ret;
/* Do callback */
@@ -901,8 +904,7 @@ static int read_from_local_sock(struct local_client *thisfd)
}
/* Free the command buffer */
if (thisfd->bits.localsock.cmd)
free(thisfd->bits.localsock.cmd);
free(thisfd->bits.localsock.cmd);
/* Clear out the cross-link */
if (thisfd->bits.localsock.pipe_client != NULL)
@@ -937,8 +939,7 @@ static int read_from_local_sock(struct local_client *thisfd)
}
/* Free any old buffer space */
if (thisfd->bits.localsock.cmd)
free(thisfd->bits.localsock.cmd);
free(thisfd->bits.localsock.cmd);
/* See if we have the whole message */
argslen =
@@ -1415,7 +1416,8 @@ next_pre:
DEBUGLOG("Waiting for next pre command\n");
pthread_mutex_lock(&client->bits.localsock.mutex);
if (client->bits.localsock.state != PRE_COMMAND) {
if (client->bits.localsock.state != PRE_COMMAND &&
!client->bits.localsock.finished) {
pthread_cond_wait(&client->bits.localsock.cond,
&client->bits.localsock.mutex);
}
@@ -1545,8 +1547,7 @@ static void send_local_reply(struct local_client *client, int status, int fd)
}
thisreply = thisreply->next;
if (tempreply->replymsg)
free(tempreply->replymsg);
free(tempreply->replymsg);
free(tempreply);
}
@@ -1577,8 +1578,7 @@ static void free_reply(struct local_client *client)
thisreply = thisreply->next;
if (tempreply->replymsg)
free(tempreply->replymsg);
free(tempreply->replymsg);
free(tempreply);
}
client->bits.localsock.replies = NULL;
@@ -1613,7 +1613,7 @@ static void send_version_message()
static int send_message(void *buf, int msglen, const char *csid, int fd,
const char *errtext)
{
int len;
int len = 0;
int saved_errno = 0;
struct timespec delay;
struct timespec remtime;
@@ -1730,8 +1730,7 @@ static __attribute__ ((noreturn)) void *lvm_thread_fn(void *arg)
pthread_mutex_unlock(&lvm_thread_mutex);
process_work_item(cmd);
if (cmd->msg)
free(cmd->msg);
free(cmd->msg);
free(cmd);
pthread_mutex_lock(&lvm_thread_mutex);
@@ -1824,8 +1823,9 @@ static int open_local_sock()
log_error("Can't create local socket: %m");
return -1;
}
/* Set Close-on-exec */
/* Set Close-on-exec & non-blocking */
fcntl(local_socket, F_SETFD, 1);
fcntl(local_socket, F_SETFL, fcntl(local_socket, F_GETFL, 0) | O_NONBLOCK);
memset(&sockaddr, 0, sizeof(sockaddr));
memcpy(sockaddr.sun_path, CLVMD_SOCKNAME, sizeof(CLVMD_SOCKNAME));

View File

@@ -1,226 +0,0 @@
/******************************************************************************
*******************************************************************************
**
** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
** Copyright (C) 2004 Red Hat, Inc. All rights reserved.
**
** This copyrighted material is made available to anyone wishing to use,
** modify, copy, or redistribute it subject to the terms and conditions
** of the GNU General Public License v.2.
**
*******************************************************************************
******************************************************************************/
/* CMAN socket interface header,
may be include by user or kernel code */
#ifndef __CNXMAN_SOCKET_H
#define __CNXMAN_SOCKET_H
/* A currently unused number. TIPC also uses this number and you're unlikely
to be using both.
*/
#define AF_CLUSTER 30
#define PF_CLUSTER AF_CLUSTER
/* Protocol(socket) types */
#define CLPROTO_MASTER 2
#define CLPROTO_CLIENT 3
/* ioctls -- should register these properly */
#define SIOCCLUSTER_NOTIFY _IOW('x', 0x01, int)
#define SIOCCLUSTER_REMOVENOTIFY _IO( 'x', 0x02)
#define SIOCCLUSTER_GETMEMBERS _IOR('x', 0x03, struct cl_cluster_nodelist)
#define SIOCCLUSTER_SETEXPECTED_VOTES _IOW('x', 0x04, int)
#define SIOCCLUSTER_ISQUORATE _IO( 'x', 0x05)
#define SIOCCLUSTER_ISLISTENING _IOW('x', 0x06, struct cl_listen_request)
#define SIOCCLUSTER_GETALLMEMBERS _IOR('x', 0x07, struct cl_cluster_nodelist)
#define SIOCCLUSTER_SET_VOTES _IOW('x', 0x08, int)
#define SIOCCLUSTER_GET_VERSION _IOR('x', 0x09, struct cl_version)
#define SIOCCLUSTER_SET_VERSION _IOW('x', 0x0a, struct cl_version)
#define SIOCCLUSTER_ISACTIVE _IO( 'x', 0x0b)
#define SIOCCLUSTER_KILLNODE _IOW('x', 0x0c, int)
#define SIOCCLUSTER_GET_JOINCOUNT _IO( 'x', 0x0d)
#define SIOCCLUSTER_SERVICE_REGISTER _IOW('x', 0x0e, char)
#define SIOCCLUSTER_SERVICE_UNREGISTER _IO('x', 0x0f)
#define SIOCCLUSTER_SERVICE_JOIN _IO( 'x', 0x10)
#define SIOCCLUSTER_SERVICE_LEAVE _IO( 'x', 0x20)
#define SIOCCLUSTER_SERVICE_SETSIGNAL _IOW('x', 0x30, int)
#define SIOCCLUSTER_SERVICE_STARTDONE _IOW('x', 0x40, unsigned int)
#define SIOCCLUSTER_SERVICE_GETEVENT _IOR('x', 0x50, struct cl_service_event)
#define SIOCCLUSTER_SERVICE_GETMEMBERS _IOR('x', 0x60, struct cl_cluster_nodelist)
#define SIOCCLUSTER_SERVICE_GLOBALID _IOR('x', 0x70, uint32_t)
#define SIOCCLUSTER_SERVICE_SETLEVEL _IOR('x', 0x80, int)
#define SIOCCLUSTER_GETNODE _IOWR('x', 0x90, struct cl_cluster_node)
#define SIOCCLUSTER_BARRIER _IOW('x', 0x0a0, struct cl_barrier_info)
/* These were setsockopts */
#define SIOCCLUSTER_PASS_SOCKET _IOW('x', 0x0b0, struct cl_passed_sock)
#define SIOCCLUSTER_SET_NODENAME _IOW('x', 0x0b1, char *)
#define SIOCCLUSTER_SET_NODEID _IOW('x', 0x0b2, int)
#define SIOCCLUSTER_JOIN_CLUSTER _IOW('x', 0x0b3, struct cl_join_cluster_info)
#define SIOCCLUSTER_LEAVE_CLUSTER _IOW('x', 0x0b4, int)
/* Maximum size of a cluster message */
#define CMAN_MAX_CLUSTER_MESSAGE 1500
#define CMAN_MAX_CLUSTER_MEMBER_NAME_LEN 255
#define MAX_BARRIER_NAME_LEN 33
#define MAX_SA_ADDR_LEN 12
#define MAX_CLUSTER_NAME_LEN 16
/* Well-known cluster port numbers */
#define CLUSTER_PORT_MEMBERSHIP 1 /* Mustn't block during cluster
* transitions! */
#define CLUSTER_PORT_SERVICES 2
#define CLUSTER_PORT_SYSMAN 10 /* Remote execution daemon */
#define CLUSTER_PORT_CLVMD 11 /* Cluster LVM daemon */
#define CLUSTER_PORT_SLM 12 /* LVM SLM (simple lock manager) */
/* Port numbers above this will be blocked when the cluster is inquorate or in
* transition */
#define HIGH_PROTECTED_PORT 9
/* Reasons for leaving the cluster */
#define CLUSTER_LEAVEFLAG_DOWN 0 /* Normal shutdown */
#define CLUSTER_LEAVEFLAG_KILLED 1
#define CLUSTER_LEAVEFLAG_PANIC 2
#define CLUSTER_LEAVEFLAG_REMOVED 3 /* This one can reduce quorum */
#define CLUSTER_LEAVEFLAG_REJECTED 4 /* Not allowed into the cluster in the
* first place */
#define CLUSTER_LEAVEFLAG_INCONSISTENT 5 /* Our view of the cluster is
* in a minority */
#define CLUSTER_LEAVEFLAG_DEAD 6 /* Discovered to be dead */
#define CLUSTER_LEAVEFLAG_FORCE 0x10 /* Forced by command-line */
/* OOB messages sent to a local socket */
#define CLUSTER_OOB_MSG_PORTCLOSED 1
#define CLUSTER_OOB_MSG_STATECHANGE 2
#define CLUSTER_OOB_MSG_SERVICEEVENT 3
/* Sendmsg flags, these are above the normal sendmsg flags so they don't
* interfere */
#define MSG_NOACK 0x010000 /* Don't need an ACK for this message */
#define MSG_QUEUE 0x020000 /* Queue the message for sending later */
#define MSG_MULTICAST 0x080000 /* Message was sent to all nodes in the cluster
*/
#define MSG_ALLINT 0x100000 /* Send out of all interfaces */
#define MSG_REPLYEXP 0x200000 /* Reply is expected */
typedef enum { NODESTATE_REMOTEMEMBER, NODESTATE_JOINING, NODESTATE_MEMBER,
NODESTATE_DEAD } nodestate_t;
struct sockaddr_cl {
unsigned short scl_family;
unsigned char scl_flags;
unsigned char scl_port;
int scl_nodeid;
};
/*
* This is how we pass the multicast & receive sockets into kernel space.
*/
struct cl_passed_sock {
int fd; /* FD of master socket to do multicast on */
int number; /* Socket number, to match up recvonly & bcast
* sockets */
int multicast; /* Is it multicast or receive ? */
};
/* Cluster configuration info passed when we join the cluster */
struct cl_join_cluster_info {
unsigned char votes;
unsigned int expected_votes;
unsigned int two_node;
unsigned int config_version;
char cluster_name[17];
};
/* This is the structure, per node, returned from the membership ioctl */
struct cl_cluster_node {
unsigned int size;
unsigned int node_id;
unsigned int us;
unsigned int leave_reason;
unsigned int incarnation;
nodestate_t state;
char name[CMAN_MAX_CLUSTER_MEMBER_NAME_LEN];
unsigned char votes;
};
/* The struct passed to the membership ioctls */
struct cl_cluster_nodelist {
uint32_t max_members;
struct cl_cluster_node *nodes;
};
/* Structure passed to SIOCCLUSTER_ISLISTENING */
struct cl_listen_request {
unsigned char port;
int nodeid;
};
/* A Cluster PORTCLOSED message - received by a local user as an OOB message */
struct cl_portclosed_oob {
unsigned char cmd; /* CLUSTER_OOB_MSG_PORTCLOSED */
unsigned char port;
};
/* Get all version numbers or set the config version */
struct cl_version {
unsigned int major;
unsigned int minor;
unsigned int patch;
unsigned int config;
};
/* structure passed to barrier ioctls */
struct cl_barrier_info {
char cmd;
char name[MAX_BARRIER_NAME_LEN];
unsigned int flags;
unsigned long arg;
};
typedef enum { SERVICE_EVENT_STOP, SERVICE_EVENT_START, SERVICE_EVENT_FINISH,
SERVICE_EVENT_LEAVEDONE } service_event_t;
typedef enum { SERVICE_START_FAILED, SERVICE_START_JOIN, SERVICE_START_LEAVE }
service_start_t;
struct cl_service_event {
service_event_t type;
service_start_t start_type;
unsigned int event_id;
unsigned int last_stop;
unsigned int last_start;
unsigned int last_finish;
unsigned int node_count;
};
/* Commands to the barrier ioctl */
#define BARRIER_IOCTL_REGISTER 1
#define BARRIER_IOCTL_CHANGE 2
#define BARRIER_IOCTL_DELETE 3
#define BARRIER_IOCTL_WAIT 4
/* Attributes of a barrier - bitmask */
#define BARRIER_ATTR_AUTODELETE 1
#define BARRIER_ATTR_MULTISTEP 2
#define BARRIER_ATTR_MANUAL 4
#define BARRIER_ATTR_ENABLED 8
#define BARRIER_ATTR_CALLBACK 16
/* Attribute setting commands */
#define BARRIER_SETATTR_AUTODELETE 1
#define BARRIER_SETATTR_MULTISTEP 2
#define BARRIER_SETATTR_ENABLED 3
#define BARRIER_SETATTR_NODES 4
#define BARRIER_SETATTR_CALLBACK 5
#define BARRIER_SETATTR_TIMEOUT 6
#endif

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -318,7 +318,7 @@ int do_lock_lv(unsigned char command, unsigned char lock_flags, char *resource)
pthread_mutex_lock(&lvm_lock);
if (!cmd->config_valid || config_files_changed(cmd)) {
/* Reinitialise various settings inc. logging, filters */
if (!refresh_toolcontext(cmd)) {
if (do_refresh_cache()) {
log_error("Updated config file invalid. Aborting.");
pthread_mutex_unlock(&lvm_lock);
return EINVAL;
@@ -437,7 +437,7 @@ int post_lock_lv(unsigned char command, unsigned char lock_flags,
return 0;
}
/* Check if a VG is un use by LVM1 so we don't stomp on it */
/* Check if a VG is in use by LVM1 so we don't stomp on it */
int do_check_lvm1(const char *vgname)
{
int status;
@@ -470,7 +470,7 @@ static void drop_vg_locks()
char line[255];
FILE *vgs =
popen
("lvm pvs --nolocking --noheadings -o vg_name", "r");
("lvm pvs --config 'log{command_names=0 prefix=\"\"}' --nolocking --noheadings -o vg_name", "r");
sync_unlock("P_orphans", LCK_EXCL);
@@ -511,7 +511,7 @@ static void *get_initial_state()
char line[255];
FILE *lvs =
popen
("lvm lvs --nolocking --noheadings -o vg_uuid,lv_uuid,lv_attr,vg_attr",
("lvm lvs --config 'log{command_names=0 prefix=\"\"}' --nolocking --noheadings -o vg_uuid,lv_uuid,lv_attr,vg_attr",
"r");
if (!lvs)

View File

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

View File

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

View File

@@ -125,8 +125,9 @@ out_parse:
return ME_IGNORE;
}
static void _temporary_log_fn(int level, const char *file,
int line, const char *format)
static void _temporary_log_fn(int level, const char *file __attribute((unused)),
int line __attribute((unused)),
const char *format)
{
if (!strncmp(format, "WARNING: ", 9) && (level < 5))
syslog(LOG_CRIT, "%s", format);
@@ -164,7 +165,8 @@ static int _remove_failed_devices(const char *device)
return (r == 1) ? 0 : -1;
}
void process_event(struct dm_task *dmt, enum dm_event_mask event,
void process_event(struct dm_task *dmt,
enum dm_event_mask event __attribute((unused)),
void **unused __attribute((unused)))
{
void *next = NULL;
@@ -222,8 +224,11 @@ void process_event(struct dm_task *dmt, enum dm_event_mask event,
pthread_mutex_unlock(&_event_mutex);
}
int register_device(const char *device, const char *uuid, int major, int minor,
void **unused __attribute((unused)))
int register_device(const char *device,
const char *uuid __attribute((unused)),
int major __attribute((unused)),
int minor __attribute((unused)),
void **unused __attribute((unused)))
{
int r = 0;
@@ -259,8 +264,11 @@ out:
return r;
}
int unregister_device(const char *device, const char *uuid, int major, int minor,
void **unused __attribute((unused)))
int unregister_device(const char *device,
const char *uuid __attribute((unused)),
int major __attribute((unused)),
int minor __attribute((unused)),
void **unused __attribute((unused)))
{
pthread_mutex_lock(&_register_mutex);

View File

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

View File

@@ -1,8 +1,8 @@
#
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
# Copyright (C) 2004 Red Hat, Inc. All rights reserved.
# Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
#
# This file is part of LVM2.
# This file is part of the LVM2.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
@@ -16,16 +16,21 @@ srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
SOURCES = fsadm.c
INCLUDES += -I${top_srcdir}/tools
CLDFLAGS += -L${top_srcdir}/tools -ldevmapper -llvm2cmd
TARGETS = fsadm
SOURCES = dmeventd_snapshot.c
ifeq ("@LIB_SUFFIX@","dylib")
LIB_SHARED = libdevmapper-event-lvm2snapshot.dylib
else
LIB_SHARED = libdevmapper-event-lvm2snapshot.so
endif
include $(top_srcdir)/make.tmpl
fsadm: $(OBJECTS)
$(CC) -o $@ $(CFLAGS) $(OBJECTS) -rdynamic
install: fsadm
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) fsadm \
$(sbindir)/fsadm
install: libdevmapper-event-lvm2snapshot.$(LIB_SUFFIX)
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \
$(libdir)/$<.$(LIB_VERSION)
$(LN_S) -f $<.$(LIB_VERSION) $(libdir)/$<

View File

@@ -0,0 +1,232 @@
/*
* Copyright (C) 2007-2008 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License v.2.1.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "libdevmapper.h"
#include "libdevmapper-event.h"
#include "lvm2cmd.h"
#include "lvm-string.h"
#include <errno.h>
#include <signal.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <syslog.h> /* FIXME Replace syslog with multilog */
/* FIXME Missing openlog? */
/* First warning when snapshot is 80% full. */
#define WARNING_THRESH 80
/* Further warnings at 85%, 90% and 95% fullness. */
#define WARNING_STEP 5
static pthread_mutex_t _register_mutex = PTHREAD_MUTEX_INITIALIZER;
/*
* Number of active registrations.
*/
static int _register_count = 0;
static struct dm_pool *_mem_pool = NULL;
static void *_lvm_handle = NULL;
struct snap_status {
int invalid;
int used;
int max;
};
/*
* Currently only one event can be processed at a time.
*/
static pthread_mutex_t _event_mutex = PTHREAD_MUTEX_INITIALIZER;
static void _temporary_log_fn(int level,
const char *file __attribute((unused)),
int line __attribute((unused)),
const char *format)
{
if (!strncmp(format, "WARNING: ", 9) && (level < 5))
syslog(LOG_CRIT, "%s", format);
else
syslog(LOG_DEBUG, "%s", format);
}
/* FIXME possibly reconcile this with target_percent when we gain
access to regular LVM library here. */
static void _parse_snapshot_params(char *params, struct snap_status *stat)
{
char *p;
/*
* xx/xx -- fractions used/max
* Invalid -- snapshot invalidated
* Unknown -- status unknown
*/
stat->used = stat->max = 0;
if (!strncmp(params, "Invalid", 7)) {
stat->invalid = 1;
return;
}
/*
* When we return without setting non-zero max, the parent is
* responsible for reporting errors.
*/
if (!strncmp(params, "Unknown", 7))
return;
if (!(p = strstr(params, "/")))
return;
*p = '\0';
p++;
stat->used = atoi(params);
stat->max = atoi(p);
}
/* send unregister command to itself */
static void _unregister_self(struct dm_task *dmt)
{
const char *name = dm_task_get_name(dmt);
struct dm_event_handler *dmevh;
if (!(dmevh = dm_event_handler_create()))
return;
if (dm_event_handler_set_dev_name(dmevh, name))
goto fail;
dm_event_handler_set_event_mask(dmevh, DM_EVENT_ALL_ERRORS|DM_EVENT_TIMEOUT);
dm_event_unregister_handler(dmevh);
fail:
dm_event_handler_destroy(dmevh);
}
void process_event(struct dm_task *dmt,
enum dm_event_mask event __attribute((unused)),
void **private)
{
void *next = NULL;
uint64_t start, length;
char *target_type = NULL;
char *params;
struct snap_status stat = { 0 };
const char *device = dm_task_get_name(dmt);
int percent, *percent_warning = (int*)private;
/* No longer monitoring, waiting for remove */
if (!*percent_warning)
return;
if (pthread_mutex_trylock(&_event_mutex)) {
syslog(LOG_NOTICE, "Another thread is handling an event. Waiting...");
pthread_mutex_lock(&_event_mutex);
}
dm_get_next_target(dmt, next, &start, &length, &target_type, &params);
if (!target_type)
goto out;
_parse_snapshot_params(params, &stat);
/*
* If the snapshot has been invalidated or we failed to parse
* the status string. Report the full status string to syslog.
*/
if (stat.invalid || !stat.max) {
syslog(LOG_ERR, "Snapshot %s changed state to: %s\n", device, params);
_unregister_self(dmt);
*percent_warning = 0;
goto out;
}
percent = 100 * stat.used / stat.max;
if (percent >= *percent_warning) {
syslog(LOG_WARNING, "Snapshot %s is now %i%% full.\n", device, percent);
/* Print warning on the next multiple of WARNING_STEP. */
*percent_warning = (percent / WARNING_STEP) * WARNING_STEP + WARNING_STEP;
}
out:
pthread_mutex_unlock(&_event_mutex);
}
int register_device(const char *device,
const char *uuid __attribute((unused)),
int major __attribute((unused)),
int minor __attribute((unused)),
void **private)
{
int r = 0;
int *percent_warning = (int*)private;
pthread_mutex_lock(&_register_mutex);
/*
* Need some space for allocations. 1024 should be more
* than enough for what we need (device mapper name splitting)
*/
if (!_mem_pool && !(_mem_pool = dm_pool_create("snapshot_dso", 1024)))
goto out;
*percent_warning = WARNING_THRESH; /* Print warning if snapshot is full */
if (!_lvm_handle) {
lvm2_log_fn(_temporary_log_fn);
if (!(_lvm_handle = lvm2_init())) {
dm_pool_destroy(_mem_pool);
_mem_pool = NULL;
goto out;
}
lvm2_log_level(_lvm_handle, LVM2_LOG_SUPPRESS);
/* FIXME Temporary: move to dmeventd core */
lvm2_run(_lvm_handle, "_memlock_inc");
}
syslog(LOG_INFO, "Monitoring snapshot %s\n", device);
_register_count++;
r = 1;
out:
pthread_mutex_unlock(&_register_mutex);
return r;
}
int unregister_device(const char *device,
const char *uuid __attribute((unused)),
int major __attribute((unused)),
int minor __attribute((unused)),
void **unused __attribute((unused)))
{
pthread_mutex_lock(&_register_mutex);
syslog(LOG_INFO, "No longer monitoring snapshot %s\n",
device);
if (!--_register_count) {
dm_pool_destroy(_mem_pool);
_mem_pool = NULL;
lvm2_run(_lvm_handle, "_memlock_dec");
lvm2_exit(_lvm_handle);
_lvm_handle = NULL;
}
pthread_mutex_unlock(&_register_mutex);
return 1;
}

View File

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

View File

@@ -125,8 +125,9 @@ out_parse:
return ME_IGNORE;
}
static void _temporary_log_fn(int level, const char *file,
int line, const char *format)
static void _temporary_log_fn(int level, const char *file __attribute((unused)),
int line __attribute((unused)),
const char *format)
{
if (!strncmp(format, "WARNING: ", 9) && (level < 5))
syslog(LOG_CRIT, "%s", format);
@@ -164,7 +165,8 @@ static int _remove_failed_devices(const char *device)
return (r == 1) ? 0 : -1;
}
void process_event(struct dm_task *dmt, enum dm_event_mask event,
void process_event(struct dm_task *dmt,
enum dm_event_mask event __attribute((unused)),
void **unused __attribute((unused)))
{
void *next = NULL;
@@ -222,8 +224,11 @@ void process_event(struct dm_task *dmt, enum dm_event_mask event,
pthread_mutex_unlock(&_event_mutex);
}
int register_device(const char *device, const char *uuid, int major, int minor,
void **unused __attribute((unused)))
int register_device(const char *device,
const char *uuid __attribute((unused)),
int major __attribute((unused)),
int minor __attribute((unused)),
void **unused __attribute((unused)))
{
int r = 0;
@@ -259,8 +264,11 @@ out:
return r;
}
int unregister_device(const char *device, const char *uuid, int major, int minor,
void **unused __attribute((unused)))
int unregister_device(const char *device,
const char *uuid __attribute((unused)),
int major __attribute((unused)),
int minor __attribute((unused)),
void **unused __attribute((unused)))
{
pthread_mutex_lock(&_register_mutex);

View File

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

View File

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

View File

@@ -0,0 +1,232 @@
/*
* Copyright (C) 2007-2008 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License v.2.1.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "libdevmapper.h"
#include "libdevmapper-event.h"
#include "lvm2cmd.h"
#include "lvm-string.h"
#include <errno.h>
#include <signal.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <syslog.h> /* FIXME Replace syslog with multilog */
/* FIXME Missing openlog? */
/* First warning when snapshot is 80% full. */
#define WARNING_THRESH 80
/* Further warnings at 85%, 90% and 95% fullness. */
#define WARNING_STEP 5
static pthread_mutex_t _register_mutex = PTHREAD_MUTEX_INITIALIZER;
/*
* Number of active registrations.
*/
static int _register_count = 0;
static struct dm_pool *_mem_pool = NULL;
static void *_lvm_handle = NULL;
struct snap_status {
int invalid;
int used;
int max;
};
/*
* Currently only one event can be processed at a time.
*/
static pthread_mutex_t _event_mutex = PTHREAD_MUTEX_INITIALIZER;
static void _temporary_log_fn(int level,
const char *file __attribute((unused)),
int line __attribute((unused)),
const char *format)
{
if (!strncmp(format, "WARNING: ", 9) && (level < 5))
syslog(LOG_CRIT, "%s", format);
else
syslog(LOG_DEBUG, "%s", format);
}
/* FIXME possibly reconcile this with target_percent when we gain
access to regular LVM library here. */
static void _parse_snapshot_params(char *params, struct snap_status *stat)
{
char *p;
/*
* xx/xx -- fractions used/max
* Invalid -- snapshot invalidated
* Unknown -- status unknown
*/
stat->used = stat->max = 0;
if (!strncmp(params, "Invalid", 7)) {
stat->invalid = 1;
return;
}
/*
* When we return without setting non-zero max, the parent is
* responsible for reporting errors.
*/
if (!strncmp(params, "Unknown", 7))
return;
if (!(p = strstr(params, "/")))
return;
*p = '\0';
p++;
stat->used = atoi(params);
stat->max = atoi(p);
}
/* send unregister command to itself */
static void _unregister_self(struct dm_task *dmt)
{
const char *name = dm_task_get_name(dmt);
struct dm_event_handler *dmevh;
if (!(dmevh = dm_event_handler_create()))
return;
if (dm_event_handler_set_dev_name(dmevh, name))
goto fail;
dm_event_handler_set_event_mask(dmevh, DM_EVENT_ALL_ERRORS|DM_EVENT_TIMEOUT);
dm_event_unregister_handler(dmevh);
fail:
dm_event_handler_destroy(dmevh);
}
void process_event(struct dm_task *dmt,
enum dm_event_mask event __attribute((unused)),
void **private)
{
void *next = NULL;
uint64_t start, length;
char *target_type = NULL;
char *params;
struct snap_status stat = { 0 };
const char *device = dm_task_get_name(dmt);
int percent, *percent_warning = (int*)private;
/* No longer monitoring, waiting for remove */
if (!*percent_warning)
return;
if (pthread_mutex_trylock(&_event_mutex)) {
syslog(LOG_NOTICE, "Another thread is handling an event. Waiting...");
pthread_mutex_lock(&_event_mutex);
}
dm_get_next_target(dmt, next, &start, &length, &target_type, &params);
if (!target_type)
goto out;
_parse_snapshot_params(params, &stat);
/*
* If the snapshot has been invalidated or we failed to parse
* the status string. Report the full status string to syslog.
*/
if (stat.invalid || !stat.max) {
syslog(LOG_ERR, "Snapshot %s changed state to: %s\n", device, params);
_unregister_self(dmt);
*percent_warning = 0;
goto out;
}
percent = 100 * stat.used / stat.max;
if (percent >= *percent_warning) {
syslog(LOG_WARNING, "Snapshot %s is now %i%% full.\n", device, percent);
/* Print warning on the next multiple of WARNING_STEP. */
*percent_warning = (percent / WARNING_STEP) * WARNING_STEP + WARNING_STEP;
}
out:
pthread_mutex_unlock(&_event_mutex);
}
int register_device(const char *device,
const char *uuid __attribute((unused)),
int major __attribute((unused)),
int minor __attribute((unused)),
void **private)
{
int r = 0;
int *percent_warning = (int*)private;
pthread_mutex_lock(&_register_mutex);
/*
* Need some space for allocations. 1024 should be more
* than enough for what we need (device mapper name splitting)
*/
if (!_mem_pool && !(_mem_pool = dm_pool_create("snapshot_dso", 1024)))
goto out;
*percent_warning = WARNING_THRESH; /* Print warning if snapshot is full */
if (!_lvm_handle) {
lvm2_log_fn(_temporary_log_fn);
if (!(_lvm_handle = lvm2_init())) {
dm_pool_destroy(_mem_pool);
_mem_pool = NULL;
goto out;
}
lvm2_log_level(_lvm_handle, LVM2_LOG_SUPPRESS);
/* FIXME Temporary: move to dmeventd core */
lvm2_run(_lvm_handle, "_memlock_inc");
}
syslog(LOG_INFO, "Monitoring snapshot %s\n", device);
_register_count++;
r = 1;
out:
pthread_mutex_unlock(&_register_mutex);
return r;
}
int unregister_device(const char *device,
const char *uuid __attribute((unused)),
int major __attribute((unused)),
int minor __attribute((unused)),
void **unused __attribute((unused)))
{
pthread_mutex_lock(&_register_mutex);
syslog(LOG_INFO, "No longer monitoring snapshot %s\n",
device);
if (!--_register_count) {
dm_pool_destroy(_mem_pool);
_mem_pool = NULL;
lvm2_run(_lvm_handle, "_memlock_dec");
lvm2_exit(_lvm_handle);
_lvm_handle = NULL;
}
pthread_mutex_unlock(&_register_mutex);
return 1;
}

View File

@@ -25,7 +25,9 @@ devices {
# list of regular expressions in turn and the first match is used.
preferred_names = [ ]
# preferred_names = [ "^/dev/mpath/", "^/dev/[hs]d" ]
# If device-mapper multipath is used, more descriptive names might
# be preferred over the dm-N names:
# preferred_names = [ "^/dev/mapper/mpath" ]
# A filter that tells LVM2 to only use a restricted set of devices.
# The filter consists of an array of regular expressions. These
@@ -384,10 +386,20 @@ activation {
# dmeventd {
# mirror_library is the library used when monitoring a mirror device.
#
# "libdevmapper-event-lvm2mirror.so" attempts to recover from failures.
# It removes failed devices from a volume group and reconfigures a
# mirror as necessary.
#
# "libdevmapper-event-lvm2mirror.so" attempts to recover from
# failures. It removes failed devices from a volume group and
# reconfigures a mirror as necessary. If no mirror library is
# provided, mirrors are not monitored through dmeventd.
# mirror_library = "libdevmapper-event-lvm2mirror.so"
# snapshot_library is the library used when monitoring a snapshot device.
#
# "libdevmapper-event-lvm2snapshot.so" monitors the filling of
# snapshots and emits a warning through syslog, when the use of
# snapshot exceedes 80%. The warning is repeated when 85%, 90% and
# 95% of the snapshot are filled.
# snapshot_library = "libdevmapper-event-lvm2snapshot.so"
#}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -391,12 +391,26 @@ int target_version(const char *target_name, uint32_t *maj,
return r;
}
int module_present(const char *target_name)
{
int ret = 0;
#ifdef MODPROBE_CMD
char module[128];
if (dm_snprintf(module, sizeof(module), "dm-%s", target_name) < 0) {
log_error("module_present module name too long: %s",
target_name);
return 0;
}
ret = exec_cmd(MODPROBE_CMD, module, "", "");
#endif
return ret;
}
int target_present(const char *target_name, int use_modprobe)
{
uint32_t maj, min, patchlevel;
#ifdef MODPROBE_CMD
char module[128];
#endif
if (!activation())
return 0;
@@ -406,14 +420,7 @@ int target_present(const char *target_name, int use_modprobe)
if (target_version(target_name, &maj, &min, &patchlevel))
return 1;
if (dm_snprintf(module, sizeof(module), "dm-%s", target_name)
< 0) {
log_error("target_present module name too long: %s",
target_name);
return 0;
}
if (!exec_cmd(MODPROBE_CMD, module, "", ""))
if (!module_present(target_name))
return_0;
}
#endif
@@ -508,6 +515,13 @@ int lv_mirror_percent(struct cmd_context *cmd, struct logical_volume *lv,
struct dev_manager *dm;
struct lvinfo info;
/* If mirrored LV is temporarily shrinked to 1 area (= linear),
* it should be considered in-sync. */
if (list_size(&lv->segments) == 1 && first_seg(lv)->area_count == 1) {
*percent = 100.0;
return 1;
}
if (!activation())
return 0;
@@ -669,9 +683,10 @@ int monitor_dev_for_events(struct cmd_context *cmd,
#ifdef DMEVENTD
int i, pending = 0, monitored;
int r = 1;
struct list *tmp;
struct list *tmp, *snh, *snht;
struct lv_segment *seg;
int (*monitor_fn) (struct lv_segment *s, int e);
uint32_t s;
/* skip dmeventd code altogether */
if (dmeventd_monitor_mode() == DMEVENTD_MONITOR_IGNORE)
@@ -683,9 +698,44 @@ int monitor_dev_for_events(struct cmd_context *cmd,
if (monitor && !dmeventd_monitor_mode())
return 1;
/*
* In case of a snapshot device, we monitor lv->snapshot->lv,
* not the actual LV itself.
*/
if (lv_is_cow(lv))
return monitor_dev_for_events(cmd, lv->snapshot->lv, monitor);
/*
* In case this LV is a snapshot origin, we instead monitor
* each of its respective snapshots (the origin itself does
* not need to be monitored).
*
* TODO: This may change when snapshots of mirrors are allowed.
*/
if (lv_is_origin(lv)) {
list_iterate_safe(snh, snht, &lv->snapshot_segs)
if (!monitor_dev_for_events(cmd, list_struct_base(snh,
struct lv_segment, origin_list)->cow, monitor))
r = 0;
return r;
}
list_iterate(tmp, &lv->segments) {
seg = list_item(tmp, struct lv_segment);
/* Recurse for AREA_LV */
for (s = 0; s < seg->area_count; s++) {
if (seg_type(seg, s) != AREA_LV)
continue;
if (!monitor_dev_for_events(cmd, seg_lv(seg, s),
monitor)) {
log_error("Failed to %smonitor %s",
monitor ? "" : "un",
seg_lv(seg, s)->name);
r = 0;
}
}
if (!seg_monitored(seg) || (seg->status & PVMOVE))
continue;

View File

@@ -30,6 +30,9 @@ struct lvinfo {
uint32_t read_ahead;
};
/* target attribute flags */
#define MIRROR_LOG_CLUSTERED 0x00000001U
void set_activation(int activation);
int activation(void);
@@ -37,6 +40,7 @@ int driver_version(char *version, size_t size);
int library_version(char *version, size_t size);
int lvm1_present(struct cmd_context *cmd);
int module_present(const char *target_name);
int target_present(const char *target_name, int use_modprobe);
int target_version(const char *target_name, uint32_t *maj,
uint32_t *min, uint32_t *patchlevel);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -100,10 +100,8 @@ static struct dm_task *_setup_task(const char *name, const char *uuid,
{
struct dm_task *dmt;
if (!(dmt = dm_task_create(task))) {
stack;
return NULL;
}
if (!(dmt = dm_task_create(task)))
return_NULL;
if (name)
dm_task_set_name(dmt, name);
@@ -127,10 +125,8 @@ static int _info_run(const char *name, const char *dlid, struct dm_info *info,
dmtask = mknodes ? DM_DEVICE_MKNODES : DM_DEVICE_INFO;
if (!(dmt = _setup_task(name, dlid, 0, dmtask))) {
stack;
return 0;
}
if (!(dmt = _setup_task(name, dlid, 0, dmtask)))
return_0;
if (!with_open_count)
if (!dm_task_no_open_count(dmt))
@@ -160,9 +156,9 @@ int device_is_usable(dev_t dev)
struct dm_task *dmt;
struct dm_info info;
const char *name;
uint64_t start, length;
char *target_type = NULL;
char *params;
uint64_t start, length;
char *target_type = NULL;
char *params;
void *next = NULL;
int r = 0;
@@ -190,13 +186,13 @@ int device_is_usable(dev_t dev)
/* FIXME Also check for mirror block_on_error and mpath no paths */
/* For now, we exclude all mirrors */
do {
next = dm_get_next_target(dmt, next, &start, &length,
&target_type, &params);
/* Skip if target type doesn't match */
if (target_type && !strcmp(target_type, "mirror"))
do {
next = dm_get_next_target(dmt, next, &start, &length,
&target_type, &params);
/* Skip if target type doesn't match */
if (target_type && !strcmp(target_type, "mirror"))
goto out;
} while (next);
} while (next);
/* FIXME Also check dependencies? */
@@ -259,10 +255,8 @@ static int _status_run(const char *name, const char *uuid,
char *type = NULL;
char *params = NULL;
if (!(dmt = _setup_task(name, uuid, 0, DM_DEVICE_STATUS))) {
stack;
return 0;
}
if (!(dmt = _setup_task(name, uuid, 0, DM_DEVICE_STATUS)))
return_0;
if (!dm_task_no_open_count(dmt))
log_error("Failed to disable open_count");
@@ -348,10 +342,8 @@ static int _percent_run(struct dev_manager *dm, const char *name,
*percent = -1;
if (!(dmt = _setup_task(name, dlid, event_nr,
wait ? DM_DEVICE_WAITEVENT : DM_DEVICE_STATUS))) {
stack;
return 0;
}
wait ? DM_DEVICE_WAITEVENT : DM_DEVICE_STATUS)))
return_0;
if (!dm_task_no_open_count(dmt))
log_error("Failed to disable open_count");
@@ -443,10 +435,8 @@ struct dev_manager *dev_manager_create(struct cmd_context *cmd,
struct dm_pool *mem;
struct dev_manager *dm;
if (!(mem = dm_pool_create("dev_manager", 16 * 1024))) {
stack;
return NULL;
}
if (!(mem = dm_pool_create("dev_manager", 16 * 1024)))
return_NULL;
if (!(dm = dm_pool_alloc(mem, sizeof(*dm))))
goto_bad;
@@ -509,10 +499,8 @@ int dev_manager_snapshot_percent(struct dev_manager *dm,
*/
log_debug("Getting device status percentage for %s", name);
if (!(_percent(dm, name, dlid, "snapshot", 0, NULL, percent,
NULL))) {
stack;
return 0;
}
NULL)))
return_0;
/* FIXME dm_pool_free ? */
@@ -544,10 +532,8 @@ int dev_manager_mirror_percent(struct dev_manager *dm,
log_debug("Getting device mirror status percentage for %s", name);
if (!(_percent(dm, name, dlid, "mirror", wait, lv, percent,
event_nr))) {
stack;
return 0;
}
event_nr)))
return_0;
return 1;
}
@@ -643,11 +629,11 @@ static int _add_dev_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
if (!(dlid = build_dlid(dm, lv->lvid.s, layer)))
return_0;
log_debug("Getting device info for %s [%s]", name, dlid);
if (!_info(name, dlid, 0, 1, 0, &info, NULL)) {
log_error("Failed to get info for %s [%s].", name, dlid);
return 0;
}
log_debug("Getting device info for %s [%s]", name, dlid);
if (!_info(name, dlid, 0, 1, 0, &info, NULL)) {
log_error("Failed to get info for %s [%s].", name, dlid);
return 0;
}
if (info.exists && !dm_tree_add_dev(dtree, info.major, info.minor)) {
log_error("Failed to add device (%" PRIu32 ":%" PRIu32") to dtree",
@@ -691,31 +677,25 @@ static struct dm_tree *_create_partial_dtree(struct dev_manager *dm, struct logi
return NULL;
}
if (!_add_lv_to_dtree(dm, dtree, lv)) {
stack;
goto fail;
}
if (!_add_lv_to_dtree(dm, dtree, lv))
goto_bad;
/* Add any snapshots of this LV */
list_iterate_safe(snh, snht, &lv->snapshot_segs)
if (!_add_lv_to_dtree(dm, dtree, list_struct_base(snh, struct lv_segment, origin_list)->cow)) {
stack;
goto fail;
}
if (!_add_lv_to_dtree(dm, dtree, list_struct_base(snh, struct lv_segment, origin_list)->cow))
goto_bad;
/* Add any LVs used by segments in this LV */
list_iterate_items(seg, &lv->segments)
for (s = 0; s < seg->area_count; s++)
if (seg_type(seg, s) == AREA_LV && seg_lv(seg, s)) {
if (!_add_lv_to_dtree(dm, dtree, seg_lv(seg, s))) {
stack;
goto fail;
}
if (!_add_lv_to_dtree(dm, dtree, seg_lv(seg, s)))
goto_bad;
}
return dtree;
fail:
bad:
dm_tree_free(dtree);
return NULL;
}
@@ -843,7 +823,7 @@ static int _add_segment_to_dtree(struct dev_manager *dm,
layer ? "-" : "", layer ? : "");
if (seg_present->segtype->ops->target_present &&
!seg_present->segtype->ops->target_present(seg_present)) {
!seg_present->segtype->ops->target_present(seg_present, NULL)) {
log_error("Can't expand LV %s: %s target support missing "
"from kernel?", seg->lv->name, seg_present->segtype->name);
return 0;
@@ -856,7 +836,7 @@ static int _add_segment_to_dtree(struct dev_manager *dm,
/* If this is a snapshot origin, add real LV */
if (lv_is_origin(seg->lv) && !layer) {
if (seg->lv->vg->status & CLUSTERED) {
if (vg_is_clustered(seg->lv->vg)) {
log_error("Clustered snapshots are not yet supported");
return 0;
}
@@ -952,10 +932,11 @@ static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
max_stripe_size = seg->stripe_size;
}
if (read_ahead == DM_READ_AHEAD_AUTO)
read_ahead = max_stripe_size;
else
if (read_ahead == DM_READ_AHEAD_AUTO) {
/* we need RA at least twice a whole stripe - see the comment in md/raid0.c */
read_ahead = max_stripe_size * 2;
read_ahead_flags = DM_READ_AHEAD_MINIMUM_FLAG;
}
dm_tree_node_set_read_ahead(dnode, read_ahead, read_ahead_flags);
@@ -986,10 +967,10 @@ static int _create_lv_symlinks(struct dev_manager *dm, struct dm_tree_node *root
name = dm_tree_node_get_name(child);
if (name && lvlayer->old_name && *lvlayer->old_name && strcmp(name, lvlayer->old_name)) {
if (!dm_split_lvm_name(dm->mem, lvlayer->old_name, &vgname, &lvname, &layer)) {
log_error("_create_lv_symlinks: Couldn't split up old device name %s", lvlayer->old_name);
return 0;
}
if (!dm_split_lvm_name(dm->mem, lvlayer->old_name, &vgname, &lvname, &layer)) {
log_error("_create_lv_symlinks: Couldn't split up old device name %s", lvlayer->old_name);
return 0;
}
fs_rename_lv(lvlayer->lv, name, lvname);
} else if (!dev_manager_lv_mknodes(lvlayer->lv))
r = 0;
@@ -1009,7 +990,7 @@ static int _remove_lv_symlinks(struct dev_manager *dm, struct dm_tree_node *root
int r = 1;
while ((child = dm_tree_next_child(&handle, root, 0))) {
if (!dm_split_lvm_name(dm->mem, dm_tree_node_get_name(child), &vgname, &lvname, &layer)) {
if (!dm_split_lvm_name(dm->mem, dm_tree_node_get_name(child), &vgname, &lvname, &layer)) {
r = 0;
continue;
}
@@ -1038,10 +1019,10 @@ static int _clean_tree(struct dev_manager *dm, struct dm_tree_node *root)
if (!(uuid = dm_tree_node_get_uuid(child)))
continue;
if (!dm_split_lvm_name(dm->mem, name, &vgname, &lvname, &layer)) {
log_error("_clean_tree: Couldn't split up device name %s.", name);
return 0;
}
if (!dm_split_lvm_name(dm->mem, name, &vgname, &lvname, &layer)) {
log_error("_clean_tree: Couldn't split up device name %s.", name);
return 0;
}
/* Not meant to be top level? */
if (!*layer)

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -138,7 +138,7 @@ static int _mk_link(const char *dev_dir, const char *vg_name,
}
/* To reach this point, the VG must have been locked.
* As locking fails if the VG is active under LVM1, it's
* As locking fails if the VG is active under LVM1, it's
* now safe to remove any LVM1 devices we find here
* (as well as any existing LVM2 symlink). */
if (!lstat(lvm1_group_path, &buf)) {
@@ -175,10 +175,8 @@ static int _mk_link(const char *dev_dir, const char *vg_name,
}
#ifdef HAVE_SELINUX
if (!dm_set_selinux_context(lv_path, S_IFLNK)) {
stack;
return 0;
}
if (!dm_set_selinux_context(lv_path, S_IFLNK))
return_0;
#endif
return 1;
@@ -225,17 +223,13 @@ static int _do_fs_op(fs_op_t type, const char *dev_dir, const char *vg_name,
switch (type) {
case FS_ADD:
if (!_mk_dir(dev_dir, vg_name) ||
!_mk_link(dev_dir, vg_name, lv_name, dev)) {
stack;
return 0;
}
!_mk_link(dev_dir, vg_name, lv_name, dev))
return_0;
break;
case FS_DEL:
if (!_rm_link(dev_dir, vg_name, lv_name) ||
!_rm_dir(dev_dir, vg_name)) {
stack;
return 0;
}
!_rm_dir(dev_dir, vg_name))
return_0;
break;
/* FIXME Use rename() */
case FS_RENAME:
@@ -316,10 +310,8 @@ static int _fs_op(fs_op_t type, const char *dev_dir, const char *vg_name,
{
if (memlock()) {
if (!_stack_fs_op(type, dev_dir, vg_name, lv_name, dev,
old_lv_name)) {
stack;
return 0;
}
old_lv_name))
return_0;
return 1;
}

380
lib/cache/lvmcache.c vendored
View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -17,6 +17,7 @@
#include "lvmcache.h"
#include "toolcontext.h"
#include "dev-cache.h"
#include "locking.h"
#include "metadata.h"
#include "filter.h"
#include "memlock.h"
@@ -29,6 +30,7 @@ static struct dm_hash_table *_lock_hash = NULL;
static struct list _vginfos;
static int _has_scanned = 0;
static int _vgs_locked = 0;
static int _vg_global_lock_held = 0; /* Global lock held when cache wiped? */
int lvmcache_init(void)
{
@@ -46,9 +48,90 @@ int lvmcache_init(void)
if (!(_lock_hash = dm_hash_create(128)))
return 0;
if (_vg_global_lock_held)
lvmcache_lock_vgname(VG_GLOBAL, 0);
return 1;
}
/* Volume Group metadata cache functions */
static void _free_cached_vgmetadata(struct lvmcache_vginfo *vginfo)
{
if (!vginfo || !vginfo->vgmetadata)
return;
dm_free(vginfo->vgmetadata);
vginfo->vgmetadata = NULL;
vginfo->fid = NULL;
log_debug("Metadata cache: VG %s wiped.", vginfo->vgname);
}
static void _store_metadata(struct lvmcache_vginfo *vginfo,
struct volume_group *vg, unsigned precommitted)
{
int size;
if (vginfo->vgmetadata)
_free_cached_vgmetadata(vginfo);
if (!(size = export_vg_to_buffer(vg, &vginfo->vgmetadata))) {
stack;
return;
}
vginfo->fid = vg->fid;
vginfo->precommitted = precommitted;
log_debug("Metadata cache: VG %s stored (%d bytes%s).", vginfo->vgname,
size, precommitted ? ", precommitted" : "");
}
static void _update_cache_info_lock_state(struct lvmcache_info *info,
int locked,
int *cached_vgmetadata_valid)
{
int was_locked = (info->status & CACHE_LOCKED) ? 1 : 0;
/*
* Cache becomes invalid whenever lock state changes
*/
if (was_locked != locked) {
info->status |= CACHE_INVALID;
*cached_vgmetadata_valid = 0;
}
if (locked)
info->status |= CACHE_LOCKED;
else
info->status &= ~CACHE_LOCKED;
}
static void _update_cache_vginfo_lock_state(struct lvmcache_vginfo *vginfo,
int locked)
{
struct lvmcache_info *info;
int cached_vgmetadata_valid = 1;
list_iterate_items(info, &vginfo->infos)
_update_cache_info_lock_state(info, locked,
&cached_vgmetadata_valid);
if (!cached_vgmetadata_valid)
_free_cached_vgmetadata(vginfo);
}
static void _update_cache_lock_state(const char *vgname, int locked)
{
struct lvmcache_vginfo *vginfo;
if (!(vginfo = vginfo_from_vgname(vgname, NULL)))
return;
_update_cache_vginfo_lock_state(vginfo, locked);
}
void lvmcache_lock_vgname(const char *vgname, int read_only __attribute((unused)))
{
if (!_lock_hash && !lvmcache_init()) {
@@ -56,9 +139,15 @@ void lvmcache_lock_vgname(const char *vgname, int read_only __attribute((unused)
return;
}
if (dm_hash_lookup(_lock_hash, vgname))
log_error("Internal error: Nested locking attempted on VG %s.",
vgname);
if (!dm_hash_insert(_lock_hash, vgname, (void *) 1))
log_error("Cache locking failure for %s", vgname);
_update_cache_lock_state(vgname, 1);
_vgs_locked++;
}
@@ -72,7 +161,12 @@ int vgname_is_locked(const char *vgname)
void lvmcache_unlock_vgname(const char *vgname)
{
/* FIXME: Clear all CACHE_LOCKED flags in this vg */
if (!dm_hash_lookup(_lock_hash, vgname))
log_error("Internal error: Attempt to unlock unlocked VG %s.",
vgname);
_update_cache_lock_state(vgname, 0);
dm_hash_remove(_lock_hash, vgname);
/* FIXME Do this per-VG */
@@ -97,7 +191,7 @@ struct lvmcache_vginfo *vginfo_from_vgname(const char *vgname, const char *vgid)
return NULL;
if (vgid)
do
do
if (!strncmp(vgid, vginfo->vgid, ID_LEN))
return vginfo;
while ((vginfo = vginfo->next));
@@ -170,9 +264,6 @@ const char *vgname_from_vgid(struct dm_pool *mem, const char *vgid)
struct lvmcache_vginfo *vginfo;
const char *vgname = NULL;
if (!*vgid)
vgname = ORPHAN;
if ((vginfo = vginfo_from_vgid(vgid)))
vgname = vginfo->vgname;
@@ -182,7 +273,43 @@ const char *vgname_from_vgid(struct dm_pool *mem, const char *vgid)
return vgname;
}
struct lvmcache_info *info_from_pvid(const char *pvid)
static int _info_is_valid(struct lvmcache_info *info)
{
if (info->status & CACHE_INVALID)
return 0;
/*
* The caller must hold the VG lock to manipulate metadata.
* In a cluster, remote nodes sometimes read metadata in the
* knowledge that the controlling node is holding the lock.
* So if the VG appears to be unlocked here, it should be safe
* to use the cached value.
*/
if (info->vginfo && !vgname_is_locked(info->vginfo->vgname))
return 1;
if (!(info->status & CACHE_LOCKED))
return 0;
return 1;
}
static int _vginfo_is_valid(struct lvmcache_vginfo *vginfo)
{
struct lvmcache_info *info;
list_iterate_items(info, &vginfo->infos)
if (!_info_is_valid(info))
return 0;
return 1;
}
/*
* If valid_only is set, data will only be returned if the cached data is
* known still to be valid.
*/
struct lvmcache_info *info_from_pvid(const char *pvid, int valid_only)
{
struct lvmcache_info *info;
char id[ID_LEN + 1] __attribute((aligned(8)));
@@ -196,6 +323,9 @@ struct lvmcache_info *info_from_pvid(const char *pvid)
if (!(info = dm_hash_lookup(_pvid_hash, id)))
return NULL;
if (valid_only && !_info_is_valid(info))
return NULL;
return info;
}
@@ -266,6 +396,32 @@ int lvmcache_label_scan(struct cmd_context *cmd, int full_scan)
return r;
}
struct volume_group *lvmcache_get_vg(const char *vgid, unsigned precommitted)
{
struct lvmcache_vginfo *vginfo;
struct volume_group *vg;
if (!vgid || !(vginfo = vginfo_from_vgid(vgid)) || !vginfo->vgmetadata)
return NULL;
if (!_vginfo_is_valid(vginfo))
return NULL;
if ((precommitted && !vginfo->precommitted) ||
(!precommitted && vginfo->precommitted))
return NULL;
if (!(vg = import_vg_from_buffer(vginfo->vgmetadata, vginfo->fid)) ||
!vg_validate(vg)) {
_free_cached_vgmetadata(vginfo);
return_NULL;
}
log_debug("Using cached metadata for VG %s.", vginfo->vgname);
return vg;
}
struct list *lvmcache_get_vgids(struct cmd_context *cmd, int full_scan)
{
struct list *vgids;
@@ -279,7 +435,7 @@ struct list *lvmcache_get_vgids(struct cmd_context *cmd, int full_scan)
}
list_iterate_items(vginfo, &_vginfos) {
if (!str_list_add(cmd->mem, vgids,
if (!str_list_add(cmd->mem, vgids,
dm_pool_strdup(cmd->mem, vginfo->vgid))) {
log_error("strlist allocation failed");
return NULL;
@@ -302,7 +458,7 @@ struct list *lvmcache_get_vgnames(struct cmd_context *cmd, int full_scan)
}
list_iterate_items(vginfo, &_vginfos) {
if (!str_list_add(cmd->mem, vgnames,
if (!str_list_add(cmd->mem, vgnames,
dm_pool_strdup(cmd->mem, vginfo->vgname))) {
log_error("strlist allocation failed");
return NULL;
@@ -328,7 +484,7 @@ struct list *lvmcache_get_pvids(struct cmd_context *cmd, const char *vgname,
return pvids;
list_iterate_items(info, &vginfo->infos) {
if (!str_list_add(cmd->mem, pvids,
if (!str_list_add(cmd->mem, pvids,
dm_pool_strdup(cmd->mem, info->dev->pvid))) {
log_error("strlist allocation failed");
return NULL;
@@ -344,7 +500,7 @@ struct device *device_from_pvid(struct cmd_context *cmd, struct id *pvid)
struct lvmcache_info *info;
/* Already cached ? */
if ((info = info_from_pvid((char *) pvid))) {
if ((info = info_from_pvid((char *) pvid, 0))) {
if (label_read(info->dev, &label, UINT64_C(0))) {
info = (struct lvmcache_info *) label->info;
if (id_equal(pvid, (struct id *) &info->dev->pvid))
@@ -355,7 +511,7 @@ struct device *device_from_pvid(struct cmd_context *cmd, struct id *pvid)
lvmcache_label_scan(cmd, 0);
/* Try again */
if ((info = info_from_pvid((char *) pvid))) {
if ((info = info_from_pvid((char *) pvid, 0))) {
if (label_read(info->dev, &label, UINT64_C(0))) {
info = (struct lvmcache_info *) label->info;
if (id_equal(pvid, (struct id *) &info->dev->pvid))
@@ -369,7 +525,7 @@ struct device *device_from_pvid(struct cmd_context *cmd, struct id *pvid)
lvmcache_label_scan(cmd, 2);
/* Try again */
if ((info = info_from_pvid((char *) pvid))) {
if ((info = info_from_pvid((char *) pvid, 0))) {
if (label_read(info->dev, &label, UINT64_C(0))) {
info = (struct lvmcache_info *) label->info;
if (id_equal(pvid, (struct id *) &info->dev->pvid))
@@ -380,34 +536,38 @@ struct device *device_from_pvid(struct cmd_context *cmd, struct id *pvid)
return NULL;
}
static int _drop_vginfo(struct lvmcache_info *info)
/*
* vginfo must be info->vginfo unless info is NULL
*/
static int _drop_vginfo(struct lvmcache_info *info, struct lvmcache_vginfo *vginfo)
{
if (!list_empty(&info->list)) {
if (info && !list_empty(&info->list)) {
list_del(&info->list);
list_init(&info->list);
}
if (info->vginfo && list_empty(&info->vginfo->infos)) {
dm_hash_remove(_vgname_hash, info->vginfo->vgname);
if (info->vginfo->next) {
if (!dm_hash_insert(_vgname_hash, info->vginfo->vgname, info->vginfo->next)) {
log_error("vg hash re-insertion failed: %s",
info->vginfo->vgname);
return 0;
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 (info->vginfo->vgname)
dm_free(info->vginfo->vgname);
if (info->vginfo->creation_host)
dm_free(info->vginfo->creation_host);
if (*info->vginfo->vgid)
dm_hash_remove(_vgid_hash, info->vginfo->vgid);
list_del(&info->vginfo->list);
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);
}
info->vginfo = NULL;
if (info)
info->vginfo = NULL;
return 1;
}
@@ -418,10 +578,10 @@ void lvmcache_del(struct lvmcache_info *info)
if (info->dev->pvid[0] && _pvid_hash)
dm_hash_remove(_pvid_hash, info->dev->pvid);
_drop_vginfo(info);
_drop_vginfo(info, info->vginfo);
info->label->labeller->ops->destroy_label(info->label->labeller,
info->label);
info->label);
dm_free(info);
return;
@@ -443,29 +603,36 @@ static int _lvmcache_update_pvid(struct lvmcache_info *info, const char *pvid)
return 1;
}
static int _lvmcache_update_vgid(struct lvmcache_info *info, const char *vgid)
/*
* vginfo must be info->vginfo unless info is NULL (orphans)
*/
static int _lvmcache_update_vgid(struct lvmcache_info *info,
struct lvmcache_vginfo *vginfo,
const char *vgid)
{
if (!vgid || !info->vginfo ||
!strncmp(info->vginfo->vgid, vgid, ID_LEN))
if (!vgid || !vginfo ||
!strncmp(vginfo->vgid, vgid, ID_LEN))
return 1;
if (info->vginfo && *info->vginfo->vgid)
dm_hash_remove(_vgid_hash, info->vginfo->vgid);
if (vginfo && *vginfo->vgid)
dm_hash_remove(_vgid_hash, vginfo->vgid);
if (!vgid) {
log_debug("lvmcache: %s: clearing VGID", dev_name(info->dev));
log_debug("lvmcache: %s: clearing VGID", info ? dev_name(info->dev) : vginfo->vgname);
return 1;
}
strncpy(info->vginfo->vgid, vgid, ID_LEN);
info->vginfo->vgid[ID_LEN] = '\0';
if (!dm_hash_insert(_vgid_hash, info->vginfo->vgid, info->vginfo)) {
strncpy(vginfo->vgid, vgid, ID_LEN);
vginfo->vgid[ID_LEN] = '\0';
if (!dm_hash_insert(_vgid_hash, vginfo->vgid, vginfo)) {
log_error("_lvmcache_update: vgid hash insertion failed: %s",
info->vginfo->vgid);
vginfo->vgid);
return 0;
}
log_debug("lvmcache: %s: setting %s VGID to %s", dev_name(info->dev),
info->vginfo->vgname, info->vginfo->vgid);
if (!is_orphan_vg(vginfo->vgname))
log_debug("lvmcache: %s: setting %s VGID to %s",
dev_name(info->dev), vginfo->vgname,
vginfo->vgid);
return 1;
}
@@ -556,25 +723,18 @@ static int _insert_vginfo(struct lvmcache_vginfo *new_vginfo, const char *vgid,
static int _lvmcache_update_vgname(struct lvmcache_info *info,
const char *vgname, const char *vgid,
uint32_t vgstatus, const char *creation_host)
uint32_t vgstatus, const char *creation_host,
const struct format_type *fmt)
{
struct lvmcache_vginfo *vginfo, *primary_vginfo;
// struct lvmcache_vginfo *old_vginfo, *next;
/* If vgname is NULL and we don't already have a vgname,
* assume ORPHAN - we want every entry to have a vginfo
* attached for scanning reasons.
*/
if (!vgname && !info->vginfo) {
vgname = ORPHAN;
vgid = ORPHAN;
}
if (!vgname || (info->vginfo && !strcmp(info->vginfo->vgname, vgname)))
if (!vgname || (info && info->vginfo && !strcmp(info->vginfo->vgname, vgname)))
return 1;
/* Remove existing vginfo entry */
_drop_vginfo(info);
if (info)
_drop_vginfo(info, info->vginfo);
/* Get existing vginfo or create new one */
if (!(vginfo = vginfo_from_vgname(vgname, vgid))) {
@@ -587,9 +747,9 @@ static int _lvmcache_update_vgname(struct lvmcache_info *info,
dm_hash_remove(_vgname_hash, old_vginfo->vgname);
if (old_vginfo->next) {
if (!dm_hash_insert(_vgname_hash, old_vginfo->vgname, old_vginfo->next)) {
log_error("vg hash re-insertion failed: %s",
log_error("vg hash re-insertion failed: %s",
old_vginfo->vgname);
return 0;
return 0;
}
}
} else do {
@@ -606,11 +766,11 @@ static int _lvmcache_update_vgname(struct lvmcache_info *info,
return 0;
}
// Rename so can assume new name does not already exist
// Rename so can assume new name does not already exist
if (!dm_hash_insert(_vgname_hash, vginfo->vgname, vginfo->next)) {
log_error("vg hash re-insertion failed: %s",
vginfo->vgname);
return 0;
return 0;
}
} else {
***/
@@ -642,17 +802,25 @@ static int _lvmcache_update_vgname(struct lvmcache_info *info,
***/
}
info->vginfo = vginfo;
list_add(&vginfo->infos, &info->list);
if (info) {
info->vginfo = vginfo;
list_add(&vginfo->infos, &info->list);
} else if (!_lvmcache_update_vgid(info, vginfo, vgid)) /* Orphans */
return_0;
_update_cache_vginfo_lock_state(vginfo, vgname_is_locked(vgname));
/* FIXME Check consistency of list! */
vginfo->fmt = info->fmt;
vginfo->fmt = fmt;
log_debug("lvmcache: %s: now %s%s%s%s%s", dev_name(info->dev),
!is_orphan_vg(vgname) ? "in VG " : "orphaned", vgname,
vginfo->vgid[0] ? " (" : "",
vginfo->vgid[0] ? vginfo->vgid : "",
vginfo->vgid[0] ? ")" : "");
if (info)
log_debug("lvmcache: %s: now in VG %s%s%s%s",
dev_name(info->dev),
vgname, vginfo->vgid[0] ? " (" : "",
vginfo->vgid[0] ? vginfo->vgid : "",
vginfo->vgid[0] ? ")" : "");
else
log_debug("lvmcache: initialised VG %s", vgname);
return 1;
}
@@ -692,23 +860,41 @@ static int _lvmcache_update_vgstatus(struct lvmcache_info *info, uint32_t vgstat
return 1;
}
int lvmcache_add_orphan_vginfo(const char *vgname, struct format_type *fmt)
{
if (!_lock_hash && !lvmcache_init()) {
log_error("Internal cache initialisation failed");
return 0;
}
return _lvmcache_update_vgname(NULL, vgname, vgname, 0, "", fmt);
}
int lvmcache_update_vgname_and_id(struct lvmcache_info *info,
const char *vgname, const char *vgid,
uint32_t vgstatus, const char *creation_host)
{
if (!vgname && !info->vginfo) {
log_error("Internal error: NULL vgname handed to cache");
/* FIXME Remove this */
vgname = info->fmt->orphan_vg_name;
vgid = vgname;
}
if (!_lvmcache_update_vgname(info, vgname, vgid, vgstatus,
creation_host) ||
!_lvmcache_update_vgid(info, vgid) ||
creation_host, info->fmt) ||
!_lvmcache_update_vgid(info, info->vginfo, vgid) ||
!_lvmcache_update_vgstatus(info, vgstatus, creation_host))
return_0;
return 1;
}
int lvmcache_update_vg(struct volume_group *vg)
int lvmcache_update_vg(struct volume_group *vg, unsigned precommitted)
{
struct pv_list *pvl;
struct lvmcache_info *info;
struct lvmcache_vginfo *vginfo;
char pvid_s[ID_LEN + 1] __attribute((aligned(8)));
pvid_s[sizeof(pvid_s) - 1] = '\0';
@@ -716,13 +902,18 @@ int lvmcache_update_vg(struct volume_group *vg)
list_iterate_items(pvl, &vg->pvs) {
strncpy(pvid_s, (char *) &pvl->pv->id, sizeof(pvid_s) - 1);
/* FIXME Could pvl->pv->dev->pvid ever be different? */
if ((info = info_from_pvid(pvid_s)) &&
if ((info = info_from_pvid(pvid_s, 0)) &&
!lvmcache_update_vgname_and_id(info, vg->name,
(char *) &vg->id,
vg->status, NULL))
return_0;
}
/* store text representation of vg to cache */
if (vg->cmd->current_settings.cache_vgmetadata &&
(vginfo = vginfo_from_vgname(vg->name, NULL)))
_store_metadata(vginfo, vg, precommitted);
return 1;
}
@@ -743,12 +934,10 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
strncpy(pvid_s, pvid, sizeof(pvid_s));
pvid_s[sizeof(pvid_s) - 1] = '\0';
if (!(existing = info_from_pvid(pvid_s)) &&
!(existing = info_from_pvid(dev->pvid))) {
if (!(label = label_create(labeller))) {
stack;
return NULL;
}
if (!(existing = info_from_pvid(pvid_s, 0)) &&
!(existing = info_from_pvid(dev->pvid, 0))) {
if (!(label = label_create(labeller)))
return_NULL;
if (!(info = dm_malloc(sizeof(*info)))) {
log_error("lvmcache_info allocation failed");
label_destroy(label);
@@ -804,11 +993,9 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
/* Has labeller changed? */
if (info->label->labeller != labeller) {
label_destroy(info->label);
if (!(info->label = label_create(labeller))) {
if (!(info->label = label_create(labeller)))
/* FIXME leaves info without label! */
stack;
return NULL;
}
return_NULL;
info->label->info = info;
}
label = info->label;
@@ -857,17 +1044,30 @@ static void _lvmcache_destroy_vgnamelist(struct lvmcache_vginfo *vginfo)
dm_free(vginfo->vgname);
if (vginfo->creation_host)
dm_free(vginfo->creation_host);
_free_cached_vgmetadata(vginfo);
dm_free(vginfo);
} while ((vginfo = next));
}
static void _lvmcache_destroy_lockname(int present __attribute((unused)))
static void _lvmcache_destroy_lockname(struct dm_hash_node *n)
{
/* Nothing to do */
char *vgname;
if (!dm_hash_get_data(_lock_hash, n))
return;
vgname = dm_hash_get_key(_lock_hash, n);
if (!strcmp(vgname, VG_GLOBAL))
_vg_global_lock_held = 1;
else
log_error("Internal error: Volume Group %s was not unlocked",
dm_hash_get_key(_lock_hash, n));
}
void lvmcache_destroy(void)
void lvmcache_destroy(struct cmd_context *cmd, int retain_orphans)
{
struct dm_hash_node *n;
log_verbose("Wiping internal VG cache");
_has_scanned = 0;
@@ -891,10 +1091,14 @@ void lvmcache_destroy(void)
}
if (_lock_hash) {
dm_hash_iter(_lock_hash, (dm_hash_iterate_fn) _lvmcache_destroy_lockname);
dm_hash_iterate(n, _lock_hash)
_lvmcache_destroy_lockname(n);
dm_hash_destroy(_lock_hash);
_lock_hash = NULL;
}
list_init(&_vginfos);
if (retain_orphans)
init_lvmcache_orphans(cmd);
}

19
lib/cache/lvmcache.h vendored
View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -20,7 +20,8 @@
#include "uuid.h"
#include "label.h"
#define ORPHAN ""
#define ORPHAN_PREFIX "#"
#define ORPHAN_VG_NAME(fmt) ORPHAN_PREFIX "orphans_" fmt
#define CACHE_INVALID 0x00000001
#define CACHE_LOCKED 0x00000002
@@ -43,6 +44,9 @@ struct lvmcache_vginfo {
char _padding[7];
struct lvmcache_vginfo *next; /* Another VG with same name? */
char *creation_host;
char *vgmetadata; /* Copy of VG metadata as format_text string */
struct format_instance *fid; /* fid associated with vgmetadata */
unsigned precommitted; /* Is vgmetadata live or precommitted? */
};
/* One per device */
@@ -59,7 +63,7 @@ struct lvmcache_info {
};
int lvmcache_init(void);
void lvmcache_destroy(void);
void lvmcache_destroy(struct cmd_context *cmd, int retain_orphans);
/* Set full_scan to 1 to reread every filtered device label or
* 2 to rescan /dev for new devices */
@@ -70,13 +74,15 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
struct device *dev,
const char *vgname, const char *vgid,
uint32_t vgstatus);
int lvmcache_add_orphan_vginfo(const char *vgname, struct format_type *fmt);
void lvmcache_del(struct lvmcache_info *info);
/* Update things */
int lvmcache_update_vgname_and_id(struct lvmcache_info *info,
const char *vgname, const char *vgid,
uint32_t vgstatus, const char *hostname);
int lvmcache_update_vg(struct volume_group *vg);
int lvmcache_update_vg(struct volume_group *vg, unsigned precommitted);
void lvmcache_drop_vg(const char *vgname);
void lvmcache_lock_vgname(const char *vgname, int read_only);
void lvmcache_unlock_vgname(const char *vgname);
@@ -86,7 +92,7 @@ const struct format_type *fmt_from_vgname(const char *vgname, const char *vgid);
struct lvmcache_vginfo *vginfo_from_vgname(const char *vgname,
const char *vgid);
struct lvmcache_vginfo *vginfo_from_vgid(const char *vgid);
struct lvmcache_info *info_from_pvid(const char *pvid);
struct lvmcache_info *info_from_pvid(const char *pvid, int valid_only);
const char *vgname_from_vgid(struct dm_pool *mem, const char *vgid);
struct device *device_from_pvid(struct cmd_context *cmd, struct id *pvid);
int vgs_locked(void);
@@ -104,4 +110,7 @@ struct list *lvmcache_get_vgids(struct cmd_context *cmd, int full_scan);
struct list *lvmcache_get_pvids(struct cmd_context *cmd, const char *vgname,
const char *vgid);
/* Returns cached volume group metadata. */
struct volume_group *lvmcache_get_vg(const char *vgid, unsigned precommitted);
#endif

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -282,10 +282,8 @@ static int _init_tags(struct cmd_context *cmd, struct config_tree *cft)
if (!cmd->hosttags && find_config_int(cft->root, "tags/hosttags",
DEFAULT_HOSTTAGS)) {
/* FIXME Strip out invalid chars: only A-Za-z0-9_+.- */
if (!_set_tag(cmd, cmd->hostname)) {
stack;
return 0;
}
if (!_set_tag(cmd, cmd->hostname))
return_0;
cmd->hosttags = 1;
}
@@ -301,17 +299,13 @@ static int _init_tags(struct cmd_context *cmd, struct config_tree *cft)
}
if (cn->child) {
passes = 0;
if (!_check_host_filters(cmd, cn->child, &passes)) {
stack;
return 0;
}
if (!_check_host_filters(cmd, cn->child, &passes))
return_0;
if (!passes)
continue;
}
if (!_set_tag(cmd, tag)) {
stack;
return 0;
}
if (!_set_tag(cmd, tag))
return_0;
}
return 1;
@@ -385,10 +379,8 @@ static int _init_lvm_conf(struct cmd_context *cmd)
return 1;
}
if (!_load_config_file(cmd, "")) {
stack;
return 0;
}
if (!_load_config_file(cmd, ""))
return_0;
return 1;
}
@@ -400,11 +392,8 @@ static int _init_tag_configs(struct cmd_context *cmd)
/* Tag list may grow while inside this loop */
list_iterate_items(sl, &cmd->tags) {
if (!_load_config_file(cmd, sl->str)) {
stack;
return 0;
}
if (!_load_config_file(cmd, sl->str))
return_0;
}
return 1;
@@ -424,10 +413,8 @@ static int _merge_config_files(struct cmd_context *cmd)
list_iterate_items(cfl, &cmd->config_files) {
/* Merge all config trees into cmd->cft using merge/tag rules */
if (!merge_config_tree(cmd, cmd->cft, cfl->cft)) {
stack;
return 0;
}
if (!merge_config_tree(cmd, cmd->cft, cfl->cft))
return_0;
}
return 1;
@@ -542,7 +529,7 @@ static struct dev_filter *_init_filter_components(struct cmd_context *cmd)
/*
* sysfs filter. Only available on 2.6 kernels. Non-critical.
* Listed first because it's very efficient at eliminating
* Listed first because it's very efficient at eliminating
* unavailable devices.
*/
if (find_config_tree_bool(cmd, "devices/sysfs_scan",
@@ -694,10 +681,8 @@ static int _init_formats(struct cmd_context *cmd)
return 0;
}
if (!(lib = load_shared_library(cmd, cv->v.str,
"format", 0))) {
stack;
return 0;
}
"format", 0)))
return_0;
if (!(init_format_fn = dlsym(lib, "init_format"))) {
log_error("Shared library %s does not contain "
@@ -736,6 +721,17 @@ static int _init_formats(struct cmd_context *cmd)
return 0;
}
int init_lvmcache_orphans(struct cmd_context *cmd)
{
struct format_type *fmt;
list_iterate_items(fmt, &cmd->formats)
if (!lvmcache_add_orphan_vginfo(fmt->orphan_vg_name, fmt))
return_0;
return 1;
}
static int _init_segtypes(struct cmd_context *cmd)
{
struct segment_type *segtype;
@@ -790,10 +786,8 @@ static int _init_segtypes(struct cmd_context *cmd)
return 0;
}
if (!(lib = load_shared_library(cmd, cv->v.str,
"segment type", 0))) {
stack;
return 0;
}
"segment type", 0)))
return_0;
if (!(init_segtype_fn = dlsym(lib, "init_segtype"))) {
log_error("Shared library %s does not contain "
@@ -998,12 +992,16 @@ struct cmd_context *create_toolcontext(struct arg *the_args, unsigned is_static,
if (!_init_formats(cmd))
goto error;
if (!init_lvmcache_orphans(cmd))
goto error;
if (!_init_segtypes(cmd))
goto error;
if (!_init_backup(cmd))
goto error;
cmd->default_settings.cache_vgmetadata = 1;
cmd->current_settings = cmd->default_settings;
cmd->config_valid = 1;
@@ -1060,7 +1058,7 @@ int refresh_toolcontext(struct cmd_context *cmd)
*/
activation_release();
lvmcache_destroy();
lvmcache_destroy(cmd, 0);
label_exit();
_destroy_segtypes(&cmd->segtypes);
_destroy_formats(&cmd->formats);
@@ -1102,6 +1100,9 @@ int refresh_toolcontext(struct cmd_context *cmd)
if (!_init_formats(cmd))
return 0;
if (!init_lvmcache_orphans(cmd))
return 0;
if (!_init_segtypes(cmd))
return 0;
@@ -1123,7 +1124,7 @@ void destroy_toolcontext(struct cmd_context *cmd)
archive_exit(cmd);
backup_exit(cmd);
lvmcache_destroy();
lvmcache_destroy(cmd, 0);
label_exit();
_destroy_segtypes(&cmd->segtypes);
_destroy_formats(&cmd->formats);

View File

@@ -34,6 +34,7 @@ struct config_info {
int archive; /* should we archive ? */
int backup; /* should we backup ? */
int read_ahead; /* DM_READ_AHEAD_NONE or _AUTO */
int cache_vgmetadata;
const char *msg_prefix;
struct format_type *fmt;
uint64_t unit_factor;
@@ -94,5 +95,6 @@ struct cmd_context *create_toolcontext(struct arg *the_args, unsigned is_static,
void destroy_toolcontext(struct cmd_context *cmd);
int refresh_toolcontext(struct cmd_context *cmd);
int config_files_changed(struct cmd_context *cmd);
int init_lvmcache_orphans(struct cmd_context *cmd);
#endif

View File

@@ -34,7 +34,8 @@
enum {
TOK_INT,
TOK_FLOAT,
TOK_STRING,
TOK_STRING, /* Single quotes */
TOK_STRING_ESCAPED, /* Double quotes */
TOK_EQ,
TOK_SECTION_B,
TOK_SECTION_E,
@@ -196,10 +197,8 @@ int read_config_fd(struct config_tree *cft, struct device *dev,
off_t mmap_offset = 0;
char *buf = NULL;
if (!(p = dm_pool_alloc(c->mem, sizeof(*p)))) {
stack;
return 0;
}
if (!(p = dm_pool_alloc(c->mem, sizeof(*p))))
return_0;
p->mem = c->mem;
/* Only use mmap with regular files */
@@ -217,10 +216,8 @@ int read_config_fd(struct config_tree *cft, struct device *dev,
}
p->fb = p->fb + mmap_offset;
} else {
if (!(buf = dm_malloc(size + size2))) {
stack;
return 0;
}
if (!(buf = dm_malloc(size + size2)))
return_0;
if (!dev_read_circular(dev, (uint64_t) offset, size,
(uint64_t) offset2, size2, buf)) {
goto out;
@@ -237,10 +234,8 @@ int read_config_fd(struct config_tree *cft, struct device *dev,
p->fe = p->fb + size + size2;
if (!_parse_config_file(p, cft)) {
stack;
goto out;
}
if (!_parse_config_file(p, cft))
goto_out;
r = 1;
@@ -378,7 +373,7 @@ static int _line_append(struct output_line *outline, const char *fmt, ...)
va_end(ap);
if (!dm_pool_grow_object(outline->mem, &buf[0], strlen(buf))) {
log_error("dm_pool_grew_object failed for config line");
log_error("dm_pool_grow_object failed for config line");
return 0;
}
@@ -407,9 +402,16 @@ static int _line_end(struct output_line *outline)
static int _write_value(struct output_line *outline, struct config_value *v)
{
char *buf;
switch (v->type) {
case CFG_STRING:
line_append("\"%s\"", v->v.str);
if (!(buf = alloca(escaped_len(v->v.str)))) {
log_error("temporary stack allocation for a config "
"string failed");
return 0;
}
line_append("\"%s\"", escape_double_quotes(buf, v->v.str));
break;
case CFG_FLOAT:
@@ -537,10 +539,8 @@ static struct config_node *_file(struct parser *p)
{
struct config_node *root = NULL, *n, *l = NULL;
while (p->t != TOK_EOF) {
if (!(n = _section(p))) {
stack;
return 0;
}
if (!(n = _section(p)))
return_0;
if (!root)
root = n;
@@ -555,25 +555,19 @@ static struct config_node *_section(struct parser *p)
{
/* IDENTIFIER SECTION_B_CHAR VALUE* SECTION_E_CHAR */
struct config_node *root, *n, *l = NULL;
if (!(root = _create_node(p))) {
stack;
return 0;
}
if (!(root = _create_node(p)))
return_0;
if (!(root->key = _dup_tok(p))) {
stack;
return 0;
}
if (!(root->key = _dup_tok(p)))
return_0;
match(TOK_IDENTIFIER);
if (p->t == TOK_SECTION_B) {
match(TOK_SECTION_B);
while (p->t != TOK_SECTION_E) {
if (!(n = _section(p))) {
stack;
return 0;
}
if (!(n = _section(p)))
return_0;
if (!root->child)
root->child = n;
@@ -584,10 +578,8 @@ static struct config_node *_section(struct parser *p)
match(TOK_SECTION_E);
} else {
match(TOK_EQ);
if (!(root->v = _value(p))) {
stack;
return 0;
}
if (!(root->v = _value(p)))
return_0;
}
return root;
@@ -600,10 +592,8 @@ static struct config_value *_value(struct parser *p)
if (p->t == TOK_ARRAY_B) {
match(TOK_ARRAY_B);
while (p->t != TOK_ARRAY_E) {
if (!(l = _type(p))) {
stack;
return 0;
}
if (!(l = _type(p)))
return_0;
if (!h)
h = l;
@@ -656,14 +646,23 @@ static struct config_value *_type(struct parser *p)
v->type = CFG_STRING;
p->tb++, p->te--; /* strip "'s */
if (!(v->v.str = _dup_tok(p))) {
stack;
return 0;
}
if (!(v->v.str = _dup_tok(p)))
return_0;
p->te++;
match(TOK_STRING);
break;
case TOK_STRING_ESCAPED:
v->type = CFG_STRING;
p->tb++, p->te--; /* strip "'s */
if (!(v->v.str = _dup_tok(p)))
return_0;
unescape_double_quotes(v->v.str);
p->te++;
match(TOK_STRING_ESCAPED);
break;
default:
log_error("Parse error at byte %" PRIptrdiff_t " (line %d): expected a value",
p->tb - p->fb + 1, p->line);
@@ -734,7 +733,7 @@ static void _get_token(struct parser *p, int tok_prev)
break;
case '"':
p->t = TOK_STRING;
p->t = TOK_STRING_ESCAPED;
p->te++;
while ((p->te != p->fe) && (*p->te) && (*p->te != '"')) {
if ((*p->te == '\\') && (p->te + 1 != p->fe) &&
@@ -847,10 +846,8 @@ static char *_dup_tok(struct parser *p)
{
size_t len = p->te - p->tb;
char *str = dm_pool_alloc(p->mem, len + 1);
if (!str) {
stack;
return 0;
}
if (!str)
return_0;
strncpy(str, p->tb, len);
str[len] = '\0';
return str;
@@ -1254,7 +1251,7 @@ static unsigned _count_tokens(const char *str, unsigned len, int type)
c = _token_type_to_char(type);
return count_chars_len(str, len, c);
return count_chars(str, len, c);
}
/*

View File

@@ -64,6 +64,7 @@
#define DEFAULT_PVMETADATACOPIES 1
#define DEFAULT_LABELSECTOR UINT64_C(1)
#define DEFAULT_READ_AHEAD "auto"
#define DEFAULT_EXTENT_SIZE 4096 /* In KB */
#define DEFAULT_MSG_PREFIX " "
#define DEFAULT_CMD_NAME 0
@@ -103,17 +104,17 @@
#define DEFAULT_REP_HEADINGS 1
#define DEFAULT_REP_SEPARATOR " "
#define DEFAULT_LVS_COLS "lv_name,vg_name,lv_attr,lv_size,origin,snap_percent,move_pv,mirror_log,copy_percent"
#define DEFAULT_LVS_COLS "lv_name,vg_name,lv_attr,lv_size,origin,snap_percent,move_pv,mirror_log,copy_percent,convert_lv"
#define DEFAULT_VGS_COLS "vg_name,pv_count,lv_count,snap_count,vg_attr,vg_size,vg_free"
#define DEFAULT_PVS_COLS "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free"
#define DEFAULT_SEGS_COLS "lv_name,vg_name,lv_attr,stripes,segtype,seg_size"
#define DEFAULT_PVSEGS_COLS "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,pvseg_start,pvseg_size"
#define DEFAULT_LVS_COLS_VERB "lv_name,vg_name,seg_count,lv_attr,lv_size,lv_major,lv_minor,lv_kernel_major,lv_kernel_minor,origin,snap_percent,move_pv,copy_percent,mirror_log,lv_uuid"
#define DEFAULT_LVS_COLS_VERB "lv_name,vg_name,seg_count,lv_attr,lv_size,lv_major,lv_minor,lv_kernel_major,lv_kernel_minor,origin,snap_percent,move_pv,copy_percent,mirror_log,convert_lv,lv_uuid"
#define DEFAULT_VGS_COLS_VERB "vg_name,vg_attr,vg_extent_size,pv_count,lv_count,snap_count,vg_size,vg_free,vg_uuid"
#define DEFAULT_PVS_COLS_VERB "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,dev_size,pv_uuid"
#define DEFAULT_SEGS_COLS_VERB "lv_name,vg_name,lv_attr,seg_start,seg_size,stripes,segtype,stripesize,chunksize"
#define DEFAULT_PVSEGS_COLS_VERB "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,pvseg_start,pvseg_size"
#define DEFAULT_PVSEGS_COLS_VERB "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,pvseg_start,pvseg_size,lv_name,seg_start_pe,segtype,seg_pe_ranges"
#define DEFAULT_LVS_SORT "vg_name,lv_name"
#define DEFAULT_VGS_SORT "vg_name"

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -87,10 +87,8 @@ int btree_insert(struct btree *t, uint32_t k, void *data)
struct node *p, **c = _lookup(&t->root, key, &p), *n;
if (!*c) {
if (!(n = dm_pool_alloc(t->mem, sizeof(*n)))) {
stack;
return 0;
}
if (!(n = dm_pool_alloc(t->mem, sizeof(*n))))
return_0;
n->key = key;
n->data = data;

View File

@@ -54,6 +54,16 @@ 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'.
*/
static inline void list_move(struct list *item, struct list *head)
{
list_del(item);
list_add(head, item);
}
/*
* Is the list empty?
*/

View File

@@ -20,10 +20,8 @@ struct list *str_list_create(struct dm_pool *mem)
{
struct list *sl;
if (!(sl = dm_pool_alloc(mem, sizeof(struct list)))) {
stack;
return NULL;
}
if (!(sl = dm_pool_alloc(mem, sizeof(struct list))))
return_NULL;
list_init(sl);
@@ -34,19 +32,15 @@ int str_list_add(struct dm_pool *mem, struct list *sll, const char *str)
{
struct str_list *sln;
if (!str) {
stack;
return 0;
}
if (!str)
return_0;
/* Already in list? */
if (str_list_match_item(sll, str))
return 1;
if (!(sln = dm_pool_alloc(mem, sizeof(*sln)))) {
stack;
return 0;
}
if (!(sln = dm_pool_alloc(mem, sizeof(*sln))))
return_0;
sln->str = str;
list_add(sll, &sln->list);
@@ -74,10 +68,8 @@ int str_list_dup(struct dm_pool *mem, struct list *sllnew,
list_init(sllnew);
list_iterate_items(sl, sllold) {
if (!str_list_add(mem, sllnew, dm_pool_strdup(mem, sl->str))) {
stack;
return 0;
}
if (!str_list_add(mem, sllnew, dm_pool_strdup(mem, sl->str)))
return_0;
}
return 1;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -236,10 +236,8 @@ static int _add_alias(struct device *dev, const char *path)
const char *oldpath;
int prefer_old = 1;
if (!sl) {
stack;
return 0;
}
if (!sl)
return_0;
/* Is name already there? */
list_iterate_items(strl, &dev->aliases) {
@@ -249,10 +247,8 @@ static int _add_alias(struct device *dev, const char *path)
}
}
if (!(sl->str = dm_pool_strdup(_cache.mem, path))) {
stack;
return 0;
}
if (!(sl->str = dm_pool_strdup(_cache.mem, path)))
return_0;
if (!list_empty(&dev->aliases)) {
oldpath = list_item(dev->aliases.n, struct str_list)->str;
@@ -294,14 +290,10 @@ static int _insert_dev(const char *path, dev_t d)
(uint32_t) d))) {
/* create new device */
if (loopfile) {
if (!(dev = dev_create_file(path, NULL, NULL, 0))) {
stack;
return 0;
}
} else if (!(dev = _dev_create(d))) {
stack;
return 0;
}
if (!(dev = dev_create_file(path, NULL, NULL, 0)))
return_0;
} else if (!(dev = _dev_create(d)))
return_0;
if (!(btree_insert(_cache.devices, (uint32_t) d, dev))) {
log_err("Couldn't insert device into binary tree.");
@@ -369,10 +361,8 @@ static int _insert_dir(const char *dir)
continue;
}
if (!(path = _join(dir, dirent[n]->d_name))) {
stack;
return 0;
}
if (!(path = _join(dir, dirent[n]->d_name)))
return_0;
_collapse_slashes(path);
r &= _insert(path, 1);
@@ -400,10 +390,8 @@ static int _insert_file(const char *path)
return 0;
}
if (!_insert_dev(path, 0)) {
stack;
return 0;
}
if (!_insert_dev(path, 0))
return_0;
return 1;
}
@@ -439,10 +427,8 @@ static int _insert(const char *path, int rec)
return 0;
}
if (!_insert_dev(path, info.st_rdev)) {
stack;
return 0;
}
if (!_insert_dev(path, info.st_rdev))
return_0;
r = 1;
}
@@ -502,7 +488,7 @@ static int _init_preferred_names(struct cmd_context *cmd)
if (v->type != CFG_STRING) {
log_error("preferred_names patterns must be enclosed in quotes");
return 0;
}
}
count++;
}
@@ -543,16 +529,13 @@ int dev_cache_init(struct cmd_context *cmd)
_cache.names = NULL;
_cache.has_scanned = 0;
if (!(_cache.mem = dm_pool_create("dev_cache", 10 * 1024))) {
stack;
return 0;
}
if (!(_cache.mem = dm_pool_create("dev_cache", 10 * 1024)))
return_0;
if (!(_cache.names = dm_hash_create(128))) {
stack;
dm_pool_destroy(_cache.mem);
_cache.mem = 0;
return 0;
return_0;
}
if (!(_cache.devices = btree_create(_cache.mem))) {

View File

@@ -170,10 +170,8 @@ static int _aligned_io(struct device_area *where, void *buffer,
struct device_area widened;
if (!(where->dev->flags & DEV_REGULAR) &&
!_get_block_size(where->dev, &block_size)) {
stack;
return 0;
}
!_get_block_size(where->dev, &block_size))
return_0;
if (!block_size)
block_size = lvm_getpagesize();
@@ -200,10 +198,8 @@ static int _aligned_io(struct device_area *where, void *buffer,
/* channel the io through the bounce buffer */
if (!_io(&widened, bounce, 0)) {
if (!should_write) {
stack;
return 0;
}
if (!should_write)
return_0;
/* FIXME pre-extend the file */
memset(bounce, '\n', widened.size);
}
@@ -340,7 +336,7 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
if (dev->open_count && !need_excl) {
/* FIXME Ensure we never get here */
log_debug("WARNING: %s already opened read-only",
log_debug("WARNING: %s already opened read-only",
dev_name(dev));
dev->open_count++;
}
@@ -354,10 +350,8 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
if (dev->flags & DEV_REGULAR)
name = dev_name(dev);
else if (!(name = dev_name_confirmed(dev, quiet))) {
stack;
return 0;
}
else if (!(name = dev_name_confirmed(dev, quiet)))
return_0;
if (!(dev->flags & DEV_REGULAR)) {
if (stat(name, &buf) < 0) {
@@ -522,8 +516,8 @@ static int _dev_close(struct device *dev, int immediate)
/* Close unless device is known to belong to a locked VG */
if (immediate ||
(dev->open_count < 1 &&
(!(info = info_from_pvid(dev->pvid)) ||
(dev->open_count < 1 &&
(!(info = info_from_pvid(dev->pvid, 0)) ||
!info->vginfo ||
!vgname_is_locked(info->vginfo->vgname))))
_close(dev);
@@ -557,10 +551,8 @@ int dev_read(struct device *dev, uint64_t offset, size_t len, void *buffer)
{
struct device_area where;
if (!dev->open_count) {
stack;
return 0;
}
if (!dev->open_count)
return_0;
where.dev = dev;
where.start = offset;
@@ -607,10 +599,8 @@ int dev_append(struct device *dev, size_t len, void *buffer)
{
int r;
if (!dev->open_count) {
stack;
return 0;
}
if (!dev->open_count)
return_0;
r = dev_write(dev, dev->end, len, buffer);
dev->end += (uint64_t) len;
@@ -625,10 +615,8 @@ int dev_write(struct device *dev, uint64_t offset, size_t len, void *buffer)
{
struct device_area where;
if (!dev->open_count) {
stack;
return 0;
}
if (!dev->open_count)
return_0;
where.dev = dev;
where.start = offset;
@@ -644,10 +632,8 @@ int dev_set(struct device *dev, uint64_t offset, size_t len, int value)
size_t s;
char buffer[4096] __attribute((aligned(8)));
if (!dev_open(dev)) {
stack;
return 0;
}
if (!dev_open(dev))
return_0;
if ((offset % SECTOR_SIZE) || (len % SECTOR_SIZE))
log_debug("Wiping %s at %" PRIu64 " length %" PRIsize_t,

View File

@@ -27,16 +27,16 @@
#define PART_OFFSET UINT64_C(0x1BE)
struct partition {
uint8_t boot_ind;
uint8_t head;
uint8_t sector;
uint8_t cyl;
uint8_t sys_ind; /* partition type */
uint8_t end_head;
uint8_t end_sector;
uint8_t end_cyl;
uint32_t start_sect;
uint32_t nr_sects;
uint8_t boot_ind;
uint8_t head;
uint8_t sector;
uint8_t cyl;
uint8_t sys_ind; /* partition type */
uint8_t end_head;
uint8_t end_sector;
uint8_t end_cyl;
uint32_t start_sect;
uint32_t nr_sects;
} __attribute__((packed));
static int _is_partitionable(struct device *dev)
@@ -62,10 +62,8 @@ static int _has_partition_table(struct device *dev)
return -1;
}
if (!dev_read(dev, UINT64_C(0), sizeof(buf), &buf)) {
stack;
goto out;
}
if (!dev_read(dev, UINT64_C(0), sizeof(buf), &buf))
goto_out;
/* FIXME Check for other types of partition table too */

View File

@@ -270,7 +270,7 @@ void pvdisplay_segments(const struct physical_volume *pv)
log_print("Physical extent %u to %u:",
pvseg->pe, pvseg->pe + pvseg->len - 1);
if (pvseg->lvseg) {
if (pvseg_is_allocated(pvseg)) {
log_print(" Logical volume\t%s%s/%s",
pvseg->lvseg->lv->vg->cmd->dev_dir,
pvseg->lvseg->lv->vg->name,
@@ -307,7 +307,8 @@ void pvdisplay_full(const struct cmd_context *cmd,
log_print("--- %sPhysical volume ---", pv->pe_size ? "" : "NEW ");
log_print("PV Name %s", pv_dev_name(pv));
log_print("VG Name %s%s", pv->vg_name,
log_print("VG Name %s%s",
is_orphan(pv) ? "" : pv->vg_name,
pv->status & EXPORTED_VG ? " (exported)" : "");
data_size = (uint64_t) pv->pe_count * pv->pe_size;
@@ -360,10 +361,8 @@ int pvdisplay_short(const struct cmd_context *cmd __attribute((unused)),
if (!pv)
return 0;
if (!id_write_format(&pv->id, uuid, sizeof(uuid))) {
stack;
return 0;
}
if (!id_write_format(&pv->id, uuid, sizeof(uuid)))
return_0;
log_print("PV Name %s ", pv_dev_name(pv));
/* FIXME pv->pv_number); */
@@ -407,10 +406,8 @@ int lvdisplay_full(struct cmd_context *cmd,
struct lv_segment *snap_seg = NULL;
float snap_percent; /* fused, fsize; */
if (!id_write_format(&lv->lvid.id[1], uuid, sizeof(uuid))) {
stack;
return 0;
}
if (!id_write_format(&lv->lvid.id[1], uuid, sizeof(uuid)))
return_0;
inkernel = lv_info(cmd, lv, &info, 1, 1) && info.exists;
@@ -577,6 +574,8 @@ void vgdisplay_full(const struct volume_group *vg)
{
uint32_t access;
uint32_t active_pvs;
uint32_t lv_count = 0;
struct lv_list *lvl;
char uuid[64] __attribute((aligned(8)));
if (vg->status & PARTIAL_VG)
@@ -605,13 +604,18 @@ void vgdisplay_full(const struct volume_group *vg)
/* vg number not part of LVM2 design
log_print ("VG # %u\n", vg->vg_number);
*/
if (vg->status & CLUSTERED) {
if (vg_is_clustered(vg)) {
log_print("Clustered yes");
log_print("Shared %s",
vg->status & SHARED ? "yes" : "no");
}
list_iterate_items(lvl, &vg->lvs)
if (lv_is_visible(lvl->lv) && !(lvl->lv->status & SNAPSHOT))
lv_count++;
log_print("MAX LV %u", vg->max_lv);
log_print("Cur LV %u", vg->lv_count + vg->snapshot_count);
log_print("Cur LV %u", lv_count);
log_print("Open LV %u", lvs_in_vg_opened(vg));
/****** FIXME Max LV Size
log_print ( "MAX LV Size %s",
@@ -655,6 +659,8 @@ void vgdisplay_full(const struct volume_group *vg)
void vgdisplay_colons(const struct volume_group *vg)
{
uint32_t active_pvs;
uint32_t lv_count;
struct lv_list *lvl;
const char *access;
char uuid[64] __attribute((aligned(8)));
@@ -663,6 +669,10 @@ void vgdisplay_colons(const struct volume_group *vg)
else
active_pvs = vg->pv_count;
list_iterate_items(lvl, &vg->lvs)
if (lv_is_visible(lvl->lv) || (lvl->lv->status & SNAPSHOT))
lv_count++;
switch (vg->status & (LVM_READ | LVM_WRITE)) {
case LVM_READ | LVM_WRITE:
access = "r/w";
@@ -698,7 +708,7 @@ void vgdisplay_colons(const struct volume_group *vg)
(uint64_t) vg->extent_count * (vg->extent_size / 2),
vg->extent_size / 2,
vg->extent_count,
vg->extent_count - vg->free_count,
vg->extent_count - vg->free_count,
vg->free_count,
uuid[0] ? uuid : "none");
return;

View File

@@ -51,7 +51,8 @@ static int _errseg_add_target_line(struct dev_manager *dm __attribute((unused)),
return dm_tree_node_add_error_target(node, len);
}
static int _errseg_target_present(const struct lv_segment *seg __attribute((unused)))
static int _errseg_target_present(const struct lv_segment *seg __attribute((unused)),
unsigned *attributes __attribute((unused)))
{
static int _errseg_checked = 0;
static int _errseg_present = 0;
@@ -77,7 +78,7 @@ static int _errseg_modules_needed(struct dm_pool *mem,
return 1;
}
static void _errseg_destroy(const struct segment_type *segtype)
{
dm_free((void *)segtype);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -50,10 +50,8 @@ struct dev_filter *composite_filter_create(int n, struct dev_filter **filters)
{
struct dev_filter **filters_copy, *cft;
if (!filters) {
stack;
return NULL;
}
if (!filters)
return_NULL;
if (!(filters_copy = dm_malloc(sizeof(*filters) * (n + 1)))) {
log_error("composite filters allocation failed");

View File

@@ -19,7 +19,8 @@
#ifdef linux
static int _ignore_md(struct dev_filter *f, struct device *dev)
static int _ignore_md(struct dev_filter *f __attribute((unused)),
struct device *dev)
{
int ret;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -18,6 +18,7 @@
#include "dev-cache.h"
#include "filter-persistent.h"
#include "lvm-file.h"
#include "lvm-string.h"
#include <sys/stat.h>
#include <fcntl.h>
@@ -42,10 +43,8 @@ static int _init_hash(struct pfilter *pf)
if (pf->devices)
dm_hash_destroy(pf->devices);
if (!(pf->devices = dm_hash_create(128))) {
stack;
return 0;
}
if (!(pf->devices = dm_hash_create(128)))
return_0;
return 1;
}
@@ -99,13 +98,13 @@ int persistent_filter_load(struct dev_filter *f, struct config_tree **cft_out)
{
struct pfilter *pf = (struct pfilter *) f->private;
struct config_tree *cft;
struct stat info;
struct stat info;
int r = 0;
if (!stat(pf->file, &info))
if (!stat(pf->file, &info))
pf->ctime = info.st_ctime;
else {
log_very_verbose("%s: stat failed: %s", pf->file,
log_very_verbose("%s: stat failed: %s", pf->file,
strerror(errno));
return_0;
}
@@ -144,6 +143,7 @@ static void _write_array(struct pfilter *pf, FILE *fp, const char *path,
{
void *d;
int first = 1;
char *buf, *str;
struct dm_hash_node *n;
for (n = dm_hash_get_first(pf->devices); n;
@@ -160,7 +160,13 @@ static void _write_array(struct pfilter *pf, FILE *fp, const char *path,
first = 0;
}
fprintf(fp, "\t\t\"%s\"", dm_hash_get_key(pf->devices, n));
str = dm_hash_get_key(pf->devices, n);
if (!(buf = alloca(escaped_len(str)))) {
log_error("persistent filter device path stack "
"allocation failed");
return;
}
fprintf(fp, "\t\t\"%s\"", escape_double_quotes(buf, str));
}
if (!first)
@@ -293,10 +299,8 @@ struct dev_filter *persistent_filter_create(struct dev_filter *real,
struct pfilter *pf;
struct dev_filter *f = NULL;
if (!(pf = dm_malloc(sizeof(*pf)))) {
stack;
return NULL;
}
if (!(pf = dm_malloc(sizeof(*pf))))
return_NULL;
memset(pf, 0, sizeof(*pf));
if (!(pf->file = dm_malloc(strlen(file) + 1)))

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -70,10 +70,8 @@ static int _extract_pattern(struct dm_pool *mem, const char *pat,
/*
* copy the regex
*/
if (!(r = dm_pool_strdup(mem, pat))) {
stack;
return 0;
}
if (!(r = dm_pool_strdup(mem, pat)))
return_0;
/*
* trim the trailing character, having checked it's sep.
@@ -192,10 +190,8 @@ struct dev_filter *regex_filter_create(struct config_value *patterns)
struct rfilter *rf;
struct dev_filter *f;
if (!mem) {
stack;
return NULL;
}
if (!mem)
return_NULL;
if (!(rf = dm_pool_alloc(mem, sizeof(*rf))))
goto_bad;

View File

@@ -236,21 +236,21 @@ static int _read_dev(const char *file, dev_t *result)
*/
static int _read_devs(struct dev_set *ds, const char *dir, unsigned sysfs_depth)
{
struct dirent *d;
DIR *dr;
struct dirent *d;
DIR *dr;
struct stat info;
char path[PATH_MAX];
char file[PATH_MAX];
dev_t dev = { 0 };
int r = 1;
if (!(dr = opendir(dir))) {
log_sys_error("opendir", dir);
return 0;
}
if (!(dr = opendir(dir))) {
log_sys_error("opendir", dir);
return 0;
}
while ((d = readdir(dr))) {
if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
while ((d = readdir(dr))) {
if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
continue;
if (dm_snprintf(path, sizeof(path), "%s/%s", dir,
@@ -278,8 +278,8 @@ static int _read_devs(struct dev_set *ds, const char *dir, unsigned sysfs_depth)
}
}
if (closedir(dr))
log_sys_error("closedir", dir);
if (closedir(dr))
log_sys_error("closedir", dir);
return r;
}

View File

@@ -77,6 +77,7 @@ static const device_info_t device_info[] = {
{"xvd", 16}, /* Xen virtual block device */
{"vdisk", 8}, /* SUN's LDOM virtual block device */
{"ps3disk", 16}, /* PlayStation 3 internal disk */
{"virtblk", 8}, /* VirtIO disk */
{NULL, 0}
};
@@ -277,9 +278,8 @@ struct dev_filter *lvm_type_filter_create(const char *proc,
f->private = NULL;
if (!_scan_proc_dev(proc, cn)) {
stack;
dm_free(f);
return NULL;
return_NULL;
}
return f;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -21,7 +21,6 @@
#include <fcntl.h>
#define fail do {stack; return 0;} while(0)
#define xx16(v) disk->v = xlate16(disk->v)
#define xx32(v) disk->v = xlate32(disk->v)
#define xx64(v) disk->v = xlate64(disk->v)
@@ -134,15 +133,15 @@ static int _munge_formats(struct pv_disk *pvd)
return 0;
}
/* UUID too long? */
if (pvd->pv_uuid[ID_LEN]) {
/* UUID too long? */
if (pvd->pv_uuid[ID_LEN]) {
/* Retain ID_LEN chars from end */
for (e = ID_LEN; e < sizeof(pvd->pv_uuid); e++) {
if (!pvd->pv_uuid[e]) {
e--;
break;
}
}
for (e = ID_LEN; e < sizeof(pvd->pv_uuid); e++) {
if (!pvd->pv_uuid[e]) {
e--;
break;
}
}
for (b = 0; b < ID_LEN; b++) {
pvd->pv_uuid[b] = pvd->pv_uuid[++e - ID_LEN];
/* FIXME Remove all invalid chars */
@@ -150,7 +149,7 @@ static int _munge_formats(struct pv_disk *pvd)
pvd->pv_uuid[b] = '#';
}
memset(&pvd->pv_uuid[ID_LEN], 0, sizeof(pvd->pv_uuid) - ID_LEN);
}
}
/* If UUID is missing, create one */
if (pvd->pv_uuid[0] == '\0') {
@@ -161,8 +160,8 @@ static int _munge_formats(struct pv_disk *pvd)
return 1;
}
/*
* If exported, remove "PV_EXP" from end of VG name
/*
* If exported, remove "PV_EXP" from end of VG name
*/
static void _munge_exported_vg(struct pv_disk *pvd)
{
@@ -178,8 +177,8 @@ static void _munge_exported_vg(struct pv_disk *pvd)
s = sizeof(EXPORTED_TAG);
if (!strncmp((char *)pvd->vg_name + l - s + 1, EXPORTED_TAG, s)) {
pvd->vg_name[l - s + 1] = '\0';
pvd->pv_status |= VG_EXPORTED;
}
pvd->pv_status |= VG_EXPORTED;
}
}
int munge_pvd(struct device *dev, struct pv_disk *pvd)
@@ -218,7 +217,7 @@ static int _read_pvd(struct device *dev, struct pv_disk *pvd)
static int _read_lvd(struct device *dev, uint64_t pos, struct lv_disk *disk)
{
if (!dev_read(dev, pos, sizeof(*disk), disk))
fail;
return_0;
_xlate_lvd(disk);
@@ -230,12 +229,12 @@ int read_vgd(struct device *dev, struct vg_disk *vgd, struct pv_disk *pvd)
uint64_t pos = pvd->vg_on_disk.base;
if (!dev_read(dev, pos, sizeof(*vgd), vgd))
fail;
return_0;
_xlate_vgd(vgd);
if ((vgd->lv_max > MAX_LV) || (vgd->pv_max > MAX_PV))
fail;
return_0;
/* If UUID is missing, create one */
if (vgd->vg_uuid[0] == '\0')
@@ -254,10 +253,10 @@ static int _read_uuids(struct disk_list *data)
while (pos < end && num_read < data->vgd.pv_cur) {
if (!dev_read(data->dev, pos, sizeof(buffer), buffer))
fail;
return_0;
if (!(ul = dm_pool_alloc(data->mem, sizeof(*ul))))
fail;
return_0;
memcpy(ul->uuid, buffer, NAME_LEN);
ul->uuid[NAME_LEN - 1] = '\0';
@@ -288,10 +287,10 @@ static int _read_lvs(struct disk_list *data)
ll = dm_pool_alloc(data->mem, sizeof(*ll));
if (!ll)
fail;
return_0;
if (!_read_lvd(data->dev, pos, &ll->lvd))
fail;
return_0;
if (!_check_lvd(&ll->lvd))
continue;
@@ -310,10 +309,10 @@ static int _read_extents(struct disk_list *data)
uint64_t pos = data->pvd.pe_on_disk.base;
if (!extents)
fail;
return_0;
if (!dev_read(data->dev, pos, len, extents))
fail;
return_0;
_xlate_extents(extents, data->pvd.pe_total);
data->extents = extents;
@@ -327,10 +326,11 @@ static void __update_lvmcache(const struct format_type *fmt,
unsigned exported)
{
struct lvmcache_info *info;
const char *vgname = *((char *)dl->pvd.vg_name) ?
(char *)dl->pvd.vg_name : fmt->orphan_vg_name;
if (!(info = lvmcache_add(fmt->labeller, (char *)dl->pvd.pv_uuid, dev,
(char *)dl->pvd.vg_name, vgid,
exported ? EXPORTED_VG : 0))) {
vgname, vgid, exported ? EXPORTED_VG : 0))) {
stack;
return;
}
@@ -347,10 +347,8 @@ static struct disk_list *__read_disk(const struct format_type *fmt,
struct disk_list *dl = dm_pool_zalloc(mem, sizeof(*dl));
const char *name = dev_name(dev);
if (!dl) {
stack;
return NULL;
}
if (!dl)
return_NULL;
dl->dev = dev;
dl->mem = mem;
@@ -366,20 +364,20 @@ static struct disk_list *__read_disk(const struct format_type *fmt,
if (!*dl->pvd.vg_name) {
log_very_verbose("%s is not a member of any format1 VG", name);
__update_lvmcache(fmt, dl, dev, NULL, 0);
__update_lvmcache(fmt, dl, dev, fmt->orphan_vg_name, 0);
return (vg_name) ? NULL : dl;
}
if (!read_vgd(dl->dev, &dl->vgd, &dl->pvd)) {
log_error("Failed to read VG data from PV (%s)", name);
__update_lvmcache(fmt, dl, dev, NULL, 0);
__update_lvmcache(fmt, dl, dev, fmt->orphan_vg_name, 0);
goto bad;
}
if (vg_name && strcmp(vg_name, (char *)dl->pvd.vg_name)) {
log_very_verbose("%s is not a member of the VG %s",
name, vg_name);
__update_lvmcache(fmt, dl, dev, NULL, 0);
__update_lvmcache(fmt, dl, dev, fmt->orphan_vg_name, 0);
goto bad;
}
@@ -417,10 +415,8 @@ struct disk_list *read_disk(const struct format_type *fmt, struct device *dev,
{
struct disk_list *dl;
if (!dev_open(dev)) {
stack;
return NULL;
}
if (!dev_open(dev))
return_NULL;
dl = __read_disk(fmt, dev, mem, vg_name);
@@ -519,7 +515,7 @@ static int _write_vgd(struct disk_list *data)
_xlate_vgd(vgd);
if (!dev_write(data->dev, pos, sizeof(*vgd), vgd))
fail;
return_0;
_xlate_vgd(vgd);
@@ -544,7 +540,7 @@ static int _write_uuids(struct disk_list *data)
pos, NAME_LEN);
if (!dev_write(data->dev, pos, NAME_LEN, ul->uuid))
fail;
return_0;
pos += NAME_LEN;
}
@@ -560,7 +556,7 @@ static int _write_lvd(struct device *dev, uint64_t pos, struct lv_disk *disk)
_xlate_lvd(disk);
if (!dev_write(dev, pos, sizeof(*disk), disk))
fail;
return_0;
_xlate_lvd(disk);
@@ -588,7 +584,7 @@ static int _write_lvs(struct disk_list *data)
}
if (!_write_lvd(data->dev, pos + offset, &ll->lvd))
fail;
return_0;
}
return 1;
@@ -606,7 +602,7 @@ static int _write_extents(struct disk_list *data)
_xlate_extents(extents, data->pvd.pe_total);
if (!dev_write(data->dev, pos, len, extents))
fail;
return_0;
_xlate_extents(extents, data->pvd.pe_total);
@@ -643,7 +639,7 @@ static int _write_pvd(struct disk_list *data)
_xlate_pvd((struct pv_disk *) buf);
if (!dev_write(data->dev, pos, size, buf)) {
dm_free(buf);
fail;
return_0;
}
dm_free(buf);
@@ -707,10 +703,8 @@ static int _write_all_pvd(const struct format_type *fmt, struct disk_list *data)
{
int r;
if (!dev_open(data->dev)) {
stack;
return 0;
}
if (!dev_open(data->dev))
return_0;
r = __write_all_pvd(fmt, data);
@@ -731,7 +725,7 @@ int write_disks(const struct format_type *fmt, struct list *pvs)
list_iterate_items(dl, pvs) {
if (!(_write_all_pvd(fmt, dl)))
fail;
return_0;
log_very_verbose("Successfully wrote data to %s",
dev_name(dl->dev));

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -18,13 +18,10 @@
#include "limits.h"
#include "display.h"
#include "toolcontext.h"
#include "lvmcache.h"
#include "lvm1-label.h"
#include "format1.h"
#include "segtype.h"
#define FMT_LVM1_NAME "lvm1"
/* VG consistency checks */
static int _check_vgs(struct list *pvs, int *partial)
{
@@ -168,7 +165,6 @@ static struct volume_group *_build_vg(struct format_instance *fid,
return vg;
bad:
stack;
dm_pool_free(mem, vg);
return NULL;
}
@@ -182,10 +178,8 @@ static struct volume_group *_format1_vg_read(struct format_instance *fid,
struct volume_group *vg = NULL;
list_init(&pvs);
if (!mem) {
stack;
return NULL;
}
if (!mem)
return_NULL;
/* Strip dev_dir if present */
vg_name = strip_dir(vg_name, fid->fmt->cmd->dev_dir);
@@ -209,10 +203,8 @@ static struct disk_list *_flatten_pv(struct format_instance *fid,
{
struct disk_list *dl = dm_pool_alloc(mem, sizeof(*dl));
if (!dl) {
stack;
return NULL;
}
if (!dl)
return_NULL;
dl->mem = mem;
dl->dev = pv->dev;
@@ -224,9 +216,8 @@ static struct disk_list *_flatten_pv(struct format_instance *fid,
!export_vg(&dl->vgd, vg) ||
!export_uuids(dl, vg) ||
!export_lvs(dl, vg, pv, dev_dir) || !calculate_layout(dl)) {
stack;
dm_pool_free(mem, dl);
return NULL;
return_NULL;
}
return dl;
@@ -241,10 +232,8 @@ static int _flatten_vg(struct format_instance *fid, struct dm_pool *mem,
struct disk_list *data;
list_iterate_items(pvl, &vg->pvs) {
if (!(data = _flatten_pv(fid, mem, vg, pvl->pv, dev_dir))) {
stack;
return 0;
}
if (!(data = _flatten_pv(fid, mem, vg, pvl->pv, dev_dir)))
return_0;
list_add(pvds, &data->list);
}
@@ -252,10 +241,8 @@ static int _flatten_vg(struct format_instance *fid, struct dm_pool *mem,
export_numbers(pvds, vg);
export_pv_act(pvds);
if (!export_vg_number(fid, pvds, vg->name, filter)) {
stack;
return 0;
}
if (!export_vg_number(fid, pvds, vg->name, filter))
return_0;
return 1;
}
@@ -267,10 +254,8 @@ static int _format1_vg_write(struct format_instance *fid, struct volume_group *v
struct list pvds;
int r = 0;
if (!mem) {
stack;
return 0;
}
if (!mem)
return_0;
list_init(&pvds);
@@ -278,7 +263,7 @@ static int _format1_vg_write(struct format_instance *fid, struct volume_group *v
fid->fmt->cmd->filter) &&
write_disks(fid->fmt, &pvds));
lvmcache_update_vg(vg);
lvmcache_update_vg(vg, 0);
dm_pool_destroy(mem);
return r;
}
@@ -293,25 +278,17 @@ static int _format1_pv_read(const struct format_type *fmt, const char *pv_name,
log_very_verbose("Reading physical volume data %s from disk", pv_name);
if (!mem) {
stack;
return 0;
}
if (!mem)
return_0;
if (!(dev = dev_cache_get(pv_name, fmt->cmd->filter))) {
stack;
goto out;
}
if (!(dev = dev_cache_get(pv_name, fmt->cmd->filter)))
goto_out;
if (!(dl = read_disk(fmt, dev, mem, NULL))) {
stack;
goto out;
}
if (!(dl = read_disk(fmt, dev, mem, NULL)))
goto_out;
if (!import_pv(fmt, fmt->cmd->mem, dl->dev, NULL, pv, &dl->pvd, &dl->vgd)) {
stack;
goto out;
}
if (!import_pv(fmt, fmt->cmd->mem, dl->dev, NULL, pv, &dl->pvd, &dl->vgd))
goto_out;
pv->fmt = fmt;
@@ -344,10 +321,8 @@ static int _format1_pv_setup(const struct format_type *fmt,
/*
* This works out pe_start and pe_count.
*/
if (!calculate_extent_count(pv, extent_size, extent_count, pe_start)) {
stack;
return 0;
}
if (!calculate_extent_count(pv, extent_size, extent_count, pe_start))
return_0;
/* Retain existing extent locations exactly */
if (((pe_start || extent_count) && (pe_start != pv->pe_start)) ||
@@ -390,10 +365,8 @@ static int _format1_pv_write(const struct format_type *fmt, struct physical_volu
struct lvmcache_info *info;
if (!(info = lvmcache_add(fmt->labeller, (char *) &pv->id, pv->dev,
pv->vg_name, NULL, 0))) {
stack;
return 0;
}
pv->vg_name, NULL, 0)))
return_0;
label = info->label;
info->device_size = pv->size << SECTOR_SHIFT;
info->fmt = fmt;
@@ -406,10 +379,8 @@ static int _format1_pv_write(const struct format_type *fmt, struct physical_volu
pv->pe_size = pv->pe_count = 0;
pv->pe_start = LVM1_PE_ALIGN;
if (!(mem = dm_pool_create("lvm1 pv_write", 1024))) {
stack;
return 0;
}
if (!(mem = dm_pool_create("lvm1 pv_write", 1024)))
return_0;
if (!(dl = dm_pool_alloc(mem, sizeof(*dl))))
goto_bad;
@@ -470,13 +441,11 @@ static int _format1_vg_setup(struct format_instance *fid, struct volume_group *v
return 1;
}
static int _format1_segtype_supported(struct format_instance *fid __attribute((unused)),
static int _format1_segtype_supported(struct format_instance *fid __attribute((unused)),
const struct segment_type *segtype)
{
if (!(segtype->flags & SEG_FORMAT1_SUPPORT)) {
stack;
return 0;
}
if (!(segtype->flags & SEG_FORMAT1_SUPPORT))
return_0;
return 1;
}
@@ -494,19 +463,16 @@ static struct format_instance *_format1_create_instance(const struct format_type
struct format_instance *fid;
struct metadata_area *mda;
if (!(fid = dm_pool_alloc(fmt->cmd->mem, sizeof(*fid)))) {
stack;
return NULL;
}
if (!(fid = dm_pool_alloc(fmt->cmd->mem, sizeof(*fid))))
return_NULL;
fid->fmt = fmt;
list_init(&fid->metadata_areas);
/* Define a NULL metadata area */
if (!(mda = dm_pool_alloc(fmt->cmd->mem, sizeof(*mda)))) {
stack;
dm_pool_free(fmt->cmd->mem, fid);
return NULL;
return_NULL;
}
mda->ops = &_metadata_format1_ops;
@@ -547,15 +513,14 @@ struct format_type *init_format(struct cmd_context *cmd)
{
struct format_type *fmt = dm_malloc(sizeof(*fmt));
if (!fmt) {
stack;
return NULL;
}
if (!fmt)
return_NULL;
fmt->cmd = cmd;
fmt->ops = &_format1_ops;
fmt->name = FMT_LVM1_NAME;
fmt->alias = NULL;
fmt->orphan_vg_name = FMT_LVM1_ORPHAN_VG_NAME;
fmt->features = FMT_RESTRICTED_LVIDS | FMT_ORPHAN_ALLOCATABLE |
FMT_RESTRICTED_READAHEAD;
fmt->private = NULL;

View File

@@ -17,6 +17,10 @@
#define _LVM_FORMAT1_H
#include "metadata.h"
#include "lvmcache.h"
#define FMT_LVM1_NAME "lvm1"
#define FMT_LVM1_ORPHAN_VG_NAME ORPHAN_VG_NAME(FMT_LVM1_NAME)
#ifdef LVM1_INTERNAL
struct format_type *init_lvm1_format(struct cmd_context *cmd);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -26,6 +26,7 @@
#include "pv_alloc.h"
#include "display.h"
#include "lvmcache.h"
#include "metadata.h"
#include <time.h>
@@ -61,7 +62,7 @@ int import_pv(const struct format_type *fmt, struct dm_pool *mem,
pv->dev = dev;
if (!*pvd->vg_name)
pv->vg_name = ORPHAN;
pv->vg_name = fmt->orphan_vg_name;
else if (!(pv->vg_name = dm_pool_strdup(mem, (char *)pvd->vg_name))) {
log_error("Volume Group name allocation failed.");
return 0;
@@ -117,10 +118,8 @@ int import_pv(const struct format_type *fmt, struct dm_pool *mem,
list_init(&pv->tags);
list_init(&pv->segments);
if (!alloc_pv_segment_whole_pv(mem, pv)) {
stack;
return 0;
}
if (!alloc_pv_segment_whole_pv(mem, pv))
return_0;
return 1;
}
@@ -149,11 +148,9 @@ int export_pv(struct cmd_context *cmd, struct dm_pool *mem __attribute((unused))
memcpy(pvd->pv_uuid, pv->id.uuid, ID_LEN);
if (pv->vg_name) {
if (!_check_vg_name(pv->vg_name)) {
stack;
return 0;
}
if (pv->vg_name && !is_orphan(pv)) {
if (!_check_vg_name(pv->vg_name))
return_0;
strncpy((char *)pvd->vg_name, pv->vg_name, sizeof(pvd->vg_name));
}
@@ -167,10 +164,8 @@ int export_pv(struct cmd_context *cmd, struct dm_pool *mem __attribute((unused))
if (!*vg->system_id ||
strncmp(vg->system_id, EXPORTED_TAG,
sizeof(EXPORTED_TAG) - 1)) {
if (!_system_id(cmd, (char *)pvd->system_id, EXPORTED_TAG)) {
stack;
return 0;
}
if (!_system_id(cmd, (char *)pvd->system_id, EXPORTED_TAG))
return_0;
}
if (strlen((char *)pvd->vg_name) + sizeof(EXPORTED_TAG) >
sizeof(pvd->vg_name)) {
@@ -184,18 +179,14 @@ int export_pv(struct cmd_context *cmd, struct dm_pool *mem __attribute((unused))
/* Is VG being imported? */
if (vg && !(vg->status & EXPORTED_VG) && *vg->system_id &&
!strncmp(vg->system_id, EXPORTED_TAG, sizeof(EXPORTED_TAG) - 1)) {
if (!_system_id(cmd, (char *)pvd->system_id, IMPORTED_TAG)) {
stack;
return 0;
}
if (!_system_id(cmd, (char *)pvd->system_id, IMPORTED_TAG))
return_0;
}
/* Generate system_id if PV is in VG */
if (!pvd->system_id || !*pvd->system_id)
if (!_system_id(cmd, (char *)pvd->system_id, "")) {
stack;
return 0;
}
if (!_system_id(cmd, (char *)pvd->system_id, ""))
return_0;
/* Update internal system_id if we changed it */
if (vg &&
@@ -227,20 +218,14 @@ int import_vg(struct dm_pool *mem,
struct vg_disk *vgd = &dl->vgd;
memcpy(vg->id.uuid, vgd->vg_uuid, ID_LEN);
if (!_check_vg_name((char *)dl->pvd.vg_name)) {
stack;
return 0;
}
if (!_check_vg_name((char *)dl->pvd.vg_name))
return_0;
if (!(vg->name = dm_pool_strdup(mem, (char *)dl->pvd.vg_name))) {
stack;
return 0;
}
if (!(vg->name = dm_pool_strdup(mem, (char *)dl->pvd.vg_name)))
return_0;
if (!(vg->system_id = dm_pool_alloc(mem, NAME_LEN))) {
stack;
return 0;
}
if (!(vg->system_id = dm_pool_alloc(mem, NAME_LEN)))
return_0;
*vg->system_id = '\0';
@@ -286,7 +271,7 @@ int export_vg(struct vg_disk *vgd, struct volume_group *vg)
if (vg->status & LVM_WRITE)
vgd->vg_access |= VG_WRITE;
if (vg->status & CLUSTERED)
if (vg_is_clustered(vg))
vgd->vg_access |= VG_CLUSTERED;
if (vg->status & SHARED)
@@ -315,10 +300,8 @@ int import_lv(struct dm_pool *mem, struct logical_volume *lv, struct lv_disk *lv
{
lvid_from_lvnum(&lv->lvid, &lv->vg->id, lvd->lv_number);
if (!(lv->name = _create_lv_name(mem, (char *)lvd->lv_name))) {
stack;
return 0;
}
if (!(lv->name = _create_lv_name(mem, (char *)lvd->lv_name)))
return_0;
lv->status |= VISIBLE_LV;
@@ -361,6 +344,7 @@ int import_lv(struct dm_pool *mem, struct logical_volume *lv, struct lv_disk *lv
list_init(&lv->snapshot_segs);
list_init(&lv->segments);
list_init(&lv->tags);
list_init(&lv->segs_using_this_lv);
return 1;
}
@@ -456,15 +440,11 @@ int import_pvs(const struct format_type *fmt, struct dm_pool *mem,
*count = 0;
list_iterate_items(dl, pvds) {
if (!(pvl = dm_pool_zalloc(mem, sizeof(*pvl))) ||
!(pvl->pv = dm_pool_alloc(mem, sizeof(*pvl->pv)))) {
stack;
return 0;
}
!(pvl->pv = dm_pool_alloc(mem, sizeof(*pvl->pv))))
return_0;
if (!import_pv(fmt, mem, dl->dev, vg, pvl->pv, &dl->pvd, &dl->vgd)) {
stack;
return 0;
}
if (!import_pv(fmt, mem, dl->dev, vg, pvl->pv, &dl->pvd, &dl->vgd))
return_0;
pvl->pv->fmt = fmt;
list_add(results, &pvl->list);
@@ -482,17 +462,13 @@ static struct logical_volume *_add_lv(struct dm_pool *mem,
struct logical_volume *lv;
if (!(ll = dm_pool_zalloc(mem, sizeof(*ll))) ||
!(ll->lv = dm_pool_zalloc(mem, sizeof(*ll->lv)))) {
stack;
return NULL;
}
!(ll->lv = dm_pool_zalloc(mem, sizeof(*ll->lv))))
return_NULL;
lv = ll->lv;
lv->vg = vg;
if (!import_lv(mem, lv, lvd)) {
stack;
return NULL;
}
if (!import_lv(mem, lv, lvd))
return_NULL;
list_add(&vg->lvs, &ll->list);
vg->lv_count++;
@@ -511,10 +487,8 @@ int import_lvs(struct dm_pool *mem, struct volume_group *vg, struct list *pvds)
lvd = &ll->lvd;
if (!find_lv(vg, (char *)lvd->lv_name) &&
!_add_lv(mem, vg, lvd)) {
stack;
return 0;
}
!_add_lv(mem, vg, lvd))
return_0;
}
}
@@ -532,49 +506,37 @@ int export_lvs(struct disk_list *dl, struct volume_group *vg,
uint32_t lv_num;
struct dm_hash_table *lvd_hash;
if (!_check_vg_name(vg->name)) {
stack;
return 0;
}
if (!_check_vg_name(vg->name))
return_0;
if (!(lvd_hash = dm_hash_create(32))) {
stack;
return 0;
}
if (!(lvd_hash = dm_hash_create(32)))
return_0;
/*
* setup the pv's extents array
*/
len = sizeof(struct pe_disk) * dl->pvd.pe_total;
if (!(dl->extents = dm_pool_alloc(dl->mem, len))) {
stack;
goto out;
}
if (!(dl->extents = dm_pool_alloc(dl->mem, len)))
goto_out;
memset(dl->extents, 0, len);
list_iterate_items(ll, &vg->lvs) {
if (ll->lv->status & SNAPSHOT)
continue;
if (!(lvdl = dm_pool_alloc(dl->mem, sizeof(*lvdl)))) {
stack;
goto out;
}
if (!(lvdl = dm_pool_alloc(dl->mem, sizeof(*lvdl))))
goto_out;
_export_lv(&lvdl->lvd, vg, ll->lv, dev_dir);
lv_num = lvnum_from_lvid(&ll->lv->lvid);
lvdl->lvd.lv_number = lv_num;
if (!dm_hash_insert(lvd_hash, ll->lv->name, &lvdl->lvd)) {
stack;
goto out;
}
if (!dm_hash_insert(lvd_hash, ll->lv->name, &lvdl->lvd))
goto_out;
if (!export_extents(dl, lv_num + 1, ll->lv, pv)) {
stack;
goto out;
}
if (!export_extents(dl, lv_num + 1, ll->lv, pv))
goto_out;
if (lv_is_origin(ll->lv))
lvdl->lvd.lv_access |= LV_SNAPSHOT_ORG;
@@ -657,7 +619,7 @@ int import_snapshots(struct dm_pool *mem __attribute((unused)), struct volume_gr
/* insert the snapshot */
if (!vg_add_snapshot(NULL, org, cow, NULL,
org->le_count,
org->le_count,
lvd->lv_chunk_size)) {
log_err("Couldn't add snapshot.");
return 0;
@@ -674,10 +636,8 @@ int export_uuids(struct disk_list *dl, struct volume_group *vg)
struct pv_list *pvl;
list_iterate_items(pvl, &vg->pvs) {
if (!(ul = dm_pool_alloc(dl->mem, sizeof(*ul)))) {
stack;
return 0;
}
if (!(ul = dm_pool_alloc(dl->mem, sizeof(*ul))))
return_0;
memset(ul->uuid, 0, sizeof(ul->uuid));
memcpy(ul->uuid, pvl->pv->id.uuid, ID_LEN);
@@ -722,10 +682,8 @@ int export_vg_number(struct format_instance *fid, struct list *pvds,
struct disk_list *dl;
int vg_num;
if (!get_free_vg_number(fid, filter, vg_name, &vg_num)) {
stack;
return 0;
}
if (!get_free_vg_number(fid, filter, vg_name, &vg_num))
return_0;
list_iterate_items(dl, pvds)
dl->vgd.vg_number = vg_num;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -118,10 +118,8 @@ static int _fill_maps(struct dm_hash_table *maps, struct volume_group *vg,
e = dl->extents;
/* build an array of lv's for this pv */
if (!_fill_lv_array(lvms, maps, dl)) {
stack;
return 0;
}
if (!_fill_lv_array(lvms, maps, dl))
return_0;
for (i = 0; i < dl->pvd.pe_total; i++) {
lv_num = e[i].lv_num;
@@ -189,10 +187,8 @@ static int _check_maps_are_complete(struct dm_hash_table *maps)
for (n = dm_hash_get_first(maps); n; n = dm_hash_get_next(maps, n)) {
lvm = (struct lv_map *) dm_hash_get_data(maps, n);
if (!_check_single_map(lvm)) {
stack;
return 0;
}
if (!_check_single_map(lvm))
return_0;
}
return 1;
}
@@ -216,10 +212,8 @@ static int _read_linear(struct cmd_context *cmd, struct lv_map *lvm)
struct lv_segment *seg;
struct segment_type *segtype;
if (!(segtype = get_segtype_from_string(cmd, "striped"))) {
stack;
return 0;
}
if (!(segtype = get_segtype_from_string(cmd, "striped")))
return_0;
while (le < lvm->lv->le_count) {
len = _area_length(lvm, le);
@@ -286,7 +280,7 @@ static int _read_stripes(struct cmd_context *cmd, struct lv_map *lvm)
while (first_area_le < total_area_len) {
area_len = 1;
/*
/*
* Find how many extents are contiguous in all stripes
* and so can form part of this segment
*/
@@ -334,10 +328,8 @@ static int _build_all_segments(struct cmd_context *cmd, struct dm_hash_table *ma
for (n = dm_hash_get_first(maps); n; n = dm_hash_get_next(maps, n)) {
lvm = (struct lv_map *) dm_hash_get_data(maps, n);
if (!_build_segments(cmd, lvm)) {
stack;
return 0;
}
if (!_build_segments(cmd, lvm))
return_0;
}
return 1;
@@ -350,10 +342,8 @@ int import_extents(struct cmd_context *cmd, struct volume_group *vg,
struct dm_pool *scratch = dm_pool_create("lvm1 import_extents", 10 * 1024);
struct dm_hash_table *maps;
if (!scratch) {
stack;
return 0;
}
if (!scratch)
return_0;
if (!(maps = _create_lv_maps(scratch, vg))) {
log_err("Couldn't allocate logical volume maps.");
@@ -365,10 +355,8 @@ int import_extents(struct cmd_context *cmd, struct volume_group *vg,
goto out;
}
if (!_check_maps_are_complete(maps) && !(vg->status & PARTIAL_VG)) {
stack;
goto out;
}
if (!_check_maps_are_complete(maps) && !(vg->status & PARTIAL_VG))
goto_out;
if (!_build_all_segments(cmd, maps)) {
log_err("Couldn't build extent segments.");

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -122,10 +122,8 @@ int calculate_extent_count(struct physical_volume *pv, uint32_t extent_size,
struct pv_disk *pvd = dm_malloc(sizeof(*pvd));
uint32_t end;
if (!pvd) {
stack;
return 0;
}
if (!pvd)
return_0;
/*
* Guess how many extents will fit, bearing in mind that

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -19,7 +19,7 @@
#include "label.h"
#include "metadata.h"
#include "xlate.h"
#include "lvmcache.h"
#include "format1.h"
#include <sys/stat.h>
#include <fcntl.h>
@@ -60,21 +60,23 @@ static int _lvm1_read(struct labeller *l, struct device *dev, void *buf,
struct pv_disk *pvd = (struct pv_disk *) buf;
struct vg_disk vgd;
struct lvmcache_info *info;
const char *vgid = NULL;
const char *vgid = FMT_LVM1_ORPHAN_VG_NAME;
const char *vgname = FMT_LVM1_ORPHAN_VG_NAME;
unsigned exported = 0;
munge_pvd(dev, pvd);
if (*pvd->vg_name && read_vgd(dev, &vgd, pvd)) {
if (*pvd->vg_name) {
if (!read_vgd(dev, &vgd, pvd))
return_0;
vgid = (char *) vgd.vg_uuid;
vgname = (char *) pvd->vg_name;
exported = pvd->pv_status & VG_EXPORTED;
}
if (!(info = lvmcache_add(l, (char *)pvd->pv_uuid, dev, (char *)pvd->vg_name, vgid,
exported))) {
stack;
return 0;
}
if (!(info = lvmcache_add(l, (char *)pvd->pv_uuid, dev, vgname, vgid,
exported)))
return_0;
*label = info->label;
info->device_size = xlate32(pvd->pv_size) << SECTOR_SHIFT;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -33,15 +33,11 @@ int get_free_vg_number(struct format_instance *fid, struct dev_filter *filter,
list_init(&all_pvs);
if (!mem) {
stack;
return 0;
}
if (!mem)
return_0;
if (!read_pvs_in_vg(fid->fmt, NULL, filter, mem, &all_pvs)) {
stack;
goto out;
}
if (!read_pvs_in_vg(fid->fmt, NULL, filter, mem, &all_pvs))
goto_out;
memset(numbers, 0, sizeof(numbers));

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -45,10 +45,8 @@ static int __read_pool_disk(const struct format_type *fmt, struct device *dev,
return 0;
}
if (!read_pool_label(pl, fmt->labeller, dev, buf, NULL)) {
stack;
return 0;
}
if (!read_pool_label(pl, fmt->labeller, dev, buf, NULL))
return_0;
return 1;
}
@@ -98,10 +96,8 @@ int read_pool_label(struct pool_list *pl, struct labeller *l,
log_debug("Calculated uuid %s for %s", uuid, pd->pl_pool_name);
if (!(info = lvmcache_add(l, (char *) &pvid, dev, pd->pl_pool_name,
(char *) &vgid, 0))) {
stack;
return 0;
}
(char *) &vgid, 0)))
return_0;
if (label)
*label = info->label;
@@ -252,10 +248,8 @@ static int _read_vg_pds(const struct format_type *fmt, struct dm_pool *mem,
/* FIXME: maybe should return a different error in memory
* allocation failure */
if (!(tmpmem = dm_pool_create("pool read_vg", 512))) {
stack;
return 0;
}
if (!(tmpmem = dm_pool_create("pool read_vg", 512)))
return_0;
list_iterate_items(info, &vginfo->infos) {
if (info->dev &&
@@ -354,20 +348,16 @@ struct pool_list *read_pool_disk(const struct format_type *fmt,
{
struct pool_list *pl;
if (!dev_open(dev)) {
stack;
return NULL;
}
if (!dev_open(dev))
return_NULL;
if (!(pl = dm_pool_zalloc(mem, sizeof(*pl)))) {
log_error("Unable to allocate pool list structure");
return 0;
}
if (!__read_pool_disk(fmt, dev, mem, pl, vg_name)) {
stack;
return NULL;
}
if (!__read_pool_disk(fmt, dev, mem, pl, vg_name))
return_NULL;
if (!dev_close(dev))
stack;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -24,8 +24,6 @@
#include "format_pool.h"
#include "pool_label.h"
#define FMT_POOL_NAME "pool"
/* Must be called after pvs are imported */
static struct user_subpool *_build_usp(struct list *pls, struct dm_pool *mem,
int *sps)
@@ -128,44 +126,32 @@ static struct volume_group *_build_vg_from_pds(struct format_instance
list_init(&vg->lvs);
list_init(&vg->tags);
if (!import_pool_vg(vg, smem, pds)) {
stack;
return NULL;
}
if (!import_pool_vg(vg, smem, pds))
return_NULL;
if (!import_pool_pvs(fid->fmt, vg, &vg->pvs, smem, pds)) {
stack;
return NULL;
}
if (!import_pool_pvs(fid->fmt, vg, &vg->pvs, smem, pds))
return_NULL;
if (!import_pool_lvs(vg, smem, pds)) {
stack;
return NULL;
}
if (!import_pool_lvs(vg, smem, pds))
return_NULL;
/*
* I need an intermediate subpool structure that contains all the
* relevant info for this. Then i can iterate through the subpool
* structures for checking, and create the segments
*/
if (!(usp = _build_usp(pds, mem, &sp_count))) {
stack;
return NULL;
}
if (!(usp = _build_usp(pds, mem, &sp_count)))
return_NULL;
/*
* check the subpool structures - we can't handle partial VGs in
* the pool format, so this will error out if we're missing PVs
*/
if (!_check_usp(vg->name, usp, sp_count)) {
stack;
return NULL;
}
if (!_check_usp(vg->name, usp, sp_count))
return_NULL;
if (!import_pool_segments(&vg->lvs, smem, usp, sp_count)) {
stack;
return NULL;
}
if (!import_pool_segments(&vg->lvs, smem, usp, sp_count))
return_NULL;
return vg;
}
@@ -182,25 +168,19 @@ static struct volume_group *_pool_vg_read(struct format_instance *fid,
/* We can safely ignore the mda passed in */
if (!mem) {
stack;
return NULL;
}
if (!mem)
return_NULL;
/* Strip dev_dir if present */
vg_name = strip_dir(vg_name, fid->fmt->cmd->dev_dir);
/* Read all the pvs in the vg */
if (!read_pool_pds(fid->fmt, vg_name, mem, &pds)) {
stack;
goto out;
}
if (!read_pool_pds(fid->fmt, vg_name, mem, &pds))
goto_out;
/* Do the rest of the vg stuff */
if (!(vg = _build_vg_from_pds(fid, mem, &pds))) {
stack;
goto out;
}
if (!(vg = _build_vg_from_pds(fid, mem, &pds)))
goto_out;
out:
dm_pool_destroy(mem);
@@ -231,30 +211,22 @@ static int _pool_pv_read(const struct format_type *fmt, const char *pv_name,
log_very_verbose("Reading physical volume data %s from disk", pv_name);
if (!mem) {
stack;
return 0;
}
if (!mem)
return_0;
if (!(dev = dev_cache_get(pv_name, fmt->cmd->filter))) {
stack;
goto out;
}
if (!(dev = dev_cache_get(pv_name, fmt->cmd->filter)))
goto_out;
/*
* I need to read the disk and populate a pv structure here
* I'll probably need to abstract some of this later for the
* vg_read code
*/
if (!(pl = read_pool_disk(fmt, dev, mem, NULL))) {
stack;
goto out;
}
if (!(pl = read_pool_disk(fmt, dev, mem, NULL)))
goto_out;
if (!import_pool_pv(fmt, fmt->cmd->mem, NULL, pv, pl)) {
stack;
goto out;
}
if (!import_pool_pv(fmt, fmt->cmd->mem, NULL, pv, pl))
goto_out;
pv->fmt = fmt;
@@ -342,6 +314,7 @@ struct format_type *init_format(struct cmd_context *cmd)
fmt->ops = &_format_pool_ops;
fmt->name = FMT_POOL_NAME;
fmt->alias = NULL;
fmt->orphan_vg_name = FMT_POOL_ORPHAN_VG_NAME;
fmt->features = 0;
fmt->private = NULL;

View File

@@ -18,6 +18,9 @@
#include "metadata.h"
#define FMT_POOL_NAME "pool"
#define FMT_POOL_ORPHAN_VG_NAME ORPHAN_VG_NAME(FMT_POOL_NAME)
#ifdef POOL_INTERNAL
struct format_type *init_pool_format(struct cmd_context *cmd);
#endif

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -83,6 +83,7 @@ int import_pool_lvs(struct volume_group *vg, struct dm_pool *mem, struct list *p
list_init(&lv->snapshot_segs);
list_init(&lv->segments);
list_init(&lv->tags);
list_init(&lv->segs_using_this_lv);
list_iterate_items(pl, pls) {
lv->size += pl->pd.pl_blocks;
@@ -90,10 +91,8 @@ int import_pool_lvs(struct volume_group *vg, struct dm_pool *mem, struct list *p
if (lv->name)
continue;
if (!(lv->name = dm_pool_strdup(mem, pl->pd.pl_pool_name))) {
stack;
return 0;
}
if (!(lv->name = dm_pool_strdup(mem, pl->pd.pl_pool_name)))
return_0;
get_pool_lv_uuid(lv->lvid.id, &pl->pd);
log_debug("Calculated lv uuid for lv %s: %s", lv->name,
@@ -177,10 +176,8 @@ int import_pool_pv(const struct format_type *fmt, struct dm_pool *mem,
list_init(&pv->tags);
list_init(&pv->segments);
if (!alloc_pv_segment_whole_pv(mem, pv)) {
stack;
return 0;
}
if (!alloc_pv_segment_whole_pv(mem, pv))
return_0;
return 1;
}
@@ -215,12 +212,10 @@ static int _add_stripe_seg(struct dm_pool *mem,
area_len = (usp->devs[0].blocks) / POOL_PE_SIZE;
if (!(segtype = get_segtype_from_string(lv->vg->cmd,
"striped"))) {
stack;
return 0;
}
"striped")))
return_0;
if (!(seg = alloc_lv_segment(mem, segtype, lv, *le_cur,
if (!(seg = alloc_lv_segment(mem, segtype, lv, *le_cur,
area_len * usp->num_devs, 0,
usp->striping, NULL, usp->num_devs,
area_len, 0, 0, 0))) {
@@ -229,10 +224,8 @@ static int _add_stripe_seg(struct dm_pool *mem,
}
for (j = 0; j < usp->num_devs; j++)
if (!set_lv_segment_area_pv(seg, j, usp->devs[j].pv, 0)) {
stack;
return 0;
}
if (!set_lv_segment_area_pv(seg, j, usp->devs[j].pv, 0))
return_0;
/* add the subpool type to the segment tag list */
str_list_add(mem, &seg->tags, _cvt_sptype(usp->type));
@@ -253,10 +246,8 @@ static int _add_linear_seg(struct dm_pool *mem,
unsigned j;
uint32_t area_len;
if (!(segtype = get_segtype_from_string(lv->vg->cmd, "striped"))) {
stack;
return 0;
}
if (!(segtype = get_segtype_from_string(lv->vg->cmd, "striped")))
return_0;
for (j = 0; j < usp->num_devs; j++) {
area_len = (usp->devs[j].blocks) / POOL_PE_SIZE;
@@ -273,10 +264,8 @@ static int _add_linear_seg(struct dm_pool *mem,
/* add the subpool type to the segment tag list */
str_list_add(mem, &seg->tags, _cvt_sptype(usp->type));
if (!set_lv_segment_area_pv(seg, 0, usp->devs[j].pv, 0)) {
stack;
return 0;
}
if (!set_lv_segment_area_pv(seg, 0, usp->devs[j].pv, 0))
return_0;
list_add(&lv->segments, &seg->list);
*le_cur += seg->len;
@@ -301,15 +290,11 @@ int import_pool_segments(struct list *lvs, struct dm_pool *mem,
for (i = 0; i < subpools; i++) {
if (usp[i].striping) {
if (!_add_stripe_seg(mem, &usp[i], lv, &le_cur)) {
stack;
return 0;
}
if (!_add_stripe_seg(mem, &usp[i], lv, &le_cur))
return_0;
} else {
if (!_add_linear_seg(mem, &usp[i], lv, &le_cur)) {
stack;
return 0;
}
if (!_add_linear_seg(mem, &usp[i], lv, &le_cur))
return_0;
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -113,10 +113,8 @@ static char *_join_file_to_dir(struct dm_pool *mem, const char *dir, const char
!dm_pool_grow_object(mem, dir, strlen(dir)) ||
!dm_pool_grow_object(mem, "/", 1) ||
!dm_pool_grow_object(mem, name, strlen(name)) ||
!dm_pool_grow_object(mem, "\0", 1)) {
stack;
return NULL;
}
!dm_pool_grow_object(mem, "\0", 1))
return_NULL;
return dm_pool_end_object(mem);
}
@@ -134,10 +132,8 @@ static struct list *_scan_archive(struct dm_pool *mem,
struct archive_file *af;
struct list *results;
if (!(results = dm_pool_alloc(mem, sizeof(*results)))) {
stack;
return NULL;
}
if (!(results = dm_pool_alloc(mem, sizeof(*results))))
return_NULL;
list_init(results);
@@ -161,10 +157,8 @@ static struct list *_scan_archive(struct dm_pool *mem,
if (strcmp(vgname, vgname_found))
continue;
if (!(path = _join_file_to_dir(mem, dir, dirent[i]->d_name))) {
stack;
goto out;
}
if (!(path = _join_file_to_dir(mem, dir, dirent[i]->d_name)))
goto_out;
/*
* Create a new archive_file.
@@ -255,10 +249,9 @@ int archive_vg(struct volume_group *vg,
}
if (!text_vg_export_file(vg, desc, fp)) {
stack;
if (fclose(fp))
log_sys_error("fclose", temp_file);
return 0;
return_0;
}
if (lvm_fclose(fp, temp_file))
@@ -267,10 +260,8 @@ int archive_vg(struct volume_group *vg,
/*
* Now we want to rename this file to <vg>_index.vg.
*/
if (!(archives = _scan_archive(vg->cmd->mem, vg->name, dir))) {
stack;
return 0;
}
if (!(archives = _scan_archive(vg->cmd->mem, vg->name, dir)))
return_0;
if (list_empty(archives))
ix = 0;
@@ -343,10 +334,8 @@ int archive_list(struct cmd_context *cmd, const char *dir, const char *vgname)
struct list *archives;
struct archive_file *af;
if (!(archives = _scan_archive(cmd->mem, vgname, dir))) {
stack;
return 0;
}
if (!(archives = _scan_archive(cmd->mem, vgname, dir)))
return_0;
if (list_empty(archives))
log_print("No archives found in %s.", dir);
@@ -379,10 +368,8 @@ int backup_list(struct cmd_context *cmd, const char *dir, const char *vgname)
{
struct archive_file af;
if (!(af.path = _join_file_to_dir(cmd->mem, dir, vgname))) {
stack;
return 0;
}
if (!(af.path = _join_file_to_dir(cmd->mem, dir, vgname)))
return_0;
if (path_exists(af.path))
_display_archive(cmd, &af);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -78,17 +78,13 @@ static char *_build_desc(struct dm_pool *mem, const char *line, int before)
size_t len = strlen(line) + 32;
char *buffer;
if (!(buffer = dm_pool_zalloc(mem, strlen(line) + 32))) {
stack;
return NULL;
}
if (!(buffer = dm_pool_zalloc(mem, strlen(line) + 32)))
return_NULL;
if (snprintf(buffer, len,
"Created %s executing '%s'",
before ? "*before*" : "*after*", line) < 0) {
stack;
return NULL;
}
before ? "*before*" : "*after*", line) < 0)
return_NULL;
return buffer;
}
@@ -97,10 +93,8 @@ static int __archive(struct volume_group *vg)
{
char *desc;
if (!(desc = _build_desc(vg->cmd->mem, vg->cmd->cmd_line, 1))) {
stack;
return 0;
}
if (!(desc = _build_desc(vg->cmd->mem, vg->cmd->cmd_line, 1)))
return_0;
return archive_vg(vg, vg->cmd->archive_params->dir, desc,
vg->cmd->archive_params->keep_days,
@@ -121,9 +115,9 @@ int archive(struct volume_group *vg)
return 0;
/* Trap a read-only file system */
if ((access(vg->cmd->archive_params->dir, R_OK | W_OK | X_OK) == -1) &&
if ((access(vg->cmd->archive_params->dir, R_OK | W_OK | X_OK) == -1) &&
(errno == EROFS))
return 0;
return 0;
log_verbose("Archiving volume group \"%s\" metadata (seqno %u).", vg->name,
vg->seqno);
@@ -196,10 +190,8 @@ static int __backup(struct volume_group *vg)
char name[PATH_MAX];
char *desc;
if (!(desc = _build_desc(vg->cmd->mem, vg->cmd->cmd_line, 0))) {
stack;
return 0;
}
if (!(desc = _build_desc(vg->cmd->mem, vg->cmd->cmd_line, 0)))
return_0;
if (dm_snprintf(name, sizeof(name), "%s/%s",
vg->cmd->backup_params->dir, vg->name) < 0) {
@@ -227,9 +219,9 @@ int backup(struct volume_group *vg)
return 0;
/* Trap a read-only file system */
if ((access(vg->cmd->backup_params->dir, R_OK | W_OK | X_OK) == -1) &&
if ((access(vg->cmd->backup_params->dir, R_OK | W_OK | X_OK) == -1) &&
(errno == EROFS))
return 0;
return 0;
if (!__backup(vg)) {
log_error("Backup of volume group %s metadata failed.",
@@ -305,7 +297,7 @@ int backup_restore_vg(struct cmd_context *cmd, struct volume_group *vg)
/* Add any metadata areas on the PVs */
list_iterate_items(pvl, &vg->pvs) {
pv = pvl->pv;
if (!(info = info_from_pvid(pv->dev->pvid))) {
if (!(info = info_from_pvid(pv->dev->pvid, 0))) {
log_error("PV %s missing from cache",
pv_dev_name(pv));
return 0;
@@ -324,10 +316,8 @@ int backup_restore_vg(struct cmd_context *cmd, struct volume_group *vg)
}
}
if (!vg_write(vg) || !vg_commit(vg)) {
stack;
return 0;
}
if (!vg_write(vg) || !vg_commit(vg))
return_0;
return 1;
}
@@ -341,10 +331,8 @@ int backup_restore_from_file(struct cmd_context *cmd, const char *vg_name,
/*
* Read in the volume group from the text file.
*/
if (!(vg = backup_read_vg(cmd, vg_name, file))) {
stack;
return 0;
}
if (!(vg = backup_read_vg(cmd, vg_name, file)))
return_0;
return backup_restore_vg(cmd, vg);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -37,7 +37,7 @@ typedef int (*nl_fn) (struct formatter * f);
* Then argument list is reset and out_with_comment_fn is called again.
*/
#define _out_with_comment(f, buffer, fmt, ap) \
do { \
do { \
va_start(ap, fmt); \
r = f->out_with_comment(f, buffer, fmt, ap); \
va_end(ap); \
@@ -135,10 +135,8 @@ static int _nl_raw(struct formatter *f)
{
/* If metadata doesn't fit, extend buffer */
if ((f->data.buf.used + 2 > f->data.buf.size) &&
(!_extend_buffer(f))) {
stack;
return 0;
}
(!_extend_buffer(f)))
return_0;
*(f->data.buf.start + f->data.buf.used) = '\n';
f->data.buf.used += 1;
@@ -195,10 +193,8 @@ static int _out_with_comment_raw(struct formatter *f,
/* If metadata doesn't fit, extend buffer */
if (n < 0 || (n + f->data.buf.used + 2 > f->data.buf.size)) {
if (!_extend_buffer(f)) {
stack;
return 0;
}
if (!_extend_buffer(f))
return_0;
return -1; /* Retry */
}
@@ -300,6 +296,7 @@ int out_text(struct formatter *f, const char *fmt, ...)
static int _print_header(struct formatter *f,
const char *desc)
{
char *buf;
time_t t;
t = time(NULL);
@@ -309,7 +306,12 @@ static int _print_header(struct formatter *f,
outf(f, FORMAT_VERSION_FIELD " = %d", FORMAT_VERSION_VALUE);
outnl(f);
outf(f, "description = \"%s\"", desc);
if (!(buf = alloca(escaped_len(desc)))) {
log_error("temporary stack allocation for description"
"string failed");
return 0;
}
outf(f, "description = \"%s\"", escape_double_quotes(buf, desc));
outnl(f);
outf(f, "creation_host = \"%s\"\t# %s %s %s %s %s", _utsname.nodename,
_utsname.sysname, _utsname.nodename, _utsname.release,
@@ -323,26 +325,20 @@ static int _print_vg(struct formatter *f, struct volume_group *vg)
{
char buffer[4096];
if (!id_write_format(&vg->id, buffer, sizeof(buffer))) {
stack;
return 0;
}
if (!id_write_format(&vg->id, buffer, sizeof(buffer)))
return_0;
outf(f, "id = \"%s\"", buffer);
outf(f, "seqno = %u", vg->seqno);
if (!print_flags(vg->status, VG_FLAGS, buffer, sizeof(buffer))) {
stack;
return 0;
}
if (!print_flags(vg->status, VG_FLAGS, buffer, sizeof(buffer)))
return_0;
outf(f, "status = %s", buffer);
if (!list_empty(&vg->tags)) {
if (!print_tags(&vg->tags, buffer, sizeof(buffer))) {
stack;
return 0;
}
if (!print_tags(&vg->tags, buffer, sizeof(buffer)))
return_0;
outf(f, "tags = %s", buffer);
}
@@ -350,10 +346,8 @@ static int _print_vg(struct formatter *f, struct volume_group *vg)
outf(f, "system_id = \"%s\"", vg->system_id);
if (!out_size(f, (uint64_t) vg->extent_size, "extent_size = %u",
vg->extent_size)) {
stack;
return 0;
}
vg->extent_size))
return_0;
outf(f, "max_lv = %u", vg->max_lv);
outf(f, "max_pv = %u", vg->max_pv);
@@ -382,6 +376,7 @@ static int _print_pvs(struct formatter *f, struct volume_group *vg)
struct pv_list *pvl;
struct physical_volume *pv;
char buffer[4096];
char *buf;
const char *name;
outf(f, "physical_volumes {");
@@ -390,52 +385,46 @@ static int _print_pvs(struct formatter *f, struct volume_group *vg)
list_iterate_items(pvl, &vg->pvs) {
pv = pvl->pv;
if (!(name = _get_pv_name(f, pv))) {
stack;
return 0;
}
if (!(name = _get_pv_name(f, pv)))
return_0;
outnl(f);
outf(f, "%s {", name);
_inc_indent(f);
if (!id_write_format(&pv->id, buffer, sizeof(buffer))) {
stack;
return 0;
}
if (!id_write_format(&pv->id, buffer, sizeof(buffer)))
return_0;
outf(f, "id = \"%s\"", buffer);
if (!out_hint(f, "device = \"%s\"", pv_dev_name(pv))) {
stack;
if (!(buf = alloca(escaped_len(pv_dev_name(pv))))) {
log_error("temporary stack allocation for device name"
"string failed");
return 0;
}
if (!out_hint(f, "device = \"%s\"",
escape_double_quotes(buf, pv_dev_name(pv))))
return_0;
outnl(f);
if (!print_flags(pv->status, PV_FLAGS, buffer, sizeof(buffer))) {
stack;
return 0;
}
if (!print_flags(pv->status, PV_FLAGS, buffer, sizeof(buffer)))
return_0;
outf(f, "status = %s", buffer);
if (!list_empty(&pv->tags)) {
if (!print_tags(&pv->tags, buffer, sizeof(buffer))) {
stack;
return 0;
}
if (!print_tags(&pv->tags, buffer, sizeof(buffer)))
return_0;
outf(f, "tags = %s", buffer);
}
if (!out_size(f, pv->size, "dev_size = %" PRIu64, pv->size)) {
stack;
return 0;
}
if (!out_size(f, pv->size, "dev_size = %" PRIu64, pv->size))
return_0;
outf(f, "pe_start = %" PRIu64, pv->pe_start);
if (!out_size(f, vg->extent_size * (uint64_t) pv->pe_count,
"pe_count = %u", pv->pe_count)) {
stack;
return 0;
}
"pe_count = %u", pv->pe_count))
return_0;
_dec_indent(f);
outf(f, "}");
@@ -456,27 +445,21 @@ static int _print_segment(struct formatter *f, struct volume_group *vg,
outf(f, "start_extent = %u", seg->le);
if (!out_size(f, (uint64_t) seg->len * vg->extent_size,
"extent_count = %u", seg->len)) {
stack;
return 0;
}
"extent_count = %u", seg->len))
return_0;
outnl(f);
outf(f, "type = \"%s\"", seg->segtype->name);
if (!list_empty(&seg->tags)) {
if (!print_tags(&seg->tags, buffer, sizeof(buffer))) {
stack;
return 0;
}
if (!print_tags(&seg->tags, buffer, sizeof(buffer)))
return_0;
outf(f, "tags = %s", buffer);
}
if (seg->segtype->ops->text_export &&
!seg->segtype->ops->text_export(seg, f)) {
stack;
return 0;
}
!seg->segtype->ops->text_export(seg, f))
return_0;
_dec_indent(f);
outf(f, "}");
@@ -498,10 +481,8 @@ int out_areas(struct formatter *f, const struct lv_segment *seg,
for (s = 0; s < seg->area_count; s++) {
switch (seg_type(seg, s)) {
case AREA_PV:
if (!(name = _get_pv_name(f, seg_pv(seg, s)))) {
stack;
return 0;
}
if (!(name = _get_pv_name(f, seg_pv(seg, s))))
return_0;
outf(f, "\"%s\", %u%s", name,
seg_pe(seg, s),
@@ -534,24 +515,18 @@ static int _print_lv(struct formatter *f, struct logical_volume *lv)
_inc_indent(f);
/* FIXME: Write full lvid */
if (!id_write_format(&lv->lvid.id[1], buffer, sizeof(buffer))) {
stack;
return 0;
}
if (!id_write_format(&lv->lvid.id[1], buffer, sizeof(buffer)))
return_0;
outf(f, "id = \"%s\"", buffer);
if (!print_flags(lv->status, LV_FLAGS, buffer, sizeof(buffer))) {
stack;
return 0;
}
if (!print_flags(lv->status, LV_FLAGS, buffer, sizeof(buffer)))
return_0;
outf(f, "status = %s", buffer);
if (!list_empty(&lv->tags)) {
if (!print_tags(&lv->tags, buffer, sizeof(buffer))) {
stack;
return 0;
}
if (!print_tags(&lv->tags, buffer, sizeof(buffer)))
return_0;
outf(f, "tags = %s", buffer);
}
@@ -579,10 +554,8 @@ static int _print_lv(struct formatter *f, struct logical_volume *lv)
seg_count = 1;
list_iterate_items(seg, &lv->segments) {
if (!_print_segment(f, lv->vg, seg_count++, seg)) {
stack;
return 0;
}
if (!_print_segment(f, lv->vg, seg_count++, seg))
return_0;
}
_dec_indent(f);
@@ -610,19 +583,15 @@ static int _print_lvs(struct formatter *f, struct volume_group *vg)
list_iterate_items(lvl, &vg->lvs) {
if (!(lvl->lv->status & VISIBLE_LV))
continue;
if (!_print_lv(f, lvl->lv)) {
stack;
return 0;
}
if (!_print_lv(f, lvl->lv))
return_0;
}
list_iterate_items(lvl, &vg->lvs) {
if ((lvl->lv->status & VISIBLE_LV))
continue;
if (!_print_lv(f, lvl->lv)) {
stack;
return 0;
}
if (!_print_lv(f, lvl->lv))
return_0;
}
_dec_indent(f);
@@ -671,10 +640,8 @@ static int _text_vg_export(struct formatter *f,
{
int r = 0;
if (!_build_pv_names(f, vg)) {
stack;
goto out;
}
if (!_build_pv_names(f, vg))
goto_out;
if (f->header && !_print_header(f, desc))
goto_out;
@@ -721,10 +688,8 @@ int text_vg_export_file(struct volume_group *vg, const char *desc, FILE *fp)
_init();
if (!(f = dm_malloc(sizeof(*f)))) {
stack;
return 0;
}
if (!(f = dm_malloc(sizeof(*f))))
return_0;
memset(f, 0, sizeof(*f));
f->data.fp = fp;
@@ -748,10 +713,8 @@ int text_vg_export_raw(struct volume_group *vg, const char *desc, char **buf)
_init();
if (!(f = dm_malloc(sizeof(*f)))) {
stack;
return 0;
}
if (!(f = dm_malloc(sizeof(*f))))
return_0;
memset(f, 0, sizeof(*f));
@@ -767,9 +730,8 @@ int text_vg_export_raw(struct volume_group *vg, const char *desc, char **buf)
f->nl = &_nl_raw;
if (!_text_vg_export(f, vg, desc)) {
stack;
dm_free(f->data.buf.start);
goto out;
goto_out;
}
r = f->data.buf.used + 1;
@@ -780,5 +742,10 @@ int text_vg_export_raw(struct volume_group *vg, const char *desc, char **buf)
return r;
}
int export_vg_to_buffer(struct volume_group *vg, char **buf)
{
return text_vg_export_raw(vg, "", buf);
}
#undef outf
#undef outnl

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -60,6 +60,7 @@ static struct flag _lv_flags[] = {
{VIRTUAL, NULL},
{SNAPSHOT, NULL},
{ACTIVATE_EXCL, NULL},
{CONVERTING, NULL},
{0, NULL}
};
@@ -90,10 +91,8 @@ int print_flags(uint32_t status, int type, char *buffer, size_t size)
int f, first = 1;
struct flag *flags;
if (!(flags = _get_flags(type))) {
stack;
return 0;
}
if (!(flags = _get_flags(type)))
return_0;
if (!emit_to_buffer(&buffer, &size, "["))
return 0;
@@ -134,10 +133,8 @@ int read_flags(uint32_t *status, int type, struct config_value *cv)
uint32_t s = 0;
struct flag *flags;
if (!(flags = _get_flags(type))) {
stack;
return 0;
}
if (!(flags = _get_flags(type)))
return_0;
if (cv->type == CFG_EMPTY_ARRAY)
goto out;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -36,9 +36,6 @@
#include <dirent.h>
#include <ctype.h>
#define FMT_TEXT_NAME "lvm2"
#define FMT_TEXT_ALIAS "text"
static struct mda_header *_raw_read_mda_header(const struct format_type *fmt,
struct device_area *dev_area);
@@ -250,7 +247,7 @@ static int _pv_analyze_mda_raw (const struct format_type * fmt,
static int _text_lv_setup(struct format_instance *fid __attribute((unused)),
struct logical_volume *lv)
{
/******** FIXME Any LV size restriction?
/******** FIXME Any LV size restriction?
uint64_t max_size = UINT_MAX;
if (lv->size > max_size) {
@@ -297,40 +294,38 @@ static struct mda_header *_raw_read_mda_header(const struct format_type *fmt,
return NULL;
}
if (!dev_read(dev_area->dev, dev_area->start, MDA_HEADER_SIZE, mdah)) {
stack;
goto error;
}
if (!dev_read(dev_area->dev, dev_area->start, MDA_HEADER_SIZE, mdah))
goto_bad;
if (mdah->checksum_xl != xlate32(calc_crc(INITIAL_CRC, mdah->magic,
MDA_HEADER_SIZE -
sizeof(mdah->checksum_xl)))) {
log_error("Incorrect metadata area header checksum");
goto error;
goto bad;
}
_xlate_mdah(mdah);
if (strncmp((char *)mdah->magic, FMTT_MAGIC, sizeof(mdah->magic))) {
log_error("Wrong magic number in metadata area header");
goto error;
goto bad;
}
if (mdah->version != FMTT_VERSION) {
log_error("Incompatible metadata area header version: %d",
mdah->version);
goto error;
goto bad;
}
if (mdah->start != dev_area->start) {
log_error("Incorrect start sector in metadata area header: %"
PRIu64, mdah->start);
goto error;
goto bad;
}
return mdah;
error:
bad:
dm_pool_free(fmt->cmd->mem, mdah);
return NULL;
}
@@ -349,9 +344,8 @@ static int _raw_write_mda_header(const struct format_type *fmt,
sizeof(mdah->checksum_xl)));
if (!dev_write(dev, start_byte, MDA_HEADER_SIZE, mdah)) {
stack;
dm_pool_free(fmt->cmd->mem, mdah);
return 0;
return_0;
}
return 1;
@@ -380,19 +374,18 @@ static struct raw_locn *_find_vg_rlocn(struct device_area *dev_area,
/* FIXME Loop through rlocns two-at-a-time. List null-terminated. */
/* FIXME Ignore if checksum incorrect!!! */
if (!dev_read(dev_area->dev, dev_area->start + rlocn->offset,
sizeof(vgnamebuf), vgnamebuf)) {
stack;
goto error;
}
sizeof(vgnamebuf), vgnamebuf))
goto_bad;
if (!strncmp(vgnamebuf, vgname, len = strlen(vgname)) &&
(isspace(vgnamebuf[len]) || vgnamebuf[len] == '{')) {
return rlocn;
}
error:
if ((info = info_from_pvid(dev_area->dev->pvid)))
lvmcache_update_vgname_and_id(info, ORPHAN, ORPHAN, 0, NULL);
bad:
if ((info = info_from_pvid(dev_area->dev->pvid, 0)))
lvmcache_update_vgname_and_id(info, FMT_TEXT_ORPHAN_VG_NAME,
FMT_TEXT_ORPHAN_VG_NAME, 0, NULL);
return NULL;
}
@@ -422,15 +415,11 @@ static int _raw_holds_vgname(struct format_instance *fid,
int noprecommit = 0;
struct mda_header *mdah;
if (!dev_open(dev_area->dev)) {
stack;
return 0;
}
if (!dev_open(dev_area->dev))
return_0;
if (!(mdah = _raw_read_mda_header(fid->fmt, dev_area))) {
stack;
return 0;
}
if (!(mdah = _raw_read_mda_header(fid->fmt, dev_area)))
return_0;
if (_find_vg_rlocn(dev_area, mdah, vgname, &noprecommit))
r = 1;
@@ -453,15 +442,11 @@ static struct volume_group *_vg_read_raw_area(struct format_instance *fid,
char *desc;
uint32_t wrap = 0;
if (!dev_open(area->dev)) {
stack;
return NULL;
}
if (!dev_open(area->dev))
return_NULL;
if (!(mdah = _raw_read_mda_header(fid->fmt, area))) {
stack;
goto out;
}
if (!(mdah = _raw_read_mda_header(fid->fmt, area)))
goto_out;
if (!(rlocn = _find_vg_rlocn(area, mdah, vgname, &precommitted))) {
log_debug("VG %s not found on %s", vgname, dev_name(area->dev));
@@ -483,10 +468,8 @@ static struct volume_group *_vg_read_raw_area(struct format_instance *fid,
(uint32_t) (rlocn->size - wrap),
(off_t) (area->start + MDA_HEADER_SIZE),
wrap, calc_crc, rlocn->checksum, &when,
&desc))) {
stack;
goto out;
}
&desc)))
goto_out;
log_debug("Read %s %smetadata (%u) from %s at %" PRIu64 " size %"
PRIu64, vg->name, precommitted ? "pre-commit " : "",
vg->seqno, dev_name(area->dev),
@@ -544,15 +527,11 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
if (!found)
return 1;
if (!dev_open(mdac->area.dev)) {
stack;
return 0;
}
if (!dev_open(mdac->area.dev))
return_0;
if (!(mdah = _raw_read_mda_header(fid->fmt, &mdac->area))) {
stack;
goto out;
}
if (!(mdah = _raw_read_mda_header(fid->fmt, &mdac->area)))
goto_out;
rlocn = _find_vg_rlocn(&mdac->area, mdah, vg->name, &noprecommit);
mdac->rlocn.offset = _next_rlocn_offset(rlocn, mdah);
@@ -589,10 +568,8 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
/* Write text out, circularly */
if (!dev_write(mdac->area.dev, mdac->area.start + mdac->rlocn.offset,
(size_t) (mdac->rlocn.size - new_wrap),
fidtc->raw_metadata_buf)) {
stack;
goto out;
}
fidtc->raw_metadata_buf))
goto_out;
if (new_wrap) {
log_debug("Writing metadata to %s at %" PRIu64 " len %" PRIu32,
@@ -602,11 +579,9 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
if (!dev_write(mdac->area.dev,
mdac->area.start + MDA_HEADER_SIZE,
(size_t) new_wrap,
fidtc->raw_metadata_buf +
mdac->rlocn.size - new_wrap)) {
stack;
goto out;
}
fidtc->raw_metadata_buf +
mdac->rlocn.size - new_wrap))
goto_out;
}
mdac->rlocn.checksum = calc_crc(INITIAL_CRC, fidtc->raw_metadata_buf,
@@ -652,10 +627,8 @@ static int _vg_commit_raw_rlocn(struct format_instance *fid,
if (!found)
return 1;
if (!(mdah = _raw_read_mda_header(fid->fmt, &mdac->area))) {
stack;
goto out;
}
if (!(mdah = _raw_read_mda_header(fid->fmt, &mdac->area)))
goto_out;
if (!(rlocn = _find_vg_rlocn(&mdac->area, mdah, vg->name, &noprecommit))) {
mdah->raw_locns[0].offset = 0;
@@ -759,15 +732,11 @@ static int _vg_remove_raw(struct format_instance *fid, struct volume_group *vg,
int r = 0;
int noprecommit = 0;
if (!dev_open(mdac->area.dev)) {
stack;
return 0;
}
if (!dev_open(mdac->area.dev))
return_0;
if (!(mdah = _raw_read_mda_header(fid->fmt, &mdac->area))) {
stack;
goto out;
}
if (!(mdah = _raw_read_mda_header(fid->fmt, &mdac->area)))
goto_out;
if (!(rlocn = _find_vg_rlocn(&mdac->area, mdah, vg->name, &noprecommit))) {
rlocn = &mdah->raw_locns[0];
@@ -801,10 +770,8 @@ static struct volume_group *_vg_read_file_name(struct format_instance *fid,
time_t when;
char *desc;
if (!(vg = text_vg_import_file(fid, read_path, &when, &desc))) {
stack;
return NULL;
}
if (!(vg = text_vg_import_file(fid, read_path, &when, &desc)))
return_NULL;
/*
* Currently you can only have a single volume group per
@@ -1038,7 +1005,7 @@ static int _scan_file(const struct format_type *fmt)
if ((vg = _vg_read_file_name(fid, vgname,
path)))
/* FIXME Store creation host in vg */
lvmcache_update_vg(vg);
lvmcache_update_vg(vg, 0);
}
if (closedir(d))
@@ -1065,10 +1032,8 @@ const char *vgname_from_mda(const struct format_type *fmt,
if (mda_free_sectors)
*mda_free_sectors = ((dev_area->size - MDA_HEADER_SIZE) / 2) >> SECTOR_SHIFT;
if (!dev_open(dev_area->dev)) {
stack;
return NULL;
}
if (!dev_open(dev_area->dev))
return_NULL;
if (!(mdah = _raw_read_mda_header(fmt, dev_area)))
goto_out;
@@ -1114,20 +1079,18 @@ const char *vgname_from_mda(const struct format_type *fmt,
/* Ignore this entry if the characters aren't permissible */
if (!validate_name(vgname)) {
stack;
vgname = NULL;
goto out;
goto_out;
}
if (!id_write_format(vgid, uuid, sizeof(uuid))) {
stack;
vgname = NULL;
goto out;
goto_out;
}
log_debug("%s: Found metadata at %" PRIu64 " size %" PRIu64
" (in area at %" PRIu64 " size %" PRIu64
") for %s (%s)",
") for %s (%s)",
dev_name(dev_area->dev), dev_area->start + rlocn->offset,
rlocn->size, dev_area->start, dev_area->size, vgname, uuid);
@@ -1170,7 +1133,7 @@ static int _scan_raw(const struct format_type *fmt)
NULL, NULL))) {
if ((vg = _vg_read_raw_area(&fid, vgname,
&rl->dev_area, 0)))
lvmcache_update_vg(vg);
lvmcache_update_vg(vg, 0);
}
}
@@ -1328,10 +1291,8 @@ static int _text_pv_write(const struct format_type *fmt, struct physical_volume
/* FIXME Test mode don't update cache? */
if (!(info = lvmcache_add(fmt->labeller, (char *) &pv->id, pv->dev,
ORPHAN, NULL, 0))) {
stack;
return 0;
}
FMT_TEXT_ORPHAN_VG_NAME, NULL, 0)))
return_0;
label = info->label;
if (label_sector != -1)
@@ -1367,7 +1328,7 @@ static int _text_pv_write(const struct format_type *fmt, struct physical_volume
else
list_init(&info->das);
/* Set pe_start to first aligned sector after any metadata
/* Set pe_start to first aligned sector after any metadata
* areas that begin before pe_start */
pv->pe_start = pe_align();
list_iterate_items(mda, &info->mdas) {
@@ -1384,15 +1345,11 @@ static int _text_pv_write(const struct format_type *fmt, struct physical_volume
}
}
if (!add_da
(NULL, &info->das, pv->pe_start << SECTOR_SHIFT, UINT64_C(0))) {
stack;
return 0;
}
(NULL, &info->das, pv->pe_start << SECTOR_SHIFT, UINT64_C(0)))
return_0;
if (!dev_open(pv->dev)) {
stack;
return 0;
}
if (!dev_open(pv->dev))
return_0;
list_iterate_items(mda, &info->mdas) {
mdac = mda->metadata_locn;
@@ -1400,19 +1357,16 @@ static int _text_pv_write(const struct format_type *fmt, struct physical_volume
mdah->size = mdac->area.size;
if (!_raw_write_mda_header(fmt, mdac->area.dev,
mdac->area.start, mdah)) {
stack;
if (!dev_close(pv->dev))
stack;
return 0;
return_0;
}
}
label_write(pv->dev, label);
if (!dev_close(pv->dev)) {
stack;
return 0;
}
if (!dev_close(pv->dev))
return_0;
return 1;
}
@@ -1449,16 +1403,12 @@ static int _text_pv_read(const struct format_type *fmt, const char *pv_name,
struct mda_context *mdac, *mdac_new;
struct data_area_list *da;
if (!(dev = dev_cache_get(pv_name, fmt->cmd->filter))) {
stack;
return 0;
}
if (!(dev = dev_cache_get(pv_name, fmt->cmd->filter)))
return_0;
/* FIXME Optimise out repeated reading when cache lock held */
if (!(label_read(dev, &label, UINT64_C(0)))) {
stack;
return 0;
}
if (!(label_read(dev, &label, UINT64_C(0))))
return_0;
info = (struct lvmcache_info *) label->info;
/* Have we already cached vgname? */
@@ -1486,7 +1436,7 @@ static int _text_pv_read(const struct format_type *fmt, const char *pv_name,
pv->dev = info->dev;
pv->fmt = info->fmt;
pv->size = info->device_size >> SECTOR_SHIFT;
pv->vg_name = ORPHAN;
pv->vg_name = FMT_TEXT_ORPHAN_VG_NAME;
memcpy(&pv->id, &info->dev->pvid, sizeof(pv->id));
/* Currently only support exactly one data area */
@@ -1610,7 +1560,7 @@ static int _text_pv_setup(const struct format_type *fmt,
/* If new vg, add any further mdas on this PV to the fid's mda list */
if (vg) {
/* Iterate through all mdas on this PV */
if ((info = info_from_pvid(pv->dev->pvid))) {
if ((info = info_from_pvid(pv->dev->pvid, 0))) {
pvmdas = &info->mdas;
list_iterate_items(mda, pvmdas) {
mda_count++;
@@ -1642,16 +1592,12 @@ static int _text_pv_setup(const struct format_type *fmt,
continue;
if (!(mda_new = dm_pool_alloc(fmt->cmd->mem,
sizeof(*mda_new)))) {
stack;
return 0;
}
sizeof(*mda_new))))
return_0;
if (!(mdac_new = dm_pool_alloc(fmt->cmd->mem,
sizeof(*mdac_new)))) {
stack;
return 0;
}
sizeof(*mdac_new))))
return_0;
/* FIXME multiple dev_areas inside area */
memcpy(mda_new, mda, sizeof(*mda));
memcpy(mdac_new, mdac, sizeof(*mdac));
@@ -1687,11 +1633,8 @@ static int _text_pv_setup(const struct format_type *fmt,
if (extent_count)
pe_end = pe_start + extent_count * extent_size - 1;
if (!_mda_setup(fmt, pe_start, pe_end, pvmetadatacopies,
pvmetadatasize, mdas, pv, vg)) {
stack;
return 0;
}
pvmetadatasize, mdas, pv, vg))
return_0;
}
return 1;
@@ -1732,10 +1675,8 @@ static struct format_instance *_text_create_text_instance(const struct format_ty
list_init(&fid->metadata_areas);
if (!vgname) {
if (!(mda = dm_pool_alloc(fmt->cmd->mem, sizeof(*mda)))) {
stack;
return NULL;
}
if (!(mda = dm_pool_alloc(fmt->cmd->mem, sizeof(*mda))))
return_NULL;
mda->ops = &_metadata_text_file_backup_ops;
mda->metadata_locn = context;
list_add(&fid->metadata_areas, &mda->list);
@@ -1751,10 +1692,8 @@ static struct format_instance *_text_create_text_instance(const struct format_ty
}
context = create_text_context(fmt->cmd, path, NULL);
if (!(mda = dm_pool_alloc(fmt->cmd->mem, sizeof(*mda)))) {
stack;
return NULL;
}
if (!(mda = dm_pool_alloc(fmt->cmd->mem, sizeof(*mda))))
return_NULL;
mda->ops = &_metadata_text_file_ops;
mda->metadata_locn = context;
list_add(&fid->metadata_areas, &mda->list);
@@ -1767,15 +1706,11 @@ static struct format_instance *_text_create_text_instance(const struct format_ty
if (!_raw_holds_vgname(fid, &rl->dev_area, vgname))
continue;
if (!(mda = dm_pool_alloc(fmt->cmd->mem, sizeof(*mda)))) {
stack;
return NULL;
}
if (!(mda = dm_pool_alloc(fmt->cmd->mem, sizeof(*mda))))
return_NULL;
if (!(mdac = dm_pool_alloc(fmt->cmd->mem, sizeof(*mdac)))) {
stack;
return NULL;
}
if (!(mdac = dm_pool_alloc(fmt->cmd->mem, sizeof(*mdac))))
return_NULL;
mda->metadata_locn = mdac;
/* FIXME Allow multiple dev_areas inside area */
memcpy(&mdac->area, &rl->dev_area, sizeof(mdac->area));
@@ -1786,10 +1721,8 @@ static struct format_instance *_text_create_text_instance(const struct format_ty
/* Scan PVs in VG for any further MDAs */
lvmcache_label_scan(fmt->cmd, 0);
if (!(vginfo = vginfo_from_vgname(vgname, vgid))) {
stack;
goto out;
}
if (!(vginfo = vginfo_from_vgname(vgname, vgid)))
goto_out;
list_iterate_items(info, &vginfo->infos) {
mdas = &info->mdas;
list_iterate_items(mda, mdas) {
@@ -1798,16 +1731,12 @@ static struct format_instance *_text_create_text_instance(const struct format_ty
/* FIXME Check it holds this VG */
if (!(mda_new = dm_pool_alloc(fmt->cmd->mem,
sizeof(*mda_new)))) {
stack;
return NULL;
}
sizeof(*mda_new))))
return_NULL;
if (!(mdac_new = dm_pool_alloc(fmt->cmd->mem,
sizeof(*mdac_new)))) {
stack;
return NULL;
}
sizeof(*mdac_new))))
return_NULL;
/* FIXME multiple dev_areas inside area */
memcpy(mda_new, mda, sizeof(*mda));
memcpy(mdac_new, mdac, sizeof(*mdac));
@@ -1834,33 +1763,26 @@ void *create_text_context(struct cmd_context *cmd, const char *path,
return NULL;
}
if (!(tc = dm_pool_alloc(cmd->mem, sizeof(*tc)))) {
stack;
return NULL;
}
if (!(tc = dm_pool_alloc(cmd->mem, sizeof(*tc))))
return_NULL;
if (!(tc->path_live = dm_pool_strdup(cmd->mem, path))) {
stack;
goto no_mem;
}
if (!(tc->path_live = dm_pool_strdup(cmd->mem, path)))
goto_bad;
if (!(tc->path_edit = dm_pool_alloc(cmd->mem, strlen(path) + 5)))
goto_bad;
if (!(tc->path_edit = dm_pool_alloc(cmd->mem, strlen(path) + 5))) {
stack;
goto no_mem;
}
sprintf(tc->path_edit, "%s.tmp", path);
if (!desc)
desc = "";
if (!(tc->desc = dm_pool_strdup(cmd->mem, desc))) {
stack;
goto no_mem;
}
if (!(tc->desc = dm_pool_strdup(cmd->mem, desc)))
goto_bad;
return (void *) tc;
no_mem:
bad:
dm_pool_free(cmd->mem, tc);
log_err("Couldn't allocate text format context object.");
@@ -1956,15 +1878,14 @@ struct format_type *create_text_format(struct cmd_context *cmd)
struct config_value *cv;
struct mda_lists *mda_lists;
if (!(fmt = dm_malloc(sizeof(*fmt)))) {
stack;
return NULL;
}
if (!(fmt = dm_malloc(sizeof(*fmt))))
return_NULL;
fmt->cmd = cmd;
fmt->ops = &_text_handler;
fmt->name = FMT_TEXT_NAME;
fmt->alias = FMT_TEXT_ALIAS;
fmt->orphan_vg_name = ORPHAN_VG_NAME(FMT_TEXT_NAME);
fmt->features = FMT_SEGMENTS | FMT_MDAS | FMT_TAGS | FMT_PRECOMMIT |
FMT_UNLIMITED_VOLS | FMT_RESIZE_PV |
FMT_UNLIMITED_STRIPESIZE;

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -86,6 +86,22 @@ static int _check_version(struct config_tree *cft)
return 1;
}
static int _is_converting(struct logical_volume *lv)
{
struct lv_segment *seg;
if (lv->status & MIRRORED) {
seg = first_seg(lv);
/* Can't use is_temporary_mirror() because the metadata for
* seg_lv may not be read in and flags may not be set yet. */
if (seg_type(seg, 0) == AREA_LV &&
strstr(seg_lv(seg, 0)->name, MIRROR_SYNC_LAYER))
return 1;
}
return 0;
}
static int _read_id(struct id *id, struct config_node *cn, const char *path)
{
struct config_value *cv;
@@ -120,10 +136,8 @@ static int _read_pv(struct format_instance *fid, struct dm_pool *mem,
uint64_t size;
if (!(pvl = dm_pool_zalloc(mem, sizeof(*pvl))) ||
!(pvl->pv = dm_pool_zalloc(mem, sizeof(*pvl->pv)))) {
stack;
return 0;
}
!(pvl->pv = dm_pool_zalloc(mem, sizeof(*pvl->pv))))
return_0;
pv = pvl->pv;
@@ -131,10 +145,8 @@ static int _read_pv(struct format_instance *fid, struct dm_pool *mem,
* Add the pv to the pv hash for quick lookup when we read
* the lv segments.
*/
if (!dm_hash_insert(pv_hash, pvn->key, pv)) {
stack;
return 0;
}
if (!dm_hash_insert(pv_hash, pvn->key, pv))
return_0;
if (!(pvn = pvn->child)) {
log_error("Empty pv section.");
@@ -164,10 +176,8 @@ static int _read_pv(struct format_instance *fid, struct dm_pool *mem,
return 0;
}
if (!(pv->vg_name = dm_pool_strdup(mem, vg->name))) {
stack;
return 0;
}
if (!(pv->vg_name = dm_pool_strdup(mem, vg->name)))
return_0;
memcpy(&pv->vgid, &vg->id, sizeof(vg->id));
@@ -215,30 +225,28 @@ static int _read_pv(struct format_instance *fid, struct dm_pool *mem,
pv->pe_alloc_count = 0;
pv->fmt = fid->fmt;
/* Fix up pv size if missing or impossibly large */
if ((!pv->size || pv->size > (1ULL << 62)) && pv->dev) {
if (!dev_get_size(pv->dev, &pv->size)) {
log_error("%s: Couldn't get size.", pv_dev_name(pv));
return 0;
}
log_verbose("Fixing up missing size (%s) "
"for PV %s", display_size(fid->fmt->cmd, pv->size),
pv_dev_name(pv));
if (vg) {
size = pv->pe_count * (uint64_t) vg->extent_size +
pv->pe_start;
if (size > pv->size)
log_error("WARNING: Physical Volume %s is too "
"large for underlying device",
pv_dev_name(pv));
}
}
if (!alloc_pv_segment_whole_pv(mem, pv)) {
stack;
return 0;
/* Fix up pv size if missing or impossibly large */
if ((!pv->size || pv->size > (1ULL << 62)) && pv->dev) {
if (!dev_get_size(pv->dev, &pv->size)) {
log_error("%s: Couldn't get size.", pv_dev_name(pv));
return 0;
}
log_verbose("Fixing up missing size (%s) "
"for PV %s", display_size(fid->fmt->cmd, pv->size),
pv_dev_name(pv));
if (vg) {
size = pv->pe_count * (uint64_t) vg->extent_size +
pv->pe_start;
if (size > pv->size)
log_error("WARNING: Physical Volume %s is too "
"large for underlying device",
pv_dev_name(pv));
}
}
if (!alloc_pv_segment_whole_pv(mem, pv))
return_0;
vg->pv_count++;
list_add(&vg->pvs, &pvl->list);
@@ -300,16 +308,12 @@ static int _read_segment(struct dm_pool *mem, struct volume_group *vg,
segtype_str = cv->v.str;
}
if (!(segtype = get_segtype_from_string(vg->cmd, segtype_str))) {
stack;
return 0;
}
if (!(segtype = get_segtype_from_string(vg->cmd, segtype_str)))
return_0;
if (segtype->ops->text_import_area_count &&
!segtype->ops->text_import_area_count(sn, &area_count)) {
stack;
return 0;
}
!segtype->ops->text_import_area_count(sn, &area_count))
return_0;
if (!(seg = alloc_lv_segment(mem, segtype, lv, start_extent,
extent_count, 0, 0, NULL, area_count,
@@ -319,10 +323,8 @@ static int _read_segment(struct dm_pool *mem, struct volume_group *vg,
}
if (seg->segtype->ops->text_import &&
!seg->segtype->ops->text_import(seg, sn, pv_hash)) {
stack;
return 0;
}
!seg->segtype->ops->text_import(seg, sn, pv_hash))
return_0;
/* Optional tags */
if ((cn = find_config_node(sn, "tags")) &&
@@ -343,6 +345,9 @@ static int _read_segment(struct dm_pool *mem, struct volume_group *vg,
if (seg_is_virtual(seg))
lv->status |= VIRTUAL;
if (_is_converting(lv))
lv->status |= CONVERTING;
return 1;
}
@@ -384,13 +389,13 @@ int text_import_areas(struct lv_segment *seg, const struct config_node *sn,
/* FIXME Cope if LV not yet read in */
if ((pv = dm_hash_lookup(pv_hash, cv->v.str))) {
if (!set_lv_segment_area_pv(seg, s, pv, (uint32_t) cv->next->v.i)) {
stack;
return 0;
}
if (!set_lv_segment_area_pv(seg, s, pv, (uint32_t) cv->next->v.i))
return_0;
} else if ((lv1 = find_lv(seg->lv->vg, cv->v.str))) {
set_lv_segment_area_lv(seg, s, lv1, (uint32_t) cv->next->v.i,
flags);
if (!set_lv_segment_area_lv(seg, s, lv1,
(uint32_t) cv->next->v.i,
flags))
return_0;
} else {
log_error("Couldn't find volume '%s' "
"for segment '%s'.",
@@ -426,10 +431,8 @@ static int _read_segments(struct dm_pool *mem, struct volume_group *vg,
* All sub-sections are assumed to be segments.
*/
if (!sn->v) {
if (!_read_segment(mem, vg, lv, sn, pv_hash)) {
stack;
return 0;
}
if (!_read_segment(mem, vg, lv, sn, pv_hash))
return_0;
count++;
}
@@ -454,18 +457,14 @@ static int _read_segments(struct dm_pool *mem, struct volume_group *vg,
/*
* Check there are no gaps or overlaps in the lv.
*/
if (!check_lv_segments(lv, 0)) {
stack;
return 0;
}
if (!check_lv_segments(lv, 0))
return_0;
/*
* Merge segments in case someones been editing things by hand.
*/
if (!lv_merge_segments(lv)) {
stack;
return 0;
}
if (!lv_merge_segments(lv))
return_0;
return 1;
}
@@ -481,17 +480,13 @@ static int _read_lvnames(struct format_instance *fid __attribute((unused)),
struct config_node *cn;
if (!(lvl = dm_pool_zalloc(mem, sizeof(*lvl))) ||
!(lvl->lv = dm_pool_zalloc(mem, sizeof(*lvl->lv)))) {
stack;
return 0;
}
!(lvl->lv = dm_pool_zalloc(mem, sizeof(*lvl->lv))))
return_0;
lv = lvl->lv;
if (!(lv->name = dm_pool_strdup(mem, lvn->key))) {
stack;
return 0;
}
if (!(lv->name = dm_pool_strdup(mem, lvn->key)))
return_0;
if (!(lvn = lvn->child)) {
log_error("Empty logical volume section.");
@@ -517,10 +512,8 @@ static int _read_lvnames(struct format_instance *fid __attribute((unused)),
}
lv->alloc = get_alloc_from_string(cv->v.str);
if (lv->alloc == ALLOC_INVALID) {
stack;
return 0;
}
if (lv->alloc == ALLOC_INVALID)
return_0;
}
if (!_read_int32(lvn, "read_ahead", &lv->read_ahead))
@@ -531,7 +524,7 @@ static int _read_lvnames(struct format_instance *fid __attribute((unused)),
case 0:
lv->read_ahead = DM_READ_AHEAD_AUTO;
break;
case -1:
case (uint32_t) -1:
lv->read_ahead = DM_READ_AHEAD_NONE;
break;
default:
@@ -543,6 +536,7 @@ static int _read_lvnames(struct format_instance *fid __attribute((unused)),
list_init(&lv->snapshot_segs);
list_init(&lv->segments);
list_init(&lv->tags);
list_init(&lv->segs_using_this_lv);
/* Optional tags */
if ((cn = find_config_node(lvn, "tags")) &&
@@ -589,10 +583,8 @@ static int _read_lvsegs(struct format_instance *fid __attribute((unused)),
memcpy(&lv->lvid.id[0], &lv->vg->id, sizeof(lv->lvid.id[0]));
if (!_read_segments(mem, vg, lv, lvn, pv_hash)) {
stack;
return 0;
}
if (!_read_segments(mem, vg, lv, lvn, pv_hash))
return_0;
lv->size = (uint64_t) lv->le_count * (uint64_t) vg->extent_size;
@@ -642,10 +634,8 @@ static int _read_sections(struct format_instance *fid,
}
for (n = n->child; n; n = n->sib) {
if (!fn(fid, mem, vg, n, vgn, pv_hash)) {
stack;
return 0;
}
if (!fn(fid, mem, vg, n, vgn, pv_hash))
return_0;
}
return 1;
@@ -667,10 +657,8 @@ static struct volume_group *_read_vg(struct format_instance *fid,
return NULL;
}
if (!(vg = dm_pool_zalloc(mem, sizeof(*vg)))) {
stack;
return NULL;
}
if (!(vg = dm_pool_zalloc(mem, sizeof(*vg))))
return_NULL;
vg->cmd = fid->fmt->cmd;
/* FIXME Determine format type from file contents */
@@ -748,10 +736,8 @@ static struct volume_group *_read_vg(struct format_instance *fid,
}
vg->alloc = get_alloc_from_string(cv->v.str);
if (vg->alloc == ALLOC_INVALID) {
stack;
return 0;
}
if (vg->alloc == ALLOC_INVALID)
return_0;
}
/*
@@ -848,7 +834,7 @@ static const char *_read_vgname(const struct format_type *fmt,
old_suppress = log_suppress(2);
*creation_host = dm_pool_strdup(mem,
find_config_str(cft->root,
"creation_host", ""));
"creation_host", ""));
log_suppress(old_suppress);
/* skip any top-level values */

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -207,7 +207,9 @@ static int _text_read(struct labeller *l, struct device *dev, void *buf,
pvhdr = (struct pv_header *) ((void *) buf + xlate32(lh->offset_xl));
if (!(info = lvmcache_add(l, (char *)pvhdr->pv_uuid, dev, NULL, NULL, 0)))
if (!(info = lvmcache_add(l, (char *)pvhdr->pv_uuid, dev,
FMT_TEXT_ORPHAN_VG_NAME,
FMT_TEXT_ORPHAN_VG_NAME, 0)))
return_0;
*label = info->label;
@@ -239,7 +241,7 @@ static int _text_read(struct labeller *l, struct device *dev, void *buf,
list_iterate_items(mda, &info->mdas) {
mdac = (struct mda_context *) mda->metadata_locn;
if ((vgname = vgname_from_mda(info->fmt, &mdac->area,
if ((vgname = vgname_from_mda(info->fmt, &mdac->area,
&vgid, &vgstatus, &creation_host,
&mdac->free_sectors)) &&
!lvmcache_update_vgname_and_id(info, vgname,

View File

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

View File

@@ -104,8 +104,8 @@ static int _send_request(char *inbuf, int inlen, char **retbuf)
/* Send it to CLVMD */
rewrite:
if ( (err = write(_clvmd_sock, inbuf, inlen)) != inlen) {
if (err == -1 && errno == EINTR)
goto rewrite;
if (err == -1 && errno == EINTR)
goto rewrite;
log_error("Error writing data to clvmd: %s", strerror(errno));
return 0;
}
@@ -113,8 +113,8 @@ static int _send_request(char *inbuf, int inlen, char **retbuf)
/* Get the response */
reread:
if ((len = read(_clvmd_sock, outbuf, sizeof(struct clvm_header))) < 0) {
if (errno == EINTR)
goto reread;
if (errno == EINTR)
goto reread;
log_error("Error reading data from clvmd: %s", strerror(errno));
return 0;
}
@@ -330,7 +330,7 @@ static int _lock_for_cluster(unsigned char cmd, uint32_t flags, const char *name
* locks are cluster-wide.
* Also, if the lock is exclusive it makes no sense to try to
* acquire it on all nodes, so just do that on the local node too.
* One exception, is that P_ locks /do/ get distributed across
* One exception, is that P_ locks /do/ get distributed across
* the cluster because they might have side-effects.
*/
if (strncmp(name, "P_", 2) &&
@@ -446,10 +446,10 @@ int lock_resource(struct cmd_context *cmd, const char *resource, uint32_t flags)
log_very_verbose("Locking %s %s %s %s%s%s%s (0x%x)", lock_scope, lockname,
lock_type,
flags & LCK_NONBLOCK ? "" : "B",
flags & LCK_HOLD ? "H" : "",
flags & LCK_LOCAL ? "L" : "",
flags & LCK_CLUSTER_VG ? "C" : "",
flags & LCK_NONBLOCK ? "" : "B",
flags & LCK_HOLD ? "H" : "",
flags & LCK_LOCAL ? "L" : "",
flags & LCK_CLUSTER_VG ? "C" : "",
flags);
/* Send a message to the cluster manager */
@@ -479,7 +479,7 @@ void reset_locking(void)
_clvmd_sock = _open_local_sock();
if (_clvmd_sock == -1)
stack;
stack;
}
#ifdef CLUSTER_LOCKING_INTERNAL

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -73,10 +73,8 @@ int init_external_locking(struct locking_type *locking, struct cmd_context *cmd)
libname = find_config_tree_str(cmd, "global/locking_library",
DEFAULT_LOCKING_LIB);
if (!(_locking_lib = load_shared_library(cmd, libname, "locking", 1))) {
stack;
return 0;
}
if (!(_locking_lib = load_shared_library(cmd, libname, "locking", 1)))
return_0;
/* Get the functions we need */
if (!(_init_fn = dlsym(_locking_lib, "locking_init")) ||

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -21,7 +21,6 @@
#include "defaults.h"
#include "lvm-file.h"
#include "lvm-string.h"
#include "lvmcache.h"
#include <limits.h>
#include <unistd.h>
@@ -221,17 +220,7 @@ static int _file_lock_resource(struct cmd_context *cmd, const char *resource,
"%s/V_%s", _lock_dir, resource);
if (!_lock_file(lockfile, flags))
return 0;
switch (flags & LCK_TYPE_MASK) {
case LCK_UNLOCK:
lvmcache_unlock_vgname(resource);
break;
default:
lvmcache_lock_vgname(resource,
(flags & LCK_TYPE_MASK) ==
LCK_READ);
}
return_0;
break;
case LCK_LV:
switch (flags & LCK_TYPE_MASK) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -21,6 +21,7 @@
#include "toolcontext.h"
#include "memlock.h"
#include "defaults.h"
#include "lvmcache.h"
#include <signal.h>
#include <sys/stat.h>
@@ -253,7 +254,7 @@ int init_locking(int type, struct cmd_context *cmd)
}
if ((type == 2 || type == 3) &&
find_config_tree_int(cmd, "locking/fallback_to_local_locking",
find_config_tree_int(cmd, "locking/fallback_to_local_locking",
DEFAULT_FALLBACK_TO_LOCAL_LOCKING)) {
log_warn("WARNING: Falling back to local file-based locking.");
log_warn("Volume Groups with the clustered attribute will "
@@ -315,22 +316,29 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname)
*/
static int _lock_vol(struct cmd_context *cmd, const char *resource, uint32_t flags)
{
int ret = 0;
_block_signals(flags);
_lock_memory(flags);
assert(resource);
if (!(_locking.lock_resource(cmd, resource, flags))) {
_unlock_memory(flags);
_unblock_signals();
return 0;
if ((ret = _locking.lock_resource(cmd, resource, flags))) {
if ((flags & LCK_SCOPE_MASK) == LCK_VG) {
if ((flags & LCK_TYPE_MASK) == LCK_UNLOCK)
lvmcache_unlock_vgname(resource);
else
lvmcache_lock_vgname(resource, (flags & LCK_TYPE_MASK)
== LCK_READ);
}
_update_vg_lock_count(flags);
}
_update_vg_lock_count(flags);
_unlock_memory(flags);
_unblock_signals();
return 1;
return ret;
}
int lock_vol(struct cmd_context *cmd, const char *vol, uint32_t flags)
@@ -404,19 +412,23 @@ int suspend_lvs(struct cmd_context *cmd, struct list *lvs)
}
/* Lock a list of LVs */
int activate_lvs_excl(struct cmd_context *cmd, struct list *lvs)
int activate_lvs(struct cmd_context *cmd, struct list *lvs, unsigned exclusive)
{
struct list *lvh;
struct lv_list *lvl;
list_iterate_items(lvl, lvs) {
if (!activate_lv_excl(cmd, lvl->lv)) {
if (!exclusive) {
if (!activate_lv(cmd, lvl->lv)) {
log_error("Failed to activate %s", lvl->lv->name);
return 0;
}
} else if (!activate_lv_excl(cmd, lvl->lv)) {
log_error("Failed to activate %s", lvl->lv->name);
list_uniterate(lvh, lvs, &lvl->list) {
lvl = list_item(lvh, struct lv_list);
activate_lv(cmd, lvl->lv);
}
return 0;
}
}

View File

@@ -99,7 +99,7 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
#define LCK_LV_DEACTIVATE (LCK_LV | LCK_NULL | LCK_NONBLOCK)
#define LCK_LV_CLUSTERED(lv) \
(((lv)->vg->status & CLUSTERED) ? LCK_CLUSTER_VG : 0)
(vg_is_clustered((lv)->vg) ? LCK_CLUSTER_VG : 0)
#define lock_lv_vol(cmd, lv, flags) \
lock_vol(cmd, (lv)->lvid.s, flags | LCK_LV_CLUSTERED(lv))
@@ -120,7 +120,7 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
/* Process list of LVs */
int suspend_lvs(struct cmd_context *cmd, struct list *lvs);
int resume_lvs(struct cmd_context *cmd, struct list *lvs);
int activate_lvs_excl(struct cmd_context *cmd, struct list *lvs);
int activate_lvs(struct cmd_context *cmd, struct list *lvs, unsigned exclusive);
/* Interrupt handling */
void sigint_clear(void);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -18,7 +18,6 @@
#include "locking_types.h"
#include "lvm-string.h"
#include "activate.h"
#include "lvmcache.h"
#include <signal.h>
@@ -41,15 +40,6 @@ static int _no_lock_resource(struct cmd_context *cmd, const char *resource,
{
switch (flags & LCK_SCOPE_MASK) {
case LCK_VG:
switch (flags & LCK_TYPE_MASK) {
case LCK_UNLOCK:
lvmcache_unlock_vgname(resource);
break;
default:
lvmcache_lock_vgname(resource,
(flags & LCK_TYPE_MASK) ==
LCK_READ);
}
break;
case LCK_LV:
switch (flags & LCK_TYPE_MASK) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -215,12 +215,18 @@ void init_cmd_name(int status)
void set_cmd_name(const char *cmd)
{
if (!_log_cmd_name)
return;
strncpy(_cmd_name, cmd, sizeof(_cmd_name));
_cmd_name[sizeof(_cmd_name) - 1] = '\0';
}
static const char *_command_name()
{
if (!_log_cmd_name)
return "";
return _cmd_name;
}
void init_msg_prefix(const char *prefix)
{
strncpy(_msg_prefix, prefix, sizeof(_msg_prefix));
@@ -352,7 +358,7 @@ void print_log(int level, const char *file, int line, const char *format, ...)
_verbose_level <= _LOG_DEBUG)
break;
if (_verbose_level >= _LOG_DEBUG) {
fprintf(stderr, "%s%s%s", locn, _cmd_name,
fprintf(stderr, "%s%s%s", locn, _command_name(),
_msg_prefix);
if (_indent)
fprintf(stderr, " ");
@@ -363,7 +369,7 @@ void print_log(int level, const char *file, int line, const char *format, ...)
case _LOG_INFO:
if (_verbose_level >= _LOG_INFO) {
fprintf(stderr, "%s%s%s", locn, _cmd_name,
fprintf(stderr, "%s%s%s", locn, _command_name(),
_msg_prefix);
if (_indent)
fprintf(stderr, " ");
@@ -373,7 +379,7 @@ void print_log(int level, const char *file, int line, const char *format, ...)
break;
case _LOG_NOTICE:
if (_verbose_level >= _LOG_NOTICE) {
fprintf(stderr, "%s%s%s", locn, _cmd_name,
fprintf(stderr, "%s%s%s", locn, _command_name(),
_msg_prefix);
if (_indent)
fprintf(stderr, " ");
@@ -383,14 +389,15 @@ void print_log(int level, const char *file, int line, const char *format, ...)
break;
case _LOG_WARN:
if (_verbose_level >= _LOG_WARN) {
fprintf(use_stderr ? stderr : stdout, "%s%s", _cmd_name, _msg_prefix);
fprintf(use_stderr ? stderr : stdout, "%s%s",
_command_name(), _msg_prefix);
vfprintf(use_stderr ? stderr : stdout, trformat, ap);
fputc('\n', use_stderr ? stderr : stdout);
}
break;
case _LOG_ERR:
if (_verbose_level >= _LOG_ERR) {
fprintf(stderr, "%s%s%s", locn, _cmd_name,
fprintf(stderr, "%s%s%s", locn, _command_name(),
_msg_prefix);
vfprintf(stderr, trformat, ap);
fputc('\n', stderr);
@@ -399,7 +406,7 @@ void print_log(int level, const char *file, int line, const char *format, ...)
case _LOG_FATAL:
default:
if (_verbose_level >= _LOG_FATAL) {
fprintf(stderr, "%s%s%s", locn, _cmd_name,
fprintf(stderr, "%s%s%s", locn, _command_name(),
_msg_prefix);
vfprintf(stderr, trformat, ap);
fputc('\n', stderr);
@@ -413,7 +420,7 @@ void print_log(int level, const char *file, int line, const char *format, ...)
return;
if (_log_to_file && (_log_while_suspended || !memlock())) {
fprintf(_log_file, "%s:%d %s%s", file, line, _cmd_name,
fprintf(_log_file, "%s:%d %s%s", file, line, _command_name(),
_msg_prefix);
va_start(ap, format);
@@ -436,7 +443,7 @@ void print_log(int level, const char *file, int line, const char *format, ...)
memset(&buf, ' ', sizeof(buf));
bufused = 0;
if ((n = dm_snprintf(buf, sizeof(buf) - bufused - 1,
"%s:%d %s%s", file, line, _cmd_name,
"%s:%d %s%s", file, line, _command_name(),
_msg_prefix)) == -1)
goto done;

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -24,7 +24,7 @@
/*
* Attempt to merge two adjacent segments.
* Currently only supports striped segments on AREA_PV.
* Returns success if successful, in which case 'first'
* Returns success if successful, in which case 'first'
* gets adjusted to contain both areas.
*/
static int _merge(struct lv_segment *first, struct lv_segment *second)
@@ -62,9 +62,10 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
{
struct lv_segment *seg, *seg2;
uint32_t le = 0;
unsigned seg_count = 0;
unsigned seg_count = 0, seg_found;
int r = 1;
uint32_t area_multiplier, s;
struct seg_list *sl;
list_iterate_items(seg, &lv->segments) {
seg_count++;
@@ -75,7 +76,7 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
r = 0;
}
area_multiplier = segtype_is_striped(seg->segtype) ?
area_multiplier = segtype_is_striped(seg->segtype) ?
seg->area_count : 1;
if (seg->area_len * area_multiplier != seg->len) {
@@ -101,7 +102,7 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
}
if (!(seg2 = first_seg(seg->log_lv)) ||
seg2->mirror_seg != seg) {
find_mirror_seg(seg2) != seg) {
log_error("LV %s: segment %u log LV does not "
"point back to mirror segment",
lv->name, seg_count);
@@ -110,8 +111,8 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
}
if (complete_vg && seg->status & MIRROR_IMAGE) {
if (!seg->mirror_seg ||
!seg_is_mirrored(seg->mirror_seg)) {
if (!find_mirror_seg(seg) ||
!seg_is_mirrored(find_mirror_seg(seg))) {
log_error("LV %s: segment %u mirror image "
"is not mirrored",
lv->name, seg_count);
@@ -157,7 +158,7 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
(seg_lv(seg, s)->status & MIRROR_IMAGE) &&
(!(seg2 = find_seg_by_le(seg_lv(seg, s),
seg_le(seg, s))) ||
seg2->mirror_seg != seg)) {
find_mirror_seg(seg2) != seg)) {
log_error("LV %s: segment %u mirror "
"image %u missing mirror ptr",
lv->name, seg_count, s);
@@ -173,12 +174,72 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
r = 0;
}
*/
seg_found = 0;
list_iterate_items(sl, &seg_lv(seg, s)->segs_using_this_lv)
if (sl->seg == seg)
seg_found++;
if (!seg_found) {
log_error("LV %s segment %d uses LV %s,"
" but missing ptr from %s to %s",
lv->name, seg_count,
seg_lv(seg, s)->name,
seg_lv(seg, s)->name, lv->name);
r = 0;
} else if (seg_found > 1) {
log_error("LV %s has duplicated links "
"to LV %s segment %d",
seg_lv(seg, s)->name,
lv->name, seg_count);
r = 0;
}
}
}
le += seg->len;
}
list_iterate_items(sl, &lv->segs_using_this_lv) {
seg = sl->seg;
seg_found = 0;
for (s = 0; s < seg->area_count; s++) {
if (seg_type(seg, s) != AREA_LV)
continue;
if (lv == seg_lv(seg, s))
seg_found++;
}
if (seg->log_lv == lv)
seg_found++;
if (!seg_found) {
log_error("LV %s is used by LV %s:%" PRIu32 "-%" PRIu32
", but missing ptr from %s to %s",
lv->name, seg->lv->name, seg->le,
seg->le + seg->len - 1,
seg->lv->name, lv->name);
r = 0;
} else if (seg_found != sl->count) {
log_error("Reference count mismatch: LV %s has %d "
"links to LV %s:%" PRIu32 "-%" PRIu32
", which has %d links",
lv->name, sl->count, seg->lv->name, seg->le,
seg->le + seg->len - 1, seg_found);
r = 0;
}
seg_found = 0;
list_iterate_items(seg2, &seg->lv->segments)
if (sl->seg == seg2) {
seg_found++;
break;
}
if (!seg_found) {
log_error("LV segment %s:%" PRIu32 "-%" PRIu32
"is incorrectly listed as being used by LV %s",
seg->lv->name, seg->le, seg->le + seg->len - 1,
lv->name);
r = 0;
}
}
if (le != lv->le_count) {
log_error("LV %s: inconsistent LE count %u != %u",
lv->name, le, lv->le_count);
@@ -243,9 +304,9 @@ static int _lv_split_segment(struct logical_volume *lv, struct lv_segment *seg,
/* Split area at the offset */
switch (seg_type(seg, s)) {
case AREA_LV:
seg_lv(split_seg, s) = seg_lv(seg, s);
seg_le(split_seg, s) =
seg_le(seg, s) + seg->area_len;
if (!set_lv_segment_area_lv(split_seg, s, seg_lv(seg, s),
seg_le(seg, s) + seg->area_len, 0))
return_0;
log_debug("Split %s:%u[%u] at %u: %s LE %u", lv->name,
seg->le, s, le, seg_lv(seg, s)->name,
seg_le(split_seg, s));
@@ -258,10 +319,8 @@ static int _lv_split_segment(struct logical_volume *lv, struct lv_segment *seg,
seg->area_len,
seg_pvseg(seg, s)->len -
seg->area_len,
split_seg, s))) {
stack;
return 0;
}
split_seg, s)))
return_0;
log_debug("Split %s:%u[%u] at %u: %s PE %u", lv->name,
seg->le, s, le,
dev_name(seg_dev(seg, s)),
@@ -297,15 +356,11 @@ int lv_split_segment(struct logical_volume *lv, uint32_t le)
if (le == seg->le)
return 1;
if (!_lv_split_segment(lv, seg, le)) {
stack;
return 0;
}
if (!_lv_split_segment(lv, seg, le))
return_0;
if (!vg_validate(lv->vg)) {
stack;
return 0;
}
if (!vg_validate(lv->vg))
return_0;
return 1;
}

View File

@@ -41,6 +41,9 @@ struct pv_segment;
#define PV_MIN_SIZE ( 512L * 1024L >> SECTOR_SHIFT) /* 512 KB in sectors */
#define MAX_RESTRICTED_LVS 255 /* Used by FMT_RESTRICTED_LVIDS */
/* Layer suffix */
#define MIRROR_SYNC_LAYER "_mimagetmp"
/* Various flags */
/* Note that the bits no longer necessarily correspond to LVM1 disk format */
@@ -66,6 +69,7 @@ struct pv_segment;
#define MIRROR_NOTSYNCED 0x00080000U /* LV */
//#define ACTIVATE_EXCL 0x00100000U /* LV - internal use only */
//#define PRECOMMITTED 0x00200000U /* VG - internal use only */
#define CONVERTING 0x00400000U /* LV */
#define LVM_READ 0x00000100U /* LV VG */
#define LVM_WRITE 0x00000200U /* LV VG */
@@ -88,6 +92,11 @@ struct pv_segment;
#define CORRECT_INCONSISTENT 0x00000001U /* Correct inconsistent metadata */
#define FAIL_INCONSISTENT 0x00000002U /* Fail if metadata inconsistent */
/* Mirror conversion type flags */
#define MIRROR_BY_SEG 0x00000001U /* segment-by-segment mirror */
#define MIRROR_BY_LV 0x00000002U /* mirror using whole mimage LVs */
#define MIRROR_SKIP_INIT_SYNC 0x00000010U /* skip initial sync */
/* Ordered list - see lv_manip.c */
typedef enum {
ALLOC_INVALID,
@@ -124,6 +133,7 @@ struct format_type {
struct labeller *labeller;
const char *name;
const char *alias;
const char *orphan_vg_name;
uint32_t features;
void *library;
void *private;
@@ -141,6 +151,8 @@ struct pv_segment {
uint32_t lv_area; /* Index to area in LV segment */
};
#define pvseg_is_allocated(pvseg) ((pvseg)->lvseg)
struct physical_volume {
struct id id;
struct device *dev;
@@ -234,7 +246,6 @@ struct lv_segment {
uint32_t region_size; /* For mirrors - in sectors */
uint32_t extents_copied;
struct logical_volume *log_lv;
struct lv_segment *mirror_seg;
struct list tags;
@@ -266,6 +277,7 @@ struct logical_volume {
struct list segments;
struct list tags;
struct list segs_using_this_lv;
};
struct pe_range {
@@ -302,11 +314,16 @@ struct list *get_pvs(struct cmd_context *cmd);
/* Set full_scan to 1 to re-read every (filtered) device label */
struct list *get_vgs(struct cmd_context *cmd, int full_scan);
struct list *get_vgids(struct cmd_context *cmd, int full_scan);
int scan_vgs_for_pvs(struct cmd_context *cmd);
int pv_write(struct cmd_context *cmd, struct physical_volume *pv,
struct list *mdas, int64_t label_sector);
int is_pv(pv_t *pv);
int is_orphan_vg(const char *vg_name);
int is_orphan(pv_t *pv);
int is_orphan(const pv_t *pv);
int vgs_are_compatible(struct cmd_context *cmd,
struct volume_group *vg_from,
struct volume_group *vg_to);
vg_t *vg_lock_and_read(struct cmd_context *cmd, const char *vg_name,
const char *vgid,
uint32_t lock_flags, uint32_t status_flags,
@@ -355,12 +372,19 @@ struct logical_volume *lv_create_empty(const char *name,
int import,
struct volume_group *vg);
/* Write out LV contents */
int set_lv(struct cmd_context *cmd, struct logical_volume *lv,
uint64_t sectors, int value);
/* Reduce the size of an LV by extents */
int lv_reduce(struct logical_volume *lv, uint32_t extents);
/* Empty an LV prior to deleting it */
int lv_empty(struct logical_volume *lv);
/* Empty an LV and add error segment */
int replace_lv_with_error_segment(struct logical_volume *lv);
/* Entry point for all LV extent allocations */
int lv_extend(struct logical_volume *lv,
const struct segment_type *segtype,
@@ -379,20 +403,50 @@ int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv,
int lv_rename(struct cmd_context *cmd, struct logical_volume *lv,
const char *new_name);
/*
* Functions for layer manipulation
*/
int insert_layer_for_segments_on_pv(struct cmd_context *cmd,
struct logical_volume *lv_where,
struct logical_volume *layer_lv,
uint32_t status,
struct pv_list *pv,
struct list *lvs_changed);
int remove_layers_for_segments(struct cmd_context *cmd,
struct logical_volume *lv,
struct logical_volume *layer_lv,
uint32_t status_mask, struct list *lvs_changed);
int remove_layers_for_segments_all(struct cmd_context *cmd,
struct logical_volume *layer_lv,
uint32_t status_mask,
struct list *lvs_changed);
int split_parent_segments_for_layer(struct cmd_context *cmd,
struct logical_volume *layer_lv);
int remove_layer_from_lv(struct logical_volume *lv,
struct logical_volume *layer_lv);
struct logical_volume *insert_layer_for_lv(struct cmd_context *cmd,
struct logical_volume *lv_where,
uint32_t status,
const char *layer_suffix);
/* Find a PV within a given VG */
struct pv_list *find_pv_in_vg(struct volume_group *vg, const char *pv_name);
pv_t *find_pv_in_vg_by_uuid(struct volume_group *vg, struct id *id);
struct pv_list *find_pv_in_vg(const struct volume_group *vg,
const char *pv_name);
pv_t *find_pv_in_vg_by_uuid(const struct volume_group *vg,
const struct id *id);
/* Find an LV within a given VG */
struct lv_list *find_lv_in_vg(struct volume_group *vg, const char *lv_name);
struct lv_list *find_lv_in_vg(const struct volume_group *vg,
const char *lv_name);
/* FIXME Merge these functions with ones above */
struct logical_volume *find_lv(struct volume_group *vg, const char *lv_name);
struct logical_volume *find_lv(const struct volume_group *vg,
const char *lv_name);
struct physical_volume *find_pv_by_name(struct cmd_context *cmd,
const char *pv_name);
/* Find LV segment containing given LE */
struct lv_segment *first_seg(struct logical_volume *lv);
struct lv_segment *first_seg(const struct logical_volume *lv);
/*
@@ -422,32 +476,44 @@ int vg_check_status(const struct volume_group *vg, uint32_t status);
/*
* Mirroring functions
*/
struct alloc_handle;
struct lv_segment *find_mirror_seg(struct lv_segment *seg);
int lv_add_mirrors(struct cmd_context *cmd, struct logical_volume *lv,
uint32_t mirrors, uint32_t stripes,
uint32_t region_size, uint32_t log_count,
struct list *pvs, alloc_policy_t alloc, uint32_t flags);
int lv_remove_mirrors(struct cmd_context *cmd, struct logical_volume *lv,
uint32_t mirrors, uint32_t log_count,
struct list *pvs, uint32_t status_mask);
int is_temporary_mirror_layer(const struct logical_volume *lv);
struct logical_volume * find_temporary_mirror(const struct logical_volume *lv);
uint32_t lv_mirror_count(const struct logical_volume *lv);
uint32_t adjusted_mirror_region_size(uint32_t extent_size, uint32_t extents,
uint32_t region_size);
int create_mirror_layers(struct alloc_handle *ah,
uint32_t first_area,
uint32_t num_mirrors,
struct logical_volume *lv,
const struct segment_type *segtype,
uint32_t status,
uint32_t region_size,
struct logical_volume *log_lv);
int remove_mirrors_from_segments(struct logical_volume *lv,
uint32_t new_mirrors, uint32_t status_mask);
int add_mirrors_to_segments(struct cmd_context *cmd, struct logical_volume *lv,
uint32_t mirrors, uint32_t region_size,
struct list *allocatable_pvs, alloc_policy_t alloc);
int remove_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors,
int remove_mirror_images(struct logical_volume *lv, uint32_t num_mirrors,
struct list *removable_pvs, unsigned remove_log);
int add_mirror_images(struct cmd_context *cmd, struct logical_volume *lv,
uint32_t mirrors, uint32_t stripes, uint32_t region_size,
struct list *allocatable_pvs, alloc_policy_t alloc,
uint32_t log_count);
struct logical_volume *detach_mirror_log(struct lv_segment *seg);
int attach_mirror_log(struct lv_segment *seg, struct logical_volume *lv);
int remove_mirror_log(struct cmd_context *cmd, struct logical_volume *lv,
struct list *removable_pvs);
int add_mirror_log(struct cmd_context *cmd, struct logical_volume *lv,
uint32_t log_count, uint32_t region_size,
struct list *allocatable_pvs, alloc_policy_t alloc);
int reconfigure_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors,
struct list *removable_pvs, unsigned remove_log);
int collapse_mirrored_lv(struct logical_volume *lv);
int insert_pvmove_mirrors(struct cmd_context *cmd,
struct logical_volume *lv_mirr,
struct list *source_pvl,
struct logical_volume *lv,
struct list *allocatable_pvs,
alloc_policy_t alloc,
struct list *lvs_changed);
int remove_pvmove_mirrors(struct volume_group *vg,
struct logical_volume *lv_mirr);
struct logical_volume *find_pvmove_lv(struct volume_group *vg,
struct device *dev, uint32_t lv_type);
struct logical_volume *find_pvmove_lv_from_pvname(struct cmd_context *cmd,
@@ -478,5 +544,21 @@ uint32_t pv_pe_count(const pv_t *pv);
uint32_t pv_pe_alloc_count(const pv_t *pv);
uint32_t vg_status(const vg_t *vg);
#define vg_is_clustered(vg) (vg_status((vg)) & CLUSTERED)
struct vgcreate_params {
char *vg_name;
uint32_t extent_size;
size_t max_pv;
size_t max_lv;
alloc_policy_t alloc;
int clustered; /* FIXME: put this into a 'status' variable instead? */
};
int validate_vg_create_params(struct cmd_context *cmd,
struct vgcreate_params *vp);
int validate_vg_rename_params(struct cmd_context *cmd,
const char *vg_name_old,
const char *vg_name_new);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -158,6 +158,12 @@ struct peg_list {
struct pv_segment *peg;
};
struct seg_list {
struct list list;
unsigned count;
struct lv_segment *seg;
};
/*
* Ownership of objects passes to caller.
*/
@@ -251,6 +257,9 @@ int get_pv_from_vg_by_id(const struct format_type *fmt, const char *vg_name,
struct lv_list *find_lv_in_vg_by_lvid(struct volume_group *vg,
const union lvid *lvid);
struct lv_list *find_lv_in_lv_list(const struct list *ll,
const struct logical_volume *lv);
/* Return the VG that contains a given LV (based on path given in lv_name) */
/* or environment var */
struct volume_group *find_vg_with_lv(const char *lv_name);
@@ -258,16 +267,19 @@ struct volume_group *find_vg_with_lv(const char *lv_name);
/* Find LV with given lvid (used during activation) */
struct logical_volume *lv_from_lvid(struct cmd_context *cmd,
const char *lvid_s,
int precommitted);
unsigned precommitted);
/* FIXME Merge these functions with ones above */
struct physical_volume *find_pv(struct volume_group *vg, struct device *dev);
struct pv_list *find_pv_in_pv_list(const struct list *pl,
const struct physical_volume *pv);
/* Find LV segment containing given LE */
struct lv_segment *find_seg_by_le(struct logical_volume *lv, uint32_t le);
struct lv_segment *find_seg_by_le(const struct logical_volume *lv, uint32_t le);
/* Find PV segment containing given LE */
struct pv_segment *find_peg_by_pe(struct physical_volume *pv, uint32_t pe);
struct pv_segment *find_peg_by_pe(const struct physical_volume *pv, uint32_t pe);
/*
* Remove a dev_dir if present.
@@ -292,19 +304,28 @@ int lv_merge_segments(struct logical_volume *lv);
*/
int lv_split_segment(struct logical_volume *lv, uint32_t le);
/*
* Add/remove upward link from underlying LV to the segment using it
* FIXME: ridiculously long name
*/
int add_seg_to_segs_using_this_lv(struct logical_volume *lv, struct lv_segment *seg);
int remove_seg_from_segs_using_this_lv(struct logical_volume *lv, struct lv_segment *seg);
struct lv_segment *get_only_segment_using_this_lv(struct logical_volume *lv);
/*
* For internal metadata caching.
*/
int export_vg_to_buffer(struct volume_group *vg, char **buf);
struct volume_group *import_vg_from_buffer(char *buf,
struct format_instance *fid);
/*
* Mirroring functions
*/
int add_mirror_layers(struct alloc_handle *ah,
uint32_t num_mirrors,
uint32_t existing_mirrors,
struct logical_volume *lv,
const struct segment_type *segtype);
/*
* Given mirror image or mirror log segment, find corresponding mirror segment
*/
struct lv_segment *find_mirror_seg(struct lv_segment *seg);
int fixup_imported_mirrors(struct volume_group *vg);
/*

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.

View File

@@ -78,7 +78,8 @@ struct segtype_handler {
struct lv_segment *seg, char *params,
uint64_t *total_numerator,
uint64_t *total_denominator, float *percent);
int (*target_present) (const struct lv_segment *seg);
int (*target_present) (const struct lv_segment *seg,
unsigned *attributes);
int (*modules_needed) (struct dm_pool *mem,
const struct lv_segment *seg,
struct list *modules);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -70,17 +70,13 @@ int vg_add_snapshot(const char *name, struct logical_volume *origin,
if (!(snap = lv_create_empty(name ? name : "snapshot%d",
lvid, LVM_READ | LVM_WRITE | VISIBLE_LV,
ALLOC_INHERIT, 1, origin->vg))) {
stack;
return 0;
}
ALLOC_INHERIT, 1, origin->vg)))
return_0;
snap->le_count = extent_count;
if (!(seg = alloc_snapshot_seg(snap, 0, 0))) {
stack;
return 0;
}
if (!(seg = alloc_snapshot_seg(snap, 0, 0)))
return_0;
seg->chunk_size = chunk_size;
seg->origin = origin;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -33,6 +33,7 @@
#endif
static int _block_on_error_available = 0;
static unsigned _mirror_attributes = 0;
enum {
MIRR_DISABLED,
@@ -110,19 +111,19 @@ static int _mirrored_text_import(struct lv_segment *seg, const struct config_nod
}
}
if ((cn = find_config_node(sn, "mirror_log"))) {
if (!cn->v || !cn->v->v.str) {
log_error("Mirror log type must be a string.");
return 0;
}
logname = cn->v->v.str;
if ((cn = find_config_node(sn, "mirror_log"))) {
if (!cn->v || !cn->v->v.str) {
log_error("Mirror log type must be a string.");
return 0;
}
logname = cn->v->v.str;
if (!(seg->log_lv = find_lv(seg->lv->vg, logname))) {
log_error("Unrecognised mirror log in segment %s.",
sn->key);
return 0;
}
seg->log_lv->status |= MIRROR_LOG;
}
}
if (logname && !seg->region_size) {
log_error("Missing region size for mirror log for segment "
@@ -232,11 +233,11 @@ static int _add_log(struct dev_manager *dm, struct lv_segment *seg,
uint32_t log_flags = 0;
/*
* Use clustered mirror log for non-exclusive activation
* Use clustered mirror log for non-exclusive activation
* in clustered VG.
*/
if ((!(seg->lv->status & ACTIVATE_EXCL) &&
(seg->lv->vg->status & CLUSTERED)))
(vg_is_clustered(seg->lv->vg))))
clustered = 1;
if (seg->log_lv) {
@@ -266,10 +267,10 @@ static int _add_log(struct dev_manager *dm, struct lv_segment *seg,
}
static int _mirrored_add_target_line(struct dev_manager *dm, struct dm_pool *mem,
struct cmd_context *cmd, void **target_state,
struct lv_segment *seg,
struct dm_tree_node *node, uint64_t len,
uint32_t *pvmove_mirror_count)
struct cmd_context *cmd, void **target_state,
struct lv_segment *seg,
struct dm_tree_node *node, uint64_t len,
uint32_t *pvmove_mirror_count)
{
struct mirror_state *mirr_state;
uint32_t area_count = seg->area_count;
@@ -283,6 +284,13 @@ static int _mirrored_add_target_line(struct dev_manager *dm, struct dm_pool *mem
mirr_state = *target_state;
/*
* Mirror segment could have only 1 area temporarily
* if the segment is under conversion.
*/
if (seg->area_count == 1)
mirror_status = MIRR_DISABLED;
/*
* For pvmove, only have one mirror segment RUNNING at once.
* Segments before this are COMPLETED and use 2nd area.
@@ -336,32 +344,42 @@ static int _mirrored_add_target_line(struct dev_manager *dm, struct dm_pool *mem
return add_areas_line(dm, seg, node, start_area, area_count);
}
static int _mirrored_target_present(const struct lv_segment *seg __attribute((unused)))
static int _mirrored_target_present(const struct lv_segment *seg __attribute((unused)),
unsigned *attributes)
{
static int _mirrored_checked = 0;
static int _mirrored_present = 0;
uint32_t maj, min, patchlevel;
unsigned maj2, min2, patchlevel2;
char vsn[80];
char vsn[80];
if (!_mirrored_checked) {
_mirrored_present = target_present("mirror", 1);
/*
* block_on_error available with mirror target >= 1.1
* block_on_error available with mirror target >= 1.1 and <= 1.11
* or with 1.0 in RHEL4U3 driver >= 4.5
*/
/* FIXME Move this into libdevmapper */
if (target_version("mirror", &maj, &min, &patchlevel) &&
maj == 1 &&
(min >= 1 ||
maj == 1 &&
((min >= 1 && min <= 11) ||
(min == 0 && driver_version(vsn, sizeof(vsn)) &&
sscanf(vsn, "%u.%u.%u", &maj2, &min2, &patchlevel2) == 3 &&
maj2 == 4 && min2 == 5 && patchlevel2 == 0))) /* RHEL4U3 */
_block_on_error_available = 1;
}
/*
* Check only for modules if atttributes requested and no previous check.
* FIXME: need better check
*/
if (attributes) {
if (!_mirror_attributes && module_present("cmirror"))
_mirror_attributes |= MIRROR_LOG_CLUSTERED;
*attributes = _mirror_attributes;
}
_mirrored_checked = 1;
return _mirrored_present;
@@ -449,7 +467,8 @@ static int _target_monitored(struct lv_segment *seg, int *pending)
}
/* FIXME This gets run while suspended and performs banned operations. */
static int _target_set_events(struct lv_segment *seg, int evmask, int set)
static int _target_set_events(struct lv_segment *seg,
int evmask __attribute((unused)), int set)
{
char *dso, *name;
struct logical_volume *lv;
@@ -500,7 +519,7 @@ static int _mirrored_modules_needed(struct dm_pool *mem,
!list_segment_modules(mem, first_seg(seg->log_lv), modules))
return_0;
if ((seg->lv->vg->status & CLUSTERED) &&
if (vg_is_clustered(seg->lv->vg) &&
!str_list_add(mem, modules, "clog")) {
log_error("cluster log string list allocation failed");
return 0;
@@ -548,10 +567,8 @@ struct segment_type *init_segtype(struct cmd_context *cmd)
{
struct segment_type *segtype = dm_malloc(sizeof(*segtype));
if (!segtype) {
stack;
return NULL;
}
if (!segtype)
return_NULL;
segtype->cmd = cmd;
segtype->ops = &_mirrored_ops;

View File

@@ -55,9 +55,6 @@
/* Define to 1 if you have the `fork' function. */
#undef HAVE_FORK
/* Define to 1 if you have the <fstab.h> header file. */
#undef HAVE_FSTAB_H
/* Define to 1 if you have the `gethostname' function. */
#undef HAVE_GETHOSTNAME
@@ -291,9 +288,6 @@
/* Define to 1 if you have the <sys/utsname.h> header file. */
#undef HAVE_SYS_UTSNAME_H
/* Define to 1 if you have the <sys/vfs.h> header file. */
#undef HAVE_SYS_VFS_H
/* Define to 1 if you have the <sys/wait.h> header file. */
#undef HAVE_SYS_WAIT_H

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -39,16 +39,16 @@ int emit_to_buffer(char **buffer, size_t *size, const char *fmt, ...)
* Count occurences of 'c' in 'str' until we reach a null char.
*
* Returns:
* len - incremented for each char we encounter, whether 'c' or not.
* count - number of occurrences of 'c'
* len - incremented for each char we encounter.
* count - number of occurrences of 'c' and 'c2'.
*/
void count_chars(const char *str, size_t *len, int *count,
const int c)
static void _count_chars(const char *str, size_t *len, int *count,
const int c1, const int c2)
{
const char *ptr;
for (ptr = str; *ptr; ptr++, (*len)++)
if (*ptr == c)
if (*ptr == c1 || *ptr == c2)
(*count)++;
}
@@ -58,7 +58,7 @@ void count_chars(const char *str, size_t *len, int *count,
* Returns:
* Number of occurrences of 'c'
*/
unsigned count_chars_len(const char *str, size_t len, const int c)
unsigned count_chars(const char *str, size_t len, const int c)
{
size_t i;
unsigned count = 0;
@@ -70,17 +70,62 @@ unsigned count_chars_len(const char *str, size_t len, const int c)
return count;
}
/*
* Length of string after escaping double quotes and backslashes.
*/
size_t escaped_len(const char *str)
{
size_t len = 1;
int count = 0;
_count_chars(str, &len, &count, '\"', '\\');
return count + len;
}
/*
* Copies a string, quoting orig_char with quote_char.
* Optionally also quote quote_char.
*/
static void _quote_characters(char **out, const char *src,
const int orig_char, const int quote_char,
int quote_quote_char)
{
while (*src) {
if (*src == orig_char ||
(*src == quote_char && quote_quote_char))
*(*out)++ = quote_char;
*(*out)++ = *src++;
}
}
/*
* Unquote orig_char in string.
* Also unquote quote_char.
*/
static void _unquote_characters(char *src, const int orig_char,
const int quote_char)
{
char *out = src;
while (*src) {
if (*src == quote_char &&
(*(src + 1) == orig_char || *(src + 1) == quote_char))
src++;
*out++ = *src++;
}
*out = '\0';
}
/*
* Copies a string, quoting hyphens with hyphens.
*/
static void _quote_hyphens(char **out, const char *src)
{
while (*src) {
if (*src == '-')
*(*out)++ = '-';
*(*out)++ = *src++;
}
return _quote_characters(out, src, '-', '-', 0);
}
/*
@@ -93,11 +138,11 @@ char *build_dm_name(struct dm_pool *mem, const char *vgname,
int hyphens = 1;
char *r, *out;
count_chars(vgname, &len, &hyphens, '-');
count_chars(lvname, &len, &hyphens, '-');
_count_chars(vgname, &len, &hyphens, '-', 0);
_count_chars(lvname, &len, &hyphens, '-', 0);
if (layer && *layer) {
count_chars(layer, &len, &hyphens, '-');
_count_chars(layer, &len, &hyphens, '-', 0);
hyphens++;
}
@@ -125,6 +170,27 @@ char *build_dm_name(struct dm_pool *mem, const char *vgname,
return r;
}
/*
* Copies a string, quoting double quotes with backslashes.
*/
char *escape_double_quotes(char *out, const char *src)
{
char *buf = out;
_quote_characters(&buf, src, '\"', '\\', 1);
*buf = '\0';
return out;
}
/*
* Undo quoting in situ.
*/
void unescape_double_quotes(char *src)
{
_unquote_characters(src, '\"', '\\');
}
/*
* Device layer names are all of the form <vg>-<lv>-<layer>, any
* other hyphens that appear in these names are quoted with yet

View File

@@ -31,8 +31,27 @@ char *build_dm_name(struct dm_pool *mem, const char *vg,
int validate_name(const char *n);
void count_chars(const char *str, size_t *len, int *count,
const int c);
unsigned count_chars_len(const char *str, size_t len, const int c);
/*
* Returns number of occurrences of c in first len characters of str.
*/
unsigned count_chars(const char *str, size_t len, const int c);
/*
* Returns what length of escaped string would be including terminating NUL.
*/
size_t escaped_len(const char *str);
/*
* Copies a string from src to out.
* Double quotation marks and backslashes are quoted with a backslash.
* Caller must ensure *out has enough space - see escaped_len().
* Returns *out.
*/
char *escape_double_quotes(char *out, const char *src);
/*
* Removes quoting of double quotation marks and backslashes in situ.
*/
void unescape_double_quotes(char *src);
#endif

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -151,8 +151,8 @@ void memlock_init(struct cmd_context *cmd)
"activation/reserved_memory",
DEFAULT_RESERVED_MEMORY) * 1024;
_default_priority = find_config_tree_int(cmd,
"activation/process_priority",
DEFAULT_PROCESS_PRIORITY);
"activation/process_priority",
DEFAULT_PROCESS_PRIORITY);
}
#endif

View File

@@ -33,6 +33,7 @@ FIELD(LVS, lv, STR, "Origin", lvid, 6, origin, "origin", "For snapshots, the ori
FIELD(LVS, lv, NUM, "Snap%", lvid, 6, snpercent, "snap_percent", "For snapshots, the percentage full if LV is active.")
FIELD(LVS, lv, NUM, "Copy%", lvid, 6, copypercent, "copy_percent", "For mirrors and pvmove, current percentage in-sync.")
FIELD(LVS, lv, STR, "Move", lvid, 4, movepv, "move_pv", "For pvmove, Source PV of temporary LV created by pvmove")
FIELD(LVS, lv, STR, "Convert", lvid, 7, convertlv, "convert_lv", "For lvconvert, Name of temporary LV created by lvconvert")
FIELD(LVS, lv, STR, "LV Tags", tags, 7, tags, "lv_tags", "Tags, if any.")
FIELD(LVS, lv, STR, "Log", lvid, 3, loglv, "mirror_log", "For mirrors, the LV holding the synchronisation log.")
FIELD(LVS, lv, STR, "Modules", lvid, 7, modules, "modules", "Kernel device-mapper modules required for this LV.")
@@ -65,7 +66,7 @@ FIELD(VGS, vg, NUM, "Free", free_count, 4, uint32, "vg_free_count", "Total numbe
FIELD(VGS, vg, NUM, "MaxLV", max_lv, 5, uint32, "max_lv", "Maximum number of LVs allowed in VG or 0 if unlimited.")
FIELD(VGS, vg, NUM, "MaxPV", max_pv, 5, uint32, "max_pv", "Maximum number of PVs allowed in VG or 0 if unlimited.")
FIELD(VGS, vg, NUM, "#PV", pv_count, 3, uint32, "pv_count", "Number of PVs.")
FIELD(VGS, vg, NUM, "#LV", lv_count, 3, uint32, "lv_count", "Number of LVs.")
FIELD(VGS, vg, NUM, "#LV", cmd, 3, lvcount, "lv_count", "Number of LVs.")
FIELD(VGS, vg, NUM, "#SN", snapshot_count, 3, uint32, "snap_count", "Number of snapshots.")
FIELD(VGS, vg, NUM, "Seq", seqno, 3, uint32, "vg_seqno", "Revision number of internal metadata. Incremented whenever it changes.")
FIELD(VGS, vg, STR, "VG Tags", tags, 7, tags, "vg_tags", "Tags, if any.")
@@ -81,8 +82,10 @@ FIELD(SEGS, seg, NUM, "Region", region_size, 6, size32, "region_size", "For mirr
FIELD(SEGS, seg, NUM, "Chunk", list, 5, chunksize, "chunksize", "For snapshots, the unit of data used when tracking changes.")
FIELD(SEGS, seg, NUM, "Chunk", list, 5, chunksize, "chunk_size", "For snapshots, the unit of data used when tracking changes.")
FIELD(SEGS, seg, NUM, "Start", list, 5, segstart, "seg_start", "Offset within the LV to the start of the segment in current units.")
FIELD(SEGS, seg, NUM, "Start", list, 5, segstartpe, "seg_start_pe", "Offset within the LV to the start of the segment in physical extents.")
FIELD(SEGS, seg, NUM, "SSize", list, 5, segsize, "seg_size", "Size of segment in current units.")
FIELD(SEGS, seg, STR, "Seg Tags", tags, 8, tags, "seg_tags", "Tags, if any.")
FIELD(SEGS, seg, STR, "PE Ranges", list, 9, peranges, "seg_pe_ranges", "Ranges of Physical Extents of underlying devices in command line format.")
FIELD(SEGS, seg, STR, "Devices", list, 5, devices, "devices", "Underlying devices used with starting extent numbers.")
FIELD(PVSEGS, pvseg, NUM, "Start", pe, 5, uint32, "pvseg_start", "Physical Extent number of start of segment.")

View File

@@ -80,9 +80,8 @@ static int _dev_name_disp(struct dm_report *rh, struct dm_pool *mem __attribute(
return dm_report_field_string(rh, field, &name);
}
static int _devices_disp(struct dm_report *rh __attribute((unused)), struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private __attribute((unused)))
static int _format_pvsegs(struct dm_pool *mem, struct dm_report_field *field,
const void *data, int range_format)
{
const struct lv_segment *seg = (const struct lv_segment *) data;
unsigned int s;
@@ -115,19 +114,32 @@ static int _devices_disp(struct dm_report *rh __attribute((unused)), struct dm_p
return 0;
}
if (dm_snprintf(extent_str, sizeof(extent_str), "(%" PRIu32
")", extent) < 0) {
if (dm_snprintf(extent_str, sizeof(extent_str),
"%s%" PRIu32 "%s",
range_format ? ":" : "(", extent,
range_format ? "-" : ")") < 0) {
log_error("Extent number dm_snprintf failed");
return 0;
}
if (!dm_pool_grow_object(mem, extent_str, strlen(extent_str))) {
log_error("dm_pool_grow_object failed");
return 0;
}
if (range_format) {
if (dm_snprintf(extent_str, sizeof(extent_str),
"%" PRIu32, extent + seg->area_len - 1) < 0) {
log_error("Extent number dm_snprintf failed");
return 0;
}
if (!dm_pool_grow_object(mem, extent_str, strlen(extent_str))) {
log_error("dm_pool_grow_object failed");
return 0;
}
}
if ((s != seg->area_count - 1) &&
!dm_pool_grow_object(mem, ",", 1)) {
!dm_pool_grow_object(mem, range_format ? " " : ",", 1)) {
log_error("dm_pool_grow_object failed");
return 0;
}
@@ -143,6 +155,20 @@ static int _devices_disp(struct dm_report *rh __attribute((unused)), struct dm_p
return 1;
}
static int _devices_disp(struct dm_report *rh __attribute((unused)), struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private __attribute((unused)))
{
return _format_pvsegs(mem, field, data, 0);
}
static int _peranges_disp(struct dm_report *rh __attribute((unused)), struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private __attribute((unused)))
{
return _format_pvsegs(mem, field, data, 1);
}
static int _tags_disp(struct dm_report *rh __attribute((unused)), struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private __attribute((unused)))
@@ -246,6 +272,23 @@ static int _lvkmin_disp(struct dm_report *rh, struct dm_pool *mem __attribute((u
return dm_report_field_uint64(rh, field, &_minusone);
}
static int _lv_mimage_in_sync(const struct logical_volume *lv)
{
float percent;
struct lv_segment *mirror_seg = find_mirror_seg(first_seg(lv));
if (!(lv->status & MIRROR_IMAGE) || !mirror_seg)
return_0;
if (!lv_mirror_percent(lv->vg->cmd, mirror_seg->lv, 0, &percent, NULL))
return_0;
if (percent >= 100.0)
return 1;
return 0;
}
static int _lvstatus_disp(struct dm_report *rh __attribute((unused)), struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private __attribute((unused)))
@@ -262,13 +305,18 @@ static int _lvstatus_disp(struct dm_report *rh __attribute((unused)), struct dm_
if (lv->status & PVMOVE)
repstr[0] = 'p';
else if (lv->status & CONVERTING)
repstr[0] = 'c';
else if (lv->status & MIRRORED) {
if (lv->status & MIRROR_NOTSYNCED)
repstr[0] = 'M';
else
repstr[0] = 'm';
}else if (lv->status & MIRROR_IMAGE)
repstr[0] = 'i';
if (_lv_mimage_in_sync(lv))
repstr[0] = 'i';
else
repstr[0] = 'I';
else if (lv->status & MIRROR_LOG)
repstr[0] = 'l';
else if (lv->status & VIRTUAL)
@@ -391,7 +439,7 @@ static int _vgstatus_disp(struct dm_report *rh __attribute((unused)), struct dm_
repstr[4] = _alloc_policy_char(vg->alloc);
if (vg->status & CLUSTERED)
if (vg_is_clustered(vg))
repstr[5] = 'c';
else
repstr[5] = '-';
@@ -501,6 +549,32 @@ static int _movepv_disp(struct dm_report *rh, struct dm_pool *mem __attribute((u
return 1;
}
static int _convertlv_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 logical_volume *lv = (const struct logical_volume *) data;
const char *name = NULL;
struct lv_segment *seg;
if (lv->status & CONVERTING) {
if (lv->status & MIRRORED) {
seg = first_seg(lv);
/* Temporary mirror is always area_num == 0 */
if (seg_type(seg, 0) == AREA_LV &&
is_temporary_mirror_layer(seg_lv(seg, 0)))
name = seg_lv(seg, 0)->name;
}
}
if (name)
return dm_report_field_string(rh, field, &name);
dm_report_field_set_value(field, "", NULL);
return 1;
}
static int _size32_disp(struct dm_report *rh __attribute((unused)), struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
@@ -509,10 +583,8 @@ static int _size32_disp(struct dm_report *rh __attribute((unused)), struct dm_po
const char *disp, *repstr;
uint64_t *sortval;
if (!*(disp = display_size_units(private, (uint64_t) size))) {
stack;
return 0;
}
if (!*(disp = display_size_units(private, (uint64_t) size)))
return_0;
if (!(repstr = dm_pool_strdup(mem, disp))) {
log_error("dm_pool_strdup failed");
@@ -540,10 +612,8 @@ static int _size64_disp(struct dm_report *rh __attribute((unused)),
const char *disp, *repstr;
uint64_t *sortval;
if (!*(disp = display_size_units(private, size))) {
stack;
return 0;
}
if (!*(disp = display_size_units(private, size)))
return_0;
if (!(repstr = dm_pool_strdup(mem, disp))) {
log_error("dm_pool_strdup failed");
@@ -613,6 +683,17 @@ static int _segstart_disp(struct dm_report *rh, struct dm_pool *mem,
return _size64_disp(rh, mem, field, &start, private);
}
static int _segstartpe_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 lv_segment *seg = (const struct lv_segment *) data;
return dm_report_field_uint32(rh, field, &seg->le);
}
static int _segsize_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
@@ -724,10 +805,8 @@ static int _uuid_disp(struct dm_report *rh __attribute((unused)), struct dm_pool
return 0;
}
if (!id_write_format((const struct id *) data, repstr, 40)) {
stack;
return 0;
}
if (!id_write_format((const struct id *) data, repstr, 40))
return_0;
dm_report_field_set_value(field, repstr, NULL);
return 1;
@@ -751,11 +830,11 @@ static int _pvmdas_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
{
struct lvmcache_info *info;
struct lvmcache_info *info;
uint32_t count;
const char *pvid = (const char *)(&((struct id *) data)->uuid);
info = info_from_pvid(pvid);
info = info_from_pvid(pvid, 0);
count = info ? list_size(&info->mdas) : 0;
return _uint32_disp(rh, mem, field, &count, private);
@@ -777,12 +856,12 @@ static int _pvmdafree_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
{
struct lvmcache_info *info;
struct lvmcache_info *info;
uint64_t freespace = UINT64_MAX, mda_free;
const char *pvid = (const char *)(&((struct id *) data)->uuid);
struct metadata_area *mda;
info = info_from_pvid(pvid);
info = info_from_pvid(pvid, 0);
list_iterate_items(mda, &info->mdas) {
if (!mda->ops->mda_free_sectors)
@@ -820,6 +899,21 @@ static int _vgmdafree_disp(struct dm_report *rh, struct dm_pool *mem,
return _size64_disp(rh, mem, field, &freespace, private);
}
static int _lvcount_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
{
const struct volume_group *vg = (const struct volume_group *) data;
struct lv_list *lvl;
uint32_t count = 0;
list_iterate_items(lvl, &vg->lvs)
if (lv_is_visible(lvl->lv) && !(lvl->lv->status & SNAPSHOT))
count++;
return _uint32_disp(rh, mem, field, &count, private);
}
static int _lvsegcount_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
@@ -925,7 +1019,7 @@ static int _copypercent_disp(struct dm_report *rh __attribute((unused)), struct
/* necessary for displaying something for PVs not belonging to VG */
static struct volume_group _dummy_vg = {
.name = (char *) ORPHAN,
.name = (char *) "",
};
static void *_obj_get_vg(void *obj)
@@ -970,7 +1064,7 @@ static const struct dm_report_object_type _report_types[] = {
#define STR DM_REPORT_FIELD_TYPE_STRING
#define NUM DM_REPORT_FIELD_TYPE_NUMBER
#define FIELD(type, strct, sorttype, head, field, width, func, id, desc) {type, sorttype, (off_t)((void *)&_dummy._ ## strct.field - (void *)&_dummy._ ## strct), width, id, head, &_ ## func ## _disp, desc},
#define FIELD(type, strct, sorttype, head, field, width, func, id, desc) {type, sorttype, (off_t)((uintptr_t)&_dummy._ ## strct.field - (uintptr_t)&_dummy._ ## strct), width, id, head, &_ ## func ## _disp, desc},
static struct dm_report_field_type _fields[] = {
#include "columns.h"

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