mirror of
git://sourceware.org/git/lvm2.git
synced 2025-12-24 16:23:50 +03:00
Compare commits
328 Commits
old-dm_v1_
...
old-dm_v1_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
075b4bef3f | ||
|
|
b59fce4393 | ||
|
|
8674a25eb8 | ||
|
|
10bf8fd2cd | ||
|
|
57cb22ff3c | ||
|
|
0162abdcae | ||
|
|
5801171518 | ||
|
|
bf1edbd1e2 | ||
|
|
a8484d987d | ||
|
|
9b2147f608 | ||
|
|
32530b378e | ||
|
|
a42905efa6 | ||
|
|
c59745f9dd | ||
|
|
b4ad9a5d08 | ||
|
|
3ead7a38b1 | ||
|
|
bf90435200 | ||
|
|
9c181fa3d3 | ||
|
|
3af0b1eb90 | ||
|
|
7110c318ee | ||
|
|
49a552ccdc | ||
|
|
57685f17a9 | ||
|
|
a1c09a463f | ||
|
|
194121760a | ||
|
|
6a987d46bf | ||
|
|
e3db0b39b9 | ||
|
|
4d4f0ee188 | ||
|
|
ac7334c167 | ||
|
|
e7bdd69af0 | ||
|
|
fefc655969 | ||
|
|
4dceaef60e | ||
|
|
6fc10dd3ae | ||
|
|
1ecd05a584 | ||
|
|
976acaca31 | ||
|
|
b4e5131d59 | ||
|
|
49f7cfefd7 | ||
|
|
fc365092f6 | ||
|
|
7f26240442 | ||
|
|
db559bb20a | ||
|
|
52850faa15 | ||
|
|
57d9a6c836 | ||
|
|
752c880bfc | ||
|
|
d83a354781 | ||
|
|
17dd81336d | ||
|
|
eaa46a2575 | ||
|
|
fc0ec1e71e | ||
|
|
fb2f92df1d | ||
|
|
74adbb77b7 | ||
|
|
788e544e1d | ||
|
|
368a0d4d2d | ||
|
|
962b7222d0 | ||
|
|
17c1f54369 | ||
|
|
33ae38e71b | ||
|
|
ef58af4bf1 | ||
|
|
3fad2db2f8 | ||
|
|
9feaeb28ca | ||
|
|
0075364715 | ||
|
|
99c5da5da5 | ||
|
|
22c957bc20 | ||
|
|
3316d59910 | ||
|
|
a109ce1eca | ||
|
|
e581a78d65 | ||
|
|
3c78f9900c | ||
|
|
bd606943e6 | ||
|
|
6381666df4 | ||
|
|
736f1aa301 | ||
|
|
b1a4eac7a8 | ||
|
|
8226a5276b | ||
|
|
77ad0bb12e | ||
|
|
9412b42206 | ||
|
|
2a91d87074 | ||
|
|
4a23617d79 | ||
|
|
0e2ceed74d | ||
|
|
ed56aed8eb | ||
|
|
8d909cbdc0 | ||
|
|
bf98943cbb | ||
|
|
6ff4552be2 | ||
|
|
1c7eb79370 | ||
|
|
f095a75f1e | ||
|
|
f70af6018c | ||
|
|
71b3b1ff4c | ||
|
|
d9fefa0c6c | ||
|
|
3bfe922381 | ||
|
|
a85cf17bf1 | ||
|
|
dbb5a09918 | ||
|
|
93e5097f20 | ||
|
|
dd53f2dc83 | ||
|
|
2b83c80593 | ||
|
|
6930f60c06 | ||
|
|
376b76e75c | ||
|
|
1ddd4509dc | ||
|
|
6af3f4f4cf | ||
|
|
6726c5f958 | ||
|
|
d5a9c43cb2 | ||
|
|
19a5a6a4eb | ||
|
|
617a599ee9 | ||
|
|
25e2d4da44 | ||
|
|
ad2e7218cb | ||
|
|
917637fa9b | ||
|
|
b595ee1c0b | ||
|
|
c8260a4a56 | ||
|
|
d2eaff3204 | ||
|
|
b65f5a844f | ||
|
|
95a69f99ba | ||
|
|
71d609895a | ||
|
|
9229630447 | ||
|
|
eb18a0b7dc | ||
|
|
05ed5c0d74 | ||
|
|
41330ecc5e | ||
|
|
16fbcc6e36 | ||
|
|
d87da9c7de | ||
|
|
94563b6017 | ||
|
|
34d22f7047 | ||
|
|
e24d996fbe | ||
|
|
9b52617919 | ||
|
|
efc1d46c89 | ||
|
|
9397833ceb | ||
|
|
e9433e83cd | ||
|
|
f3c58100a0 | ||
|
|
8900231d99 | ||
|
|
c7a63b8a2b | ||
|
|
90e90672a4 | ||
|
|
fa51e5c762 | ||
|
|
911f55d005 | ||
|
|
d30eb4e570 | ||
|
|
67bcfb6947 | ||
|
|
3915a61b1e | ||
|
|
c170d321e8 | ||
|
|
2802c476ee | ||
|
|
1050cebf7f | ||
|
|
dad73465fc | ||
|
|
8e2ac98fe2 | ||
|
|
9aaf0c36d5 | ||
|
|
1cb07e9cfd | ||
|
|
f1ccdf25b1 | ||
|
|
6dca497b27 | ||
|
|
42a83262a1 | ||
|
|
63ee9cbee6 | ||
|
|
3862f8ca7c | ||
|
|
4ada7cffd0 | ||
|
|
a664ce4298 | ||
|
|
8d7b6c6905 | ||
|
|
16d22d404a | ||
|
|
ccb24d5779 | ||
|
|
8795b45cb4 | ||
|
|
628d3bff45 | ||
|
|
0336bc9de9 | ||
|
|
033cb21797 | ||
|
|
09b98a45df | ||
|
|
38857ba29e | ||
|
|
1c7520ec8f | ||
|
|
362b9769b2 | ||
|
|
b2d68bd3d2 | ||
|
|
0dc7e635d4 | ||
|
|
80e070a857 | ||
|
|
cc203245e4 | ||
|
|
2f9a65fc93 | ||
|
|
62738e8001 | ||
|
|
5ecacf0c7f | ||
|
|
06b103c8d4 | ||
|
|
d473b7bca8 | ||
|
|
50a1e81ba7 | ||
|
|
d9885b1b64 | ||
|
|
0a9c8cada2 | ||
|
|
60f55f8461 | ||
|
|
7bedaea38f | ||
|
|
9e4b87e798 | ||
|
|
95bf59095c | ||
|
|
e0f34a9720 | ||
|
|
f3797c2a8e | ||
|
|
30cbcccc80 | ||
|
|
f49c0d696f | ||
|
|
71f564ee5b | ||
|
|
4b0950aba5 | ||
|
|
8c3af822ec | ||
|
|
878a207d19 | ||
|
|
0537ad860a | ||
|
|
2cdbbb1aea | ||
|
|
7af977d36b | ||
|
|
9afff4cf30 | ||
|
|
48ba9734aa | ||
|
|
897fc59f72 | ||
|
|
947e44ae67 | ||
|
|
e44843beba | ||
|
|
147482ea69 | ||
|
|
09091c5cf8 | ||
|
|
50827a5f69 | ||
|
|
2d6444c924 | ||
|
|
1d2675d9aa | ||
|
|
ad98990a8e | ||
|
|
8e58c143f2 | ||
|
|
556a4a2395 | ||
|
|
5be987b40f | ||
|
|
066bc35e69 | ||
|
|
403779437c | ||
|
|
fb806f61d4 | ||
|
|
6ce306661c | ||
|
|
3c08ff94d4 | ||
|
|
a6afae2356 | ||
|
|
0eea7070a7 | ||
|
|
105c2b1eea | ||
|
|
82bb0e8dda | ||
|
|
8c01179075 | ||
|
|
c9d9a96630 | ||
|
|
8f21c9a920 | ||
|
|
0ba7d05ea7 | ||
|
|
5a4c5b4155 | ||
|
|
55323fb497 | ||
|
|
7c082d2471 | ||
|
|
f3cafcf983 | ||
|
|
75073e4aa6 | ||
|
|
a3c23f650c | ||
|
|
0545cd5879 | ||
|
|
c96506f22c | ||
|
|
49b2006824 | ||
|
|
8c6f96faab | ||
|
|
a0e648abfd | ||
|
|
6350cd12fc | ||
|
|
f2fab0677b | ||
|
|
edffc52927 | ||
|
|
d6e5e3d103 | ||
|
|
5be7a0ebf7 | ||
|
|
7f722fe7d3 | ||
|
|
a01732ee9b | ||
|
|
85ac11b69b | ||
|
|
590cfb77a5 | ||
|
|
f01dd16a27 | ||
|
|
df49287e5f | ||
|
|
c8ec8391ee | ||
|
|
3499e48064 | ||
|
|
2e379cb8a5 | ||
|
|
f8ee3c2369 | ||
|
|
c74fa11518 | ||
|
|
ceec4455df | ||
|
|
17c9975c0b | ||
|
|
6c1cdff912 | ||
|
|
79f53f569d | ||
|
|
ccb85cc719 | ||
|
|
c0eff8a07f | ||
|
|
954626f157 | ||
|
|
17e7dfa4bd | ||
|
|
971f233fb7 | ||
|
|
b12bc692af | ||
|
|
730301b34d | ||
|
|
c443bcf43c | ||
|
|
b77e7eeddc | ||
|
|
031b7b57a1 | ||
|
|
5123fab525 | ||
|
|
705b96c6f9 | ||
|
|
9ec582002b | ||
|
|
ee79277774 | ||
|
|
db02dc218e | ||
|
|
b66ce1089e | ||
|
|
ec0e70b599 | ||
|
|
a273482f9d | ||
|
|
76cf8c4cf7 | ||
|
|
9691ecc839 | ||
|
|
59b2a86359 | ||
|
|
fe7cd72cff | ||
|
|
f0761fc570 | ||
|
|
90990aa19d | ||
|
|
a3d3ce82e4 | ||
|
|
b8e48113a3 | ||
|
|
d4b1003a97 | ||
|
|
efd83567c9 | ||
|
|
5563f373f7 | ||
|
|
15a36619fe | ||
|
|
38e54b626e | ||
|
|
8aa30fb56a | ||
|
|
b764becd1b | ||
|
|
219370932e | ||
|
|
90afae186c | ||
|
|
84e49a809d | ||
|
|
1cfb9ff46a | ||
|
|
f35026c74f | ||
|
|
5f2d3da8c5 | ||
|
|
4e61f32a28 | ||
|
|
d7814c7011 | ||
|
|
aa40668e84 | ||
|
|
3767e6e96f | ||
|
|
44976cef6c | ||
|
|
eba4417947 | ||
|
|
c99204d370 | ||
|
|
1bfc4335bb | ||
|
|
6b9c7485f1 | ||
|
|
737f3d78f2 | ||
|
|
b1d5e1b5e3 | ||
|
|
8d92a5cc14 | ||
|
|
fc455df92c | ||
|
|
c0076ebfa1 | ||
|
|
5d607aa3cd | ||
|
|
fa1b9a4098 | ||
|
|
c8c4dbb409 | ||
|
|
16628e6cea | ||
|
|
7067c12991 | ||
|
|
7b47e241e0 | ||
|
|
d1e46207a5 | ||
|
|
2a04b97cbd | ||
|
|
e6c8ef59e0 | ||
|
|
d3380f41de | ||
|
|
4ef1633969 | ||
|
|
57e593aab2 | ||
|
|
6461caacbb | ||
|
|
e5531e2a93 | ||
|
|
329402a614 | ||
|
|
4656ed462e | ||
|
|
96ddad91a9 | ||
|
|
5eb40588d2 | ||
|
|
58def149aa | ||
|
|
0ee5743d75 | ||
|
|
7c266f3e81 | ||
|
|
d7ce981cd1 | ||
|
|
eadadf6299 | ||
|
|
8ac9fabd07 | ||
|
|
44c2b4b281 | ||
|
|
4cd97611e5 | ||
|
|
da27380ab5 | ||
|
|
756e539661 | ||
|
|
cde44e3172 | ||
|
|
e79a4b34b0 | ||
|
|
e9f0bdd72c | ||
|
|
d080291150 | ||
|
|
06c69c56ba | ||
|
|
d79710ba9d | ||
|
|
c9bc7dd0b6 | ||
|
|
ebc26c7421 | ||
|
|
3769425f6b | ||
|
|
a50957443e | ||
|
|
63fa007af0 |
@@ -2,7 +2,7 @@
|
||||
# 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 the LVM2.
|
||||
# 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
|
||||
@@ -68,3 +68,6 @@ cscope.out: tools
|
||||
@CSCOPE_CMD@ -b -R
|
||||
all: cscope.out
|
||||
endif
|
||||
|
||||
check: all
|
||||
$(MAKE) -C test all
|
||||
|
||||
219
WHATS_NEW
219
WHATS_NEW
@@ -1,27 +1,214 @@
|
||||
Version 2.02.28 -
|
||||
================================
|
||||
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.
|
||||
Change file locking state messages from debug to very verbose.
|
||||
Fix --addtag to drop @ prefix from name.
|
||||
Stop clvmd going haywire if a pre_function fails.
|
||||
Convert some vg_reads into vg_lock_and_reads.
|
||||
Avoid nested vg_reads when processing PVs in VGs and fix associated locking.
|
||||
Accept sizes with --readahead argument.
|
||||
Store size arguments as sectors internally.
|
||||
Attempt to remove incomplete LVs with lvcreate zeroing/activation problems.
|
||||
Add read_ahead activation code.
|
||||
Add activation/readahead configuration option and FMT_RESTRICTED_READAHEAD.
|
||||
Extend readahead arg to accept "auto" and "none".
|
||||
Add lv_read_ahead and lv_kernel_read_ahead fields to reports and lvdisplay.
|
||||
Prevent lvconvert -s from using same LV as origin and snapshot.
|
||||
Fix human-readable output of odd numbers of sectors.
|
||||
Add pv_mda_free and vg_mda_free fields to reports for raw text format.
|
||||
Add LVM2 version to 'Generated by' comment in metadata.
|
||||
Show 'not usable' space when PV is too large for device in pvdisplay.
|
||||
Ignore and fix up any excessive device size found in metadata.
|
||||
Fix error message when fixing up PV size in lvm2 metadata (2.02.11).
|
||||
Fix orphan-related locking in pvdisplay and pvs.
|
||||
Fix missing VG unlocks in some pvchange error paths.
|
||||
Add some missing validation of VG names.
|
||||
Rename validate_vg_name() to validate_new_vg_name().
|
||||
Change orphan lock to VG_ORPHANS.
|
||||
Change format1 to use ORPHAN as orphan VG name.
|
||||
Convert pvchange, pvdisplay, pvscan to use is_orphan()
|
||||
Add is_orphan_vg() and change all hard-coded checks to use it.
|
||||
Detect md superblocks version 1.0, 1.1 and 1.2.
|
||||
Add _alloc_pv() and _free_pv() from _pv_create() code and fix error paths.
|
||||
Add pv_dev_name() to access PV device name.
|
||||
Add const attributes to pv accessor functions.
|
||||
Refactor vg_add_snapshot() and lv_create_empty().
|
||||
Handle new sysfs subsystem/block/devices directory structure.
|
||||
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.
|
||||
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.
|
||||
Detect command line PE values that exceed their 32-bit range.
|
||||
Include strerror string in dev_open_flags' stat failure message.
|
||||
Move guts of pvresize into library.
|
||||
Avoid error when --corelog is provided without --mirrorlog. (2.02.28)
|
||||
Correct --mirrorlog argument name in man pages (not --log).
|
||||
Clear MIRROR_NOTSYNCED LV flag when converting from mirror to linear.
|
||||
Modify lvremove to prompt for removal if LV active on other cluster nodes.
|
||||
Add '-f' to vgremove to force removal of VG even if LVs exist.
|
||||
|
||||
Version 2.02.28 - 24th August 2007
|
||||
==================================
|
||||
Fix clvmd logging so you can get lvm-level debugging out of it.
|
||||
Introduce VG_GLOBAL lock type for vgscan/pvscan to trigger clvmd -R.
|
||||
Change locking_flags from int to uint32_t.
|
||||
Fix clvmd -R, so it fully refreshes the caches.
|
||||
Change lvconvert_mirrors to use mirror segtype not striped.
|
||||
Fix lvconvert_mirrors detection of number of existing mirrors.
|
||||
Clean up numerous compiler warnings that appeared in recent releases.
|
||||
Remove several unused parameters from _allocate().
|
||||
Only permit --force, --verbose and --debug arguments to be repeated.
|
||||
Fix inconsistent licence notices: executables are GPLv2; libraries LGPLv2.1.
|
||||
Move guts of lvremove into library.
|
||||
Allow clvmd debug to be turned on in a running daemon using clvmd -d
|
||||
Move guts of vgremove and lvremove into library, including yes_no_prompt.
|
||||
Allow clvmd debug to be turned on in a running daemon using clvmd -d [-C].
|
||||
Update to use autoconf 2.61, while still supporting 2.57.
|
||||
Add more cluster info to lvmdump
|
||||
Add const attributes where possible, first cut.
|
||||
Add more cluster info to lvmdump.
|
||||
Add further const attributes throughout.
|
||||
Add support for renaming mirrored LVs.
|
||||
Factor out core of lvrename() to lv_rename lvm library function.
|
||||
Add --log argument to specify log type for mirrors.
|
||||
Don't try to monitor devices which we failed to create.
|
||||
Don't leak a file descriptor in fcntl_lock_file(), when fcntl fails.
|
||||
Remove create_dir function; use now-equivalent dm_create_dir instead
|
||||
Detect stream write failure reliably; new fn: lvm_fclose; use dm_fclose
|
||||
Factor out core of lvrename() to library function.
|
||||
Add --mirrorlog argument to specify log type for mirrors.
|
||||
Don't attempt to monitor devices if their creation failed in _lv_activate.
|
||||
Don't leak a file descriptor in fcntl_lock_file() when fcntl fails.
|
||||
Replace create_dir with dm_create_dir.
|
||||
Detect stream write failure reliably with lvm_fclose using dm_fclose.
|
||||
Fix clvmd if compiled with gulm support. (2.02.26)
|
||||
Trivial fix to lvdisplay man page.
|
||||
Fix lvdisplay man page to say LV size is reported in sectors, not KB.
|
||||
Add vg_lock_and_read() external library function.
|
||||
Fix loading of persistent cache if cache_dir is used. (2.02.23)
|
||||
Eliminate uses of strdup+basename. Use last_path_component instead.
|
||||
Reduce _compare_paths lstat error message from log_error to log_very_verbose.
|
||||
Create util.h with last_path_component replacing strdup + basename.
|
||||
Use gcc's printf attribute wherever possible.
|
||||
In _line_append, use "sizeof buf - 1" rather than equivalent "4095"
|
||||
In _line_append, use "sizeof buf - 1" rather than equivalent "4095".
|
||||
Introduce is_same_inode macro, now including a comparison of st_dev.
|
||||
Don't leak a file descriptor in _lock_file(), when flock fails.
|
||||
Don't leak a file descriptor in _lock_file() when flock fails.
|
||||
Add SUN's LDOM virtual block device (vdisk) and ps3disk to filters.
|
||||
Split metadata-external.h out from metadata.h for the tools to use.
|
||||
|
||||
|
||||
31
WHATS_NEW_DM
31
WHATS_NEW_DM
@@ -1,3 +1,31 @@
|
||||
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 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.
|
||||
|
||||
Version 1.02.22 - 21st August 2007
|
||||
==================================
|
||||
Fix inconsistent licence notices: executables are GPLv2; libraries LGPLv2.1.
|
||||
@@ -11,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
|
||||
================================
|
||||
@@ -299,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.
|
||||
|
||||
|
||||
365
configure
vendored
365
configure
vendored
@@ -719,6 +719,7 @@ CLVMD
|
||||
CLUSTER
|
||||
FSADM
|
||||
DMEVENTD
|
||||
LIB_PTHREAD
|
||||
LTLIBOBJS'
|
||||
ac_subst_files=''
|
||||
ac_precious_vars='build_alias
|
||||
@@ -8066,8 +8067,8 @@ fi
|
||||
echo "${ECHO_T}$CMDLIB" >&6; }
|
||||
|
||||
################################################################################
|
||||
{ echo "$as_me:$LINENO: checking whether to build fsadm" >&5
|
||||
echo $ECHO_N "checking whether to build fsadm... $ECHO_C" >&6; }
|
||||
{ echo "$as_me:$LINENO: checking whether to install fsadm" >&5
|
||||
echo $ECHO_N "checking whether to install fsadm... $ECHO_C" >&6; }
|
||||
# Check whether --enable-fsadm was given.
|
||||
if test "${enable_fsadm+set}" = set; then
|
||||
enableval=$enable_fsadm; FSADM=$enableval
|
||||
@@ -8852,6 +8853,99 @@ _ACEOF
|
||||
{ echo "$as_me:$LINENO: WARNING: Disabling selinux" >&5
|
||||
echo "$as_me: WARNING: Disabling selinux" >&2;}
|
||||
fi
|
||||
|
||||
# With --enable-static_link and selinux enabled, linking lvm.static
|
||||
# fails on at least Debian unstable due to unsatisfied references
|
||||
# to pthread_mutex_lock and _unlock. See if we need -lpthread.
|
||||
if test "$STATIC_LINK-$HAVE_SELINUX" = yes-yes; then
|
||||
lvm_saved_libs=$LIBS
|
||||
LIBS="$LIBS -static"
|
||||
{ echo "$as_me:$LINENO: checking for library containing pthread_mutex_lock" >&5
|
||||
echo $ECHO_N "checking for library containing pthread_mutex_lock... $ECHO_C" >&6; }
|
||||
if test "${ac_cv_search_pthread_mutex_lock+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
ac_func_search_save_LIBS=$LIBS
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char pthread_mutex_lock ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return pthread_mutex_lock ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
for ac_lib in '' pthread; do
|
||||
if test -z "$ac_lib"; then
|
||||
ac_res="none required"
|
||||
else
|
||||
ac_res=-l$ac_lib
|
||||
LIBS="-l$ac_lib $ac_func_search_save_LIBS"
|
||||
fi
|
||||
rm -f conftest.$ac_objext conftest$ac_exeext
|
||||
if { (ac_try="$ac_link"
|
||||
case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
|
||||
(eval "$ac_link") 2>conftest.er1
|
||||
ac_status=$?
|
||||
grep -v '^ *+' conftest.er1 >conftest.err
|
||||
rm -f conftest.er1
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } && {
|
||||
test -z "$ac_c_werror_flag" ||
|
||||
test ! -s conftest.err
|
||||
} && test -s conftest$ac_exeext &&
|
||||
$as_test_x conftest$ac_exeext; then
|
||||
ac_cv_search_pthread_mutex_lock=$ac_res
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
|
||||
fi
|
||||
|
||||
rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
|
||||
conftest$ac_exeext
|
||||
if test "${ac_cv_search_pthread_mutex_lock+set}" = set; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test "${ac_cv_search_pthread_mutex_lock+set}" = set; then
|
||||
:
|
||||
else
|
||||
ac_cv_search_pthread_mutex_lock=no
|
||||
fi
|
||||
rm conftest.$ac_ext
|
||||
LIBS=$ac_func_search_save_LIBS
|
||||
fi
|
||||
{ echo "$as_me:$LINENO: result: $ac_cv_search_pthread_mutex_lock" >&5
|
||||
echo "${ECHO_T}$ac_cv_search_pthread_mutex_lock" >&6; }
|
||||
ac_res=$ac_cv_search_pthread_mutex_lock
|
||||
if test "$ac_res" != no; then
|
||||
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
|
||||
test "$ac_cv_search_pthread_mutex_lock" = "none required" ||
|
||||
LIB_PTHREAD=-lpthread
|
||||
fi
|
||||
|
||||
LIBS=$lvm_saved_libs
|
||||
fi
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
@@ -9365,6 +9459,12 @@ else
|
||||
fi
|
||||
|
||||
|
||||
# Convert a relative dir name to absolute.
|
||||
case $DMDIR in
|
||||
/*) ;;
|
||||
*) DMDIR="`pwd`/$DMDIR" ;;
|
||||
esac
|
||||
|
||||
################################################################################
|
||||
if test x$READLINE = xyes; then
|
||||
|
||||
@@ -10095,253 +10195,6 @@ rm -f conftest*
|
||||
|
||||
fi
|
||||
|
||||
if test x$FSADM = xyes; then
|
||||
|
||||
|
||||
|
||||
for ac_header in fstab.h sys/mount.h sys/vfs.h
|
||||
do
|
||||
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
|
||||
if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
|
||||
{ echo "$as_me:$LINENO: checking for $ac_header" >&5
|
||||
echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
|
||||
if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
fi
|
||||
ac_res=`eval echo '${'$as_ac_Header'}'`
|
||||
{ echo "$as_me:$LINENO: result: $ac_res" >&5
|
||||
echo "${ECHO_T}$ac_res" >&6; }
|
||||
else
|
||||
# Is the header compilable?
|
||||
{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
|
||||
echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
$ac_includes_default
|
||||
#include <$ac_header>
|
||||
_ACEOF
|
||||
rm -f conftest.$ac_objext
|
||||
if { (ac_try="$ac_compile"
|
||||
case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
|
||||
(eval "$ac_compile") 2>conftest.er1
|
||||
ac_status=$?
|
||||
grep -v '^ *+' conftest.er1 >conftest.err
|
||||
rm -f conftest.er1
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } && {
|
||||
test -z "$ac_c_werror_flag" ||
|
||||
test ! -s conftest.err
|
||||
} && test -s conftest.$ac_objext; then
|
||||
ac_header_compiler=yes
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
ac_header_compiler=no
|
||||
fi
|
||||
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
|
||||
echo "${ECHO_T}$ac_header_compiler" >&6; }
|
||||
|
||||
# Is the header present?
|
||||
{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
|
||||
echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
#include <$ac_header>
|
||||
_ACEOF
|
||||
if { (ac_try="$ac_cpp conftest.$ac_ext"
|
||||
case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
|
||||
(eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
|
||||
ac_status=$?
|
||||
grep -v '^ *+' conftest.er1 >conftest.err
|
||||
rm -f conftest.er1
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } >/dev/null && {
|
||||
test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
|
||||
test ! -s conftest.err
|
||||
}; then
|
||||
ac_header_preproc=yes
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
ac_header_preproc=no
|
||||
fi
|
||||
|
||||
rm -f conftest.err conftest.$ac_ext
|
||||
{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
|
||||
echo "${ECHO_T}$ac_header_preproc" >&6; }
|
||||
|
||||
# So? What about this header?
|
||||
case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
|
||||
yes:no: )
|
||||
{ echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
|
||||
echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
|
||||
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
|
||||
echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
|
||||
ac_header_preproc=yes
|
||||
;;
|
||||
no:yes:* )
|
||||
{ echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
|
||||
echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
|
||||
{ echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
|
||||
echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
|
||||
{ echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
|
||||
echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
|
||||
{ echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
|
||||
echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
|
||||
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
|
||||
echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
|
||||
{ echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
|
||||
echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
|
||||
|
||||
;;
|
||||
esac
|
||||
{ echo "$as_me:$LINENO: checking for $ac_header" >&5
|
||||
echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
|
||||
if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
eval "$as_ac_Header=\$ac_header_preproc"
|
||||
fi
|
||||
ac_res=`eval echo '${'$as_ac_Header'}'`
|
||||
{ echo "$as_me:$LINENO: result: $ac_res" >&5
|
||||
echo "${ECHO_T}$ac_res" >&6; }
|
||||
|
||||
fi
|
||||
if test `eval echo '${'$as_ac_Header'}'` = yes; then
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
|
||||
_ACEOF
|
||||
|
||||
else
|
||||
{ { echo "$as_me:$LINENO: error: bailing out" >&5
|
||||
echo "$as_me: error: bailing out" >&2;}
|
||||
{ (exit 1); exit 1; }; }
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
|
||||
for ac_func in memmove
|
||||
do
|
||||
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||
{ echo "$as_me:$LINENO: checking for $ac_func" >&5
|
||||
echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
|
||||
if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
|
||||
For example, HP-UX 11i <limits.h> declares gettimeofday. */
|
||||
#define $ac_func innocuous_$ac_func
|
||||
|
||||
/* System header to define __stub macros and hopefully few prototypes,
|
||||
which can conflict with char $ac_func (); below.
|
||||
Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
|
||||
<limits.h> exists even on freestanding compilers. */
|
||||
|
||||
#ifdef __STDC__
|
||||
# include <limits.h>
|
||||
#else
|
||||
# include <assert.h>
|
||||
#endif
|
||||
|
||||
#undef $ac_func
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char $ac_func ();
|
||||
/* The GNU C library defines this for functions which it implements
|
||||
to always fail with ENOSYS. Some functions are actually named
|
||||
something starting with __ and the normal name is an alias. */
|
||||
#if defined __stub_$ac_func || defined __stub___$ac_func
|
||||
choke me
|
||||
#endif
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return $ac_func ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
rm -f conftest.$ac_objext conftest$ac_exeext
|
||||
if { (ac_try="$ac_link"
|
||||
case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
|
||||
(eval "$ac_link") 2>conftest.er1
|
||||
ac_status=$?
|
||||
grep -v '^ *+' conftest.er1 >conftest.err
|
||||
rm -f conftest.er1
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } && {
|
||||
test -z "$ac_c_werror_flag" ||
|
||||
test ! -s conftest.err
|
||||
} && test -s conftest$ac_exeext &&
|
||||
$as_test_x conftest$ac_exeext; then
|
||||
eval "$as_ac_var=yes"
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
eval "$as_ac_var=no"
|
||||
fi
|
||||
|
||||
rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
fi
|
||||
ac_res=`eval echo '${'$as_ac_var'}'`
|
||||
{ echo "$as_me:$LINENO: result: $ac_res" >&5
|
||||
echo "${ECHO_T}$ac_res" >&6; }
|
||||
if test `eval echo '${'$as_ac_var'}'` = yes; then
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
|
||||
_ACEOF
|
||||
|
||||
else
|
||||
{ { echo "$as_me:$LINENO: error: bailing out" >&5
|
||||
echo "$as_me: error: bailing out" >&2;}
|
||||
{ (exit 1); exit 1; }; }
|
||||
fi
|
||||
done
|
||||
|
||||
fi
|
||||
|
||||
if test x$CLUSTER != xnone; then
|
||||
|
||||
|
||||
@@ -11269,10 +11122,11 @@ fi
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
################################################################################
|
||||
ac_config_files="$ac_config_files Makefile make.tmpl daemons/Makefile daemons/clvmd/Makefile dmeventd/Makefile dmeventd/mirror/Makefile doc/Makefile include/Makefile lib/Makefile lib/format1/Makefile lib/format_pool/Makefile lib/locking/Makefile lib/mirror/Makefile lib/snapshot/Makefile man/Makefile po/Makefile scripts/Makefile tools/Makefile tools/version.h tools/fsadm/Makefile test/mm/Makefile test/device/Makefile test/format1/Makefile test/regex/Makefile test/filters/Makefile"
|
||||
ac_config_files="$ac_config_files Makefile make.tmpl daemons/Makefile daemons/clvmd/Makefile dmeventd/Makefile dmeventd/mirror/Makefile dmeventd/snapshot/Makefile doc/Makefile include/Makefile lib/Makefile lib/format1/Makefile lib/format_pool/Makefile lib/locking/Makefile lib/mirror/Makefile lib/snapshot/Makefile test/Makefile man/Makefile po/Makefile scripts/Makefile tools/Makefile tools/version.h"
|
||||
|
||||
cat >confcache <<\_ACEOF
|
||||
# This file is a shell script that caches the results of configure
|
||||
@@ -11834,6 +11688,7 @@ do
|
||||
"daemons/clvmd/Makefile") CONFIG_FILES="$CONFIG_FILES daemons/clvmd/Makefile" ;;
|
||||
"dmeventd/Makefile") CONFIG_FILES="$CONFIG_FILES dmeventd/Makefile" ;;
|
||||
"dmeventd/mirror/Makefile") CONFIG_FILES="$CONFIG_FILES dmeventd/mirror/Makefile" ;;
|
||||
"dmeventd/snapshot/Makefile" ) CONFIG_FILES="$CONFIG_FILES dmeventd/snapshot/Makefile" ;;
|
||||
"doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
|
||||
"include/Makefile") CONFIG_FILES="$CONFIG_FILES include/Makefile" ;;
|
||||
"lib/Makefile") CONFIG_FILES="$CONFIG_FILES lib/Makefile" ;;
|
||||
@@ -11842,17 +11697,12 @@ do
|
||||
"lib/locking/Makefile") CONFIG_FILES="$CONFIG_FILES lib/locking/Makefile" ;;
|
||||
"lib/mirror/Makefile") CONFIG_FILES="$CONFIG_FILES lib/mirror/Makefile" ;;
|
||||
"lib/snapshot/Makefile") CONFIG_FILES="$CONFIG_FILES lib/snapshot/Makefile" ;;
|
||||
"test/Makefile") CONFIG_FILES="$CONFIG_FILES test/Makefile" ;;
|
||||
"man/Makefile") CONFIG_FILES="$CONFIG_FILES man/Makefile" ;;
|
||||
"po/Makefile") CONFIG_FILES="$CONFIG_FILES po/Makefile" ;;
|
||||
"scripts/Makefile") CONFIG_FILES="$CONFIG_FILES scripts/Makefile" ;;
|
||||
"tools/Makefile") CONFIG_FILES="$CONFIG_FILES tools/Makefile" ;;
|
||||
"tools/version.h") CONFIG_FILES="$CONFIG_FILES tools/version.h" ;;
|
||||
"tools/fsadm/Makefile") CONFIG_FILES="$CONFIG_FILES tools/fsadm/Makefile" ;;
|
||||
"test/mm/Makefile") CONFIG_FILES="$CONFIG_FILES test/mm/Makefile" ;;
|
||||
"test/device/Makefile") CONFIG_FILES="$CONFIG_FILES test/device/Makefile" ;;
|
||||
"test/format1/Makefile") CONFIG_FILES="$CONFIG_FILES test/format1/Makefile" ;;
|
||||
"test/regex/Makefile") CONFIG_FILES="$CONFIG_FILES test/regex/Makefile" ;;
|
||||
"test/filters/Makefile") CONFIG_FILES="$CONFIG_FILES test/filters/Makefile" ;;
|
||||
|
||||
*) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
|
||||
echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
|
||||
@@ -12060,10 +11910,11 @@ CLVMD!$CLVMD$ac_delim
|
||||
CLUSTER!$CLUSTER$ac_delim
|
||||
FSADM!$FSADM$ac_delim
|
||||
DMEVENTD!$DMEVENTD$ac_delim
|
||||
LIB_PTHREAD!$LIB_PTHREAD$ac_delim
|
||||
LTLIBOBJS!$LTLIBOBJS$ac_delim
|
||||
_ACEOF
|
||||
|
||||
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 9; then
|
||||
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 10; then
|
||||
break
|
||||
elif $ac_last_try; then
|
||||
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
|
||||
|
||||
82
configure.in
82
configure.in
@@ -1,8 +1,8 @@
|
||||
##
|
||||
## Copyright (C) 2000-2004 Sistina Software, Inc. All rights reserved.
|
||||
## Copyright (C) 2004 Red Hat, Inc. All rights reserved.
|
||||
## Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
|
||||
##
|
||||
## This file is part of the LVM2.
|
||||
## 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
|
||||
@@ -24,7 +24,7 @@ AC_CONFIG_HEADERS(lib/misc/configure.h)
|
||||
|
||||
################################################################################
|
||||
dnl -- Setup the directory where autoconf has auxilary files
|
||||
AC_CONFIG_AUX_DIR(autoconf)
|
||||
AC_CONFIG_AUX_DIR(autoconf)
|
||||
|
||||
################################################################################
|
||||
dnl -- Get system type
|
||||
@@ -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)
|
||||
@@ -453,6 +453,18 @@ if test x$SELINUX = xyes; then
|
||||
else
|
||||
AC_MSG_WARN(Disabling selinux)
|
||||
fi
|
||||
|
||||
# With --enable-static_link and selinux enabled, linking lvm.static
|
||||
# fails on at least Debian unstable due to unsatisfied references
|
||||
# to pthread_mutex_lock and _unlock. See if we need -lpthread.
|
||||
if test "$STATIC_LINK-$HAVE_SELINUX" = yes-yes; then
|
||||
lvm_saved_libs=$LIBS
|
||||
LIBS="$LIBS -static"
|
||||
AC_SEARCH_LIBS([pthread_mutex_lock], [pthread],
|
||||
[test "$ac_cv_search_pthread_mutex_lock" = "none required" ||
|
||||
LIB_PTHREAD=-lpthread])
|
||||
LIBS=$lvm_saved_libs
|
||||
fi
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
@@ -526,6 +538,12 @@ AC_ARG_WITH(dmdir,
|
||||
[ DMDIR="$withval" CPPFLAGS="$CPPFLAGS -I$DMDIR/include"],
|
||||
[ DMDIR= ])
|
||||
|
||||
# Convert a relative dir name to absolute.
|
||||
case $DMDIR in
|
||||
/*) ;;
|
||||
*) DMDIR="`pwd`/$DMDIR" ;;
|
||||
esac
|
||||
|
||||
################################################################################
|
||||
dnl -- Ensure additional headers required
|
||||
if test x$READLINE = xyes; then
|
||||
@@ -540,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))
|
||||
@@ -617,36 +630,33 @@ AC_SUBST(FSADM)
|
||||
AC_SUBST(DMEVENTD)
|
||||
AC_SUBST(CFLOW_CMD)
|
||||
AC_SUBST(CSCOPE_CMD)
|
||||
AC_SUBST([LIB_PTHREAD])
|
||||
|
||||
################################################################################
|
||||
dnl -- First and last lines should not contain files to generate in order to
|
||||
dnl -- First and last lines should not contain files to generate in order to
|
||||
dnl -- keep utility scripts running properly
|
||||
AC_CONFIG_FILES([\
|
||||
Makefile \
|
||||
make.tmpl \
|
||||
daemons/Makefile \
|
||||
daemons/clvmd/Makefile \
|
||||
dmeventd/Makefile \
|
||||
dmeventd/mirror/Makefile \
|
||||
doc/Makefile \
|
||||
include/Makefile \
|
||||
lib/Makefile \
|
||||
lib/format1/Makefile \
|
||||
lib/format_pool/Makefile \
|
||||
lib/locking/Makefile \
|
||||
lib/mirror/Makefile \
|
||||
lib/snapshot/Makefile \
|
||||
man/Makefile \
|
||||
po/Makefile \
|
||||
scripts/Makefile \
|
||||
tools/Makefile \
|
||||
tools/version.h \
|
||||
tools/fsadm/Makefile \
|
||||
test/mm/Makefile \
|
||||
test/device/Makefile \
|
||||
test/format1/Makefile \
|
||||
test/regex/Makefile \
|
||||
test/filters/Makefile \
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
make.tmpl
|
||||
daemons/Makefile
|
||||
daemons/clvmd/Makefile
|
||||
dmeventd/Makefile
|
||||
dmeventd/mirror/Makefile
|
||||
dmeventd/snapshot/Makefile
|
||||
doc/Makefile
|
||||
include/Makefile
|
||||
lib/Makefile
|
||||
lib/format1/Makefile
|
||||
lib/format_pool/Makefile
|
||||
lib/locking/Makefile
|
||||
lib/mirror/Makefile
|
||||
lib/snapshot/Makefile
|
||||
test/Makefile
|
||||
man/Makefile
|
||||
po/Makefile
|
||||
scripts/Makefile
|
||||
tools/Makefile
|
||||
tools/version.h
|
||||
])
|
||||
AC_OUTPUT
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# Copyright (C) 2004 Red Hat, Inc. All rights reserved.
|
||||
#
|
||||
# This file is part of the LVM2.
|
||||
# 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
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# Copyright (C) 2004 Red Hat, Inc. All rights reserved.
|
||||
#
|
||||
# This file is part of the LVM2.
|
||||
# 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
|
||||
|
||||
@@ -67,4 +67,5 @@ static const char CLVMD_SOCKNAME[] = "\0clvmd";
|
||||
#define CLVMD_CMD_REFRESH 40
|
||||
#define CLVMD_CMD_GET_CLUSTERNAME 41
|
||||
#define CLVMD_CMD_SET_DEBUG 42
|
||||
#define CLVMD_CMD_VG_BACKUP 43
|
||||
#endif
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -115,8 +115,13 @@ int do_command(struct local_client *client, struct clvm_header *msg, int msglen,
|
||||
break;
|
||||
|
||||
case CLVMD_CMD_LOCK_VG:
|
||||
lockname = &args[2];
|
||||
/* Check to see if the VG is in use by LVM1 */
|
||||
status = do_check_lvm1(&args[2]);
|
||||
status = do_check_lvm1(lockname);
|
||||
/* P_global causes a cache refresh */
|
||||
if (strcmp(lockname, "P_global") == 0)
|
||||
do_refresh_cache();
|
||||
|
||||
break;
|
||||
|
||||
case CLVMD_CMD_LOCK_LV:
|
||||
@@ -148,6 +153,10 @@ int do_command(struct local_client *client, struct clvm_header *msg, int msglen,
|
||||
*retlen = strlen(*buf)+1;
|
||||
break;
|
||||
|
||||
case CLVMD_CMD_VG_BACKUP:
|
||||
lvm_do_backup(&args[2]);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Won't get here because command is validated in pre_command */
|
||||
break;
|
||||
@@ -255,6 +264,7 @@ int do_pre_command(struct local_client *client)
|
||||
case CLVMD_CMD_REFRESH:
|
||||
case CLVMD_CMD_GET_CLUSTERNAME:
|
||||
case CLVMD_CMD_SET_DEBUG:
|
||||
case CLVMD_CMD_VG_BACKUP:
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -284,6 +294,7 @@ int do_post_command(struct local_client *client)
|
||||
break;
|
||||
|
||||
case CLVMD_CMD_LOCK_VG:
|
||||
case CLVMD_CMD_VG_BACKUP:
|
||||
/* Nothing to do here */
|
||||
break;
|
||||
|
||||
|
||||
@@ -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 =
|
||||
@@ -1379,8 +1380,10 @@ static __attribute__ ((noreturn)) void *pre_and_post_thread(void *arg)
|
||||
break;
|
||||
} while(1);
|
||||
|
||||
if (status)
|
||||
continue; /* Wait for another PRE command */
|
||||
if (status) {
|
||||
client->bits.localsock.state = POST_COMMAND;
|
||||
goto next_pre;
|
||||
}
|
||||
|
||||
/* We may need to wait for the condition variable before running the post command */
|
||||
pthread_mutex_lock(&client->bits.localsock.mutex);
|
||||
@@ -1409,11 +1412,12 @@ static __attribute__ ((noreturn)) void *pre_and_post_thread(void *arg)
|
||||
log_error("Error sending to pipe: %m\n");
|
||||
break;
|
||||
} while(1);
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -1543,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);
|
||||
}
|
||||
|
||||
@@ -1575,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;
|
||||
@@ -1611,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;
|
||||
@@ -1728,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);
|
||||
@@ -1822,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));
|
||||
|
||||
@@ -1,226 +0,0 @@
|
||||
/******************************************************************************
|
||||
*******************************************************************************
|
||||
**
|
||||
** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
|
||||
** Copyright (C) 2004 Red Hat, Inc. All rights reserved.
|
||||
**
|
||||
** This copyrighted material is made available to anyone wishing to use,
|
||||
** modify, copy, or redistribute it subject to the terms and conditions
|
||||
** of the GNU General Public License v.2.
|
||||
**
|
||||
*******************************************************************************
|
||||
******************************************************************************/
|
||||
|
||||
/* CMAN socket interface header,
|
||||
may be include by user or kernel code */
|
||||
|
||||
#ifndef __CNXMAN_SOCKET_H
|
||||
#define __CNXMAN_SOCKET_H
|
||||
|
||||
/* A currently unused number. TIPC also uses this number and you're unlikely
|
||||
to be using both.
|
||||
*/
|
||||
#define AF_CLUSTER 30
|
||||
#define PF_CLUSTER AF_CLUSTER
|
||||
|
||||
/* Protocol(socket) types */
|
||||
#define CLPROTO_MASTER 2
|
||||
#define CLPROTO_CLIENT 3
|
||||
|
||||
/* ioctls -- should register these properly */
|
||||
#define SIOCCLUSTER_NOTIFY _IOW('x', 0x01, int)
|
||||
#define SIOCCLUSTER_REMOVENOTIFY _IO( 'x', 0x02)
|
||||
#define SIOCCLUSTER_GETMEMBERS _IOR('x', 0x03, struct cl_cluster_nodelist)
|
||||
#define SIOCCLUSTER_SETEXPECTED_VOTES _IOW('x', 0x04, int)
|
||||
#define SIOCCLUSTER_ISQUORATE _IO( 'x', 0x05)
|
||||
#define SIOCCLUSTER_ISLISTENING _IOW('x', 0x06, struct cl_listen_request)
|
||||
#define SIOCCLUSTER_GETALLMEMBERS _IOR('x', 0x07, struct cl_cluster_nodelist)
|
||||
#define SIOCCLUSTER_SET_VOTES _IOW('x', 0x08, int)
|
||||
#define SIOCCLUSTER_GET_VERSION _IOR('x', 0x09, struct cl_version)
|
||||
#define SIOCCLUSTER_SET_VERSION _IOW('x', 0x0a, struct cl_version)
|
||||
#define SIOCCLUSTER_ISACTIVE _IO( 'x', 0x0b)
|
||||
#define SIOCCLUSTER_KILLNODE _IOW('x', 0x0c, int)
|
||||
#define SIOCCLUSTER_GET_JOINCOUNT _IO( 'x', 0x0d)
|
||||
#define SIOCCLUSTER_SERVICE_REGISTER _IOW('x', 0x0e, char)
|
||||
#define SIOCCLUSTER_SERVICE_UNREGISTER _IO('x', 0x0f)
|
||||
#define SIOCCLUSTER_SERVICE_JOIN _IO( 'x', 0x10)
|
||||
#define SIOCCLUSTER_SERVICE_LEAVE _IO( 'x', 0x20)
|
||||
#define SIOCCLUSTER_SERVICE_SETSIGNAL _IOW('x', 0x30, int)
|
||||
#define SIOCCLUSTER_SERVICE_STARTDONE _IOW('x', 0x40, unsigned int)
|
||||
#define SIOCCLUSTER_SERVICE_GETEVENT _IOR('x', 0x50, struct cl_service_event)
|
||||
#define SIOCCLUSTER_SERVICE_GETMEMBERS _IOR('x', 0x60, struct cl_cluster_nodelist)
|
||||
#define SIOCCLUSTER_SERVICE_GLOBALID _IOR('x', 0x70, uint32_t)
|
||||
#define SIOCCLUSTER_SERVICE_SETLEVEL _IOR('x', 0x80, int)
|
||||
#define SIOCCLUSTER_GETNODE _IOWR('x', 0x90, struct cl_cluster_node)
|
||||
#define SIOCCLUSTER_BARRIER _IOW('x', 0x0a0, struct cl_barrier_info)
|
||||
|
||||
/* These were setsockopts */
|
||||
#define SIOCCLUSTER_PASS_SOCKET _IOW('x', 0x0b0, struct cl_passed_sock)
|
||||
#define SIOCCLUSTER_SET_NODENAME _IOW('x', 0x0b1, char *)
|
||||
#define SIOCCLUSTER_SET_NODEID _IOW('x', 0x0b2, int)
|
||||
#define SIOCCLUSTER_JOIN_CLUSTER _IOW('x', 0x0b3, struct cl_join_cluster_info)
|
||||
#define SIOCCLUSTER_LEAVE_CLUSTER _IOW('x', 0x0b4, int)
|
||||
|
||||
|
||||
/* Maximum size of a cluster message */
|
||||
#define CMAN_MAX_CLUSTER_MESSAGE 1500
|
||||
#define CMAN_MAX_CLUSTER_MEMBER_NAME_LEN 255
|
||||
#define MAX_BARRIER_NAME_LEN 33
|
||||
#define MAX_SA_ADDR_LEN 12
|
||||
#define MAX_CLUSTER_NAME_LEN 16
|
||||
|
||||
/* Well-known cluster port numbers */
|
||||
#define CLUSTER_PORT_MEMBERSHIP 1 /* Mustn't block during cluster
|
||||
* transitions! */
|
||||
#define CLUSTER_PORT_SERVICES 2
|
||||
#define CLUSTER_PORT_SYSMAN 10 /* Remote execution daemon */
|
||||
#define CLUSTER_PORT_CLVMD 11 /* Cluster LVM daemon */
|
||||
#define CLUSTER_PORT_SLM 12 /* LVM SLM (simple lock manager) */
|
||||
|
||||
/* Port numbers above this will be blocked when the cluster is inquorate or in
|
||||
* transition */
|
||||
#define HIGH_PROTECTED_PORT 9
|
||||
|
||||
/* Reasons for leaving the cluster */
|
||||
#define CLUSTER_LEAVEFLAG_DOWN 0 /* Normal shutdown */
|
||||
#define CLUSTER_LEAVEFLAG_KILLED 1
|
||||
#define CLUSTER_LEAVEFLAG_PANIC 2
|
||||
#define CLUSTER_LEAVEFLAG_REMOVED 3 /* This one can reduce quorum */
|
||||
#define CLUSTER_LEAVEFLAG_REJECTED 4 /* Not allowed into the cluster in the
|
||||
* first place */
|
||||
#define CLUSTER_LEAVEFLAG_INCONSISTENT 5 /* Our view of the cluster is
|
||||
* in a minority */
|
||||
#define CLUSTER_LEAVEFLAG_DEAD 6 /* Discovered to be dead */
|
||||
#define CLUSTER_LEAVEFLAG_FORCE 0x10 /* Forced by command-line */
|
||||
|
||||
/* OOB messages sent to a local socket */
|
||||
#define CLUSTER_OOB_MSG_PORTCLOSED 1
|
||||
#define CLUSTER_OOB_MSG_STATECHANGE 2
|
||||
#define CLUSTER_OOB_MSG_SERVICEEVENT 3
|
||||
|
||||
/* Sendmsg flags, these are above the normal sendmsg flags so they don't
|
||||
* interfere */
|
||||
#define MSG_NOACK 0x010000 /* Don't need an ACK for this message */
|
||||
#define MSG_QUEUE 0x020000 /* Queue the message for sending later */
|
||||
#define MSG_MULTICAST 0x080000 /* Message was sent to all nodes in the cluster
|
||||
*/
|
||||
#define MSG_ALLINT 0x100000 /* Send out of all interfaces */
|
||||
#define MSG_REPLYEXP 0x200000 /* Reply is expected */
|
||||
|
||||
typedef enum { NODESTATE_REMOTEMEMBER, NODESTATE_JOINING, NODESTATE_MEMBER,
|
||||
NODESTATE_DEAD } nodestate_t;
|
||||
|
||||
|
||||
struct sockaddr_cl {
|
||||
unsigned short scl_family;
|
||||
unsigned char scl_flags;
|
||||
unsigned char scl_port;
|
||||
int scl_nodeid;
|
||||
};
|
||||
|
||||
/*
|
||||
* This is how we pass the multicast & receive sockets into kernel space.
|
||||
*/
|
||||
struct cl_passed_sock {
|
||||
int fd; /* FD of master socket to do multicast on */
|
||||
int number; /* Socket number, to match up recvonly & bcast
|
||||
* sockets */
|
||||
int multicast; /* Is it multicast or receive ? */
|
||||
};
|
||||
|
||||
/* Cluster configuration info passed when we join the cluster */
|
||||
struct cl_join_cluster_info {
|
||||
unsigned char votes;
|
||||
unsigned int expected_votes;
|
||||
unsigned int two_node;
|
||||
unsigned int config_version;
|
||||
|
||||
char cluster_name[17];
|
||||
};
|
||||
|
||||
|
||||
/* This is the structure, per node, returned from the membership ioctl */
|
||||
struct cl_cluster_node {
|
||||
unsigned int size;
|
||||
unsigned int node_id;
|
||||
unsigned int us;
|
||||
unsigned int leave_reason;
|
||||
unsigned int incarnation;
|
||||
nodestate_t state;
|
||||
char name[CMAN_MAX_CLUSTER_MEMBER_NAME_LEN];
|
||||
unsigned char votes;
|
||||
};
|
||||
|
||||
/* The struct passed to the membership ioctls */
|
||||
struct cl_cluster_nodelist {
|
||||
uint32_t max_members;
|
||||
struct cl_cluster_node *nodes;
|
||||
};
|
||||
|
||||
/* Structure passed to SIOCCLUSTER_ISLISTENING */
|
||||
struct cl_listen_request {
|
||||
unsigned char port;
|
||||
int nodeid;
|
||||
};
|
||||
|
||||
/* A Cluster PORTCLOSED message - received by a local user as an OOB message */
|
||||
struct cl_portclosed_oob {
|
||||
unsigned char cmd; /* CLUSTER_OOB_MSG_PORTCLOSED */
|
||||
unsigned char port;
|
||||
};
|
||||
|
||||
/* Get all version numbers or set the config version */
|
||||
struct cl_version {
|
||||
unsigned int major;
|
||||
unsigned int minor;
|
||||
unsigned int patch;
|
||||
unsigned int config;
|
||||
};
|
||||
|
||||
/* structure passed to barrier ioctls */
|
||||
struct cl_barrier_info {
|
||||
char cmd;
|
||||
char name[MAX_BARRIER_NAME_LEN];
|
||||
unsigned int flags;
|
||||
unsigned long arg;
|
||||
};
|
||||
|
||||
typedef enum { SERVICE_EVENT_STOP, SERVICE_EVENT_START, SERVICE_EVENT_FINISH,
|
||||
SERVICE_EVENT_LEAVEDONE } service_event_t;
|
||||
|
||||
typedef enum { SERVICE_START_FAILED, SERVICE_START_JOIN, SERVICE_START_LEAVE }
|
||||
service_start_t;
|
||||
|
||||
struct cl_service_event {
|
||||
service_event_t type;
|
||||
service_start_t start_type;
|
||||
unsigned int event_id;
|
||||
unsigned int last_stop;
|
||||
unsigned int last_start;
|
||||
unsigned int last_finish;
|
||||
unsigned int node_count;
|
||||
};
|
||||
|
||||
|
||||
/* Commands to the barrier ioctl */
|
||||
#define BARRIER_IOCTL_REGISTER 1
|
||||
#define BARRIER_IOCTL_CHANGE 2
|
||||
#define BARRIER_IOCTL_DELETE 3
|
||||
#define BARRIER_IOCTL_WAIT 4
|
||||
|
||||
/* Attributes of a barrier - bitmask */
|
||||
#define BARRIER_ATTR_AUTODELETE 1
|
||||
#define BARRIER_ATTR_MULTISTEP 2
|
||||
#define BARRIER_ATTR_MANUAL 4
|
||||
#define BARRIER_ATTR_ENABLED 8
|
||||
#define BARRIER_ATTR_CALLBACK 16
|
||||
|
||||
/* Attribute setting commands */
|
||||
#define BARRIER_SETATTR_AUTODELETE 1
|
||||
#define BARRIER_SETATTR_MULTISTEP 2
|
||||
#define BARRIER_SETATTR_ENABLED 3
|
||||
#define BARRIER_SETATTR_NODES 4
|
||||
#define BARRIER_SETATTR_CALLBACK 5
|
||||
#define BARRIER_SETATTR_TIMEOUT 6
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
*
|
||||
@@ -42,9 +42,11 @@
|
||||
|
||||
/* LVM2 headers */
|
||||
#include "toolcontext.h"
|
||||
#include "lvmcache.h"
|
||||
#include "log.h"
|
||||
#include "activate.h"
|
||||
#include "locking.h"
|
||||
#include "archiver.h"
|
||||
#include "defaults.h"
|
||||
|
||||
static struct cmd_context *cmd = NULL;
|
||||
@@ -52,6 +54,7 @@ static struct dm_hash_table *lv_hash = NULL;
|
||||
static pthread_mutex_t lv_hash_lock;
|
||||
static pthread_mutex_t lvm_lock;
|
||||
static char last_error[1024];
|
||||
static int suspended = 0;
|
||||
|
||||
struct lv_info {
|
||||
int lock_id;
|
||||
@@ -222,7 +225,7 @@ static int do_activate_lv(char *resource, unsigned char lock_flags, int mode)
|
||||
}
|
||||
|
||||
/* If it's suspended then resume it */
|
||||
if (!lv_info_by_lvid(cmd, resource, &lvi, 0))
|
||||
if (!lv_info_by_lvid(cmd, resource, &lvi, 0, 0))
|
||||
return EIO;
|
||||
|
||||
if (lvi.suspended)
|
||||
@@ -268,7 +271,7 @@ static int do_suspend_lv(char *resource)
|
||||
}
|
||||
|
||||
/* Only suspend it if it exists */
|
||||
if (!lv_info_by_lvid(cmd, resource, &lvi, 0))
|
||||
if (!lv_info_by_lvid(cmd, resource, &lvi, 0, 0))
|
||||
return EIO;
|
||||
|
||||
if (lvi.exists) {
|
||||
@@ -315,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;
|
||||
@@ -338,11 +341,15 @@ int do_lock_lv(unsigned char command, unsigned char lock_flags, char *resource)
|
||||
|
||||
case LCK_LV_SUSPEND:
|
||||
status = do_suspend_lv(resource);
|
||||
if (!status)
|
||||
suspended++;
|
||||
break;
|
||||
|
||||
case LCK_UNLOCK:
|
||||
case LCK_LV_RESUME: /* if active */
|
||||
status = do_resume_lv(resource);
|
||||
if (!status)
|
||||
suspended--;
|
||||
break;
|
||||
|
||||
case LCK_LV_ACTIVATE:
|
||||
@@ -413,7 +420,7 @@ int post_lock_lv(unsigned char command, unsigned char lock_flags,
|
||||
struct lvinfo lvi;
|
||||
|
||||
pthread_mutex_lock(&lvm_lock);
|
||||
status = lv_info_by_lvid(cmd, resource, &lvi, 0);
|
||||
status = lv_info_by_lvid(cmd, resource, &lvi, 0, 0);
|
||||
pthread_mutex_unlock(&lvm_lock);
|
||||
if (!status)
|
||||
return EIO;
|
||||
@@ -430,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;
|
||||
@@ -442,9 +449,15 @@ int do_check_lvm1(const char *vgname)
|
||||
|
||||
int do_refresh_cache()
|
||||
{
|
||||
int ret;
|
||||
DEBUGLOG("Refreshing context\n");
|
||||
log_notice("Refreshing context");
|
||||
return refresh_toolcontext(cmd)==1?0:-1;
|
||||
|
||||
ret = refresh_toolcontext(cmd);
|
||||
init_full_scan_done(0);
|
||||
lvmcache_label_scan(cmd, 2);
|
||||
|
||||
return ret==1?0:-1;
|
||||
}
|
||||
|
||||
|
||||
@@ -457,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);
|
||||
|
||||
@@ -498,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)
|
||||
@@ -541,6 +554,15 @@ static void *get_initial_state()
|
||||
static void lvm2_log_fn(int level, const char *file, int line,
|
||||
const char *message)
|
||||
{
|
||||
|
||||
/* Send messages to the normal LVM2 logging system too,
|
||||
so we get debug output when it's asked for.
|
||||
We need to NULL the function ptr otherwise it will just call
|
||||
back into here! */
|
||||
init_log_fn(NULL);
|
||||
print_log(level, file, line, "%s", message);
|
||||
init_log_fn(lvm2_log_fn);
|
||||
|
||||
/*
|
||||
* Ignore non-error messages, but store the latest one for returning
|
||||
* to the user.
|
||||
@@ -584,6 +606,24 @@ void init_lvhash()
|
||||
pthread_mutex_init(&lvm_lock, NULL);
|
||||
}
|
||||
|
||||
/* Backups up the LVM metadata if it's changed */
|
||||
void lvm_do_backup(const char *vgname)
|
||||
{
|
||||
struct volume_group * vg;
|
||||
int consistent = 0;
|
||||
|
||||
DEBUGLOG("Triggering backup of VG metadata for %s. suspended=%d\n", vgname, suspended);
|
||||
|
||||
vg = vg_read(cmd, vgname, NULL /*vgid*/, &consistent);
|
||||
if (vg) {
|
||||
if (consistent)
|
||||
check_current_backup(vg);
|
||||
}
|
||||
else {
|
||||
log_error("Error backing up metadata, can't find VG for group %s", vgname);
|
||||
}
|
||||
}
|
||||
|
||||
/* Called to initialise the LVM context of the daemon */
|
||||
int init_lvm(int using_gulm)
|
||||
{
|
||||
@@ -594,7 +634,13 @@ int init_lvm(int using_gulm)
|
||||
|
||||
/* Use LOG_DAEMON for syslog messages instead of LOG_USER */
|
||||
init_syslog(LOG_DAEMON);
|
||||
init_debug(_LOG_ERR);
|
||||
openlog("clvmd", LOG_PID, LOG_DAEMON);
|
||||
init_debug(cmd->current_settings.debug);
|
||||
init_verbose(cmd->current_settings.verbose + VERBOSE_BASE_LEVEL);
|
||||
set_activation(cmd->current_settings.activation);
|
||||
archive_enable(cmd, cmd->current_settings.archive);
|
||||
backup_enable(cmd, cmd->current_settings.backup);
|
||||
cmd->cmd_line = (char *)"clvmd";
|
||||
|
||||
/* Check lvm.conf is setup for cluster-LVM */
|
||||
check_config();
|
||||
|
||||
@@ -28,7 +28,7 @@ extern int do_check_lvm1(const char *vgname);
|
||||
extern int do_refresh_cache(void);
|
||||
extern int init_lvm(int using_gulm);
|
||||
extern void init_lvhash(void);
|
||||
|
||||
extern void lvm_do_backup(const char *vgname);
|
||||
extern int hold_unlock(char *resource);
|
||||
extern int hold_lock(char *resource, int mode, int flags);
|
||||
extern void unlock_all(void);
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <libdevmapper.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "clvm.h"
|
||||
#include "refresh_clvmd.h"
|
||||
|
||||
@@ -722,10 +722,15 @@ int dm_event_get_registered_device(struct dm_event_handler *dmevh, int next)
|
||||
dm_event_handler_set_dso(dmevh, reply_dso);
|
||||
dm_event_handler_set_event_mask(dmevh, reply_mask);
|
||||
|
||||
if (reply_dso)
|
||||
if (reply_dso) {
|
||||
dm_free(reply_dso);
|
||||
if (reply_uuid)
|
||||
reply_dso = NULL;
|
||||
}
|
||||
|
||||
if (reply_uuid) {
|
||||
dm_free(reply_uuid);
|
||||
reply_uuid = NULL;
|
||||
}
|
||||
|
||||
dmevh->dev_name = dm_strdup(dm_task_get_name(dmt));
|
||||
if (!dmevh->dev_name) {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# 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 the LVM2.
|
||||
# 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
|
||||
@@ -16,7 +16,7 @@ srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
SUBDIRS += mirror
|
||||
SUBDIRS += mirror snapshot
|
||||
|
||||
include $(top_srcdir)/make.tmpl
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# 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 the LVM2.
|
||||
# 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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
3
daemons/dmeventd/plugins/snapshot/.exported_symbols
Normal file
3
daemons/dmeventd/plugins/snapshot/.exported_symbols
Normal file
@@ -0,0 +1,3 @@
|
||||
process_event
|
||||
register_device
|
||||
unregister_device
|
||||
@@ -1,6 +1,6 @@
|
||||
#
|
||||
# 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 the LVM2.
|
||||
#
|
||||
@@ -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)/$<
|
||||
|
||||
232
daemons/dmeventd/plugins/snapshot/dmeventd_snapshot.c
Normal file
232
daemons/dmeventd/plugins/snapshot/dmeventd_snapshot.c
Normal 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, ¶ms);
|
||||
if (!target_type)
|
||||
goto out;
|
||||
|
||||
_parse_snapshot_params(params, &stat);
|
||||
/*
|
||||
* If the snapshot has been invalidated or we failed to parse
|
||||
* the status string. Report the full status string to syslog.
|
||||
*/
|
||||
if (stat.invalid || !stat.max) {
|
||||
syslog(LOG_ERR, "Snapshot %s changed state to: %s\n", device, params);
|
||||
_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;
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
# 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 the LVM2.
|
||||
# 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
|
||||
@@ -16,7 +16,7 @@ srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
SUBDIRS += mirror
|
||||
SUBDIRS += mirror snapshot
|
||||
|
||||
include $(top_srcdir)/make.tmpl
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# 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 the LVM2.
|
||||
# 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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
3
dmeventd/snapshot/.exported_symbols
Normal file
3
dmeventd/snapshot/.exported_symbols
Normal file
@@ -0,0 +1,3 @@
|
||||
process_event
|
||||
register_device
|
||||
unregister_device
|
||||
36
dmeventd/snapshot/Makefile.in
Normal file
36
dmeventd/snapshot/Makefile.in
Normal 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)/$<
|
||||
|
||||
232
dmeventd/snapshot/dmeventd_snapshot.c
Normal file
232
dmeventd/snapshot/dmeventd_snapshot.c
Normal 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, ¶ms);
|
||||
if (!target_type)
|
||||
goto out;
|
||||
|
||||
_parse_snapshot_params(params, &stat);
|
||||
/*
|
||||
* If the snapshot has been invalidated or we failed to parse
|
||||
* the status string. Report the full status string to syslog.
|
||||
*/
|
||||
if (stat.invalid || !stat.max) {
|
||||
syslog(LOG_ERR, "Snapshot %s changed state to: %s\n", device, params);
|
||||
_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;
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# Copyright (C) 2004 Red Hat, Inc. All rights reserved.
|
||||
#
|
||||
# This file is part of the LVM2.
|
||||
# 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
|
||||
|
||||
@@ -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
|
||||
@@ -291,6 +293,12 @@ activation {
|
||||
# Size (in KB) of each copy operation when mirroring
|
||||
mirror_region_size = 512
|
||||
|
||||
# Setting to use when there is no readahead value stored in the metadata.
|
||||
#
|
||||
# "none" - Disable readahead.
|
||||
# "auto" - Use default value chosen by kernel.
|
||||
readahead = "auto"
|
||||
|
||||
# 'mirror_image_fault_policy' and 'mirror_log_fault_policy' define
|
||||
# how a device failure affecting a mirror is handled.
|
||||
# A mirror is composed of mirror images (copies) and a log.
|
||||
@@ -378,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"
|
||||
#}
|
||||
|
||||
|
||||
@@ -22,8 +22,8 @@ LVM2 that is running the LV's on my development box.
|
||||
}
|
||||
|
||||
|
||||
The important this to note is the devices section which makes sure that
|
||||
only the loopback devices are considered for LVM2 operations.
|
||||
The important thing to note is the devices section which makes sure
|
||||
that only the loopback devices are considered for LVM2 operations.
|
||||
|
||||
4) When you want to use this test setup just set the environment
|
||||
variable LVM_SYSTEM_DIR to point to your config directory
|
||||
@@ -39,8 +39,3 @@ LVM2 that is running the LV's on my development box.
|
||||
7) Test away. Make sure that you are explicit about which lvm
|
||||
executable you want to execute (eg, ./lvm if you are in
|
||||
LVM2/tools).
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
../lib/misc/crc.h
|
||||
../lib/misc/intl.h
|
||||
../lib/misc/util.h
|
||||
../lib/misc/last-path-component.h
|
||||
../lib/misc/lib.h
|
||||
../lib/misc/lvm-exec.h
|
||||
../lib/misc/lvm-file.h
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
# Copyright (C) 2004 Red Hat, Inc. All rights reserved.
|
||||
#
|
||||
# This file is part of the LVM2.
|
||||
# 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# 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 the LVM2.
|
||||
# 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
|
||||
|
||||
@@ -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.
|
||||
@@ -146,12 +146,12 @@ int target_present(const char *target_name, int use_modprobe)
|
||||
return 0;
|
||||
}
|
||||
int lv_info(struct cmd_context *cmd, const struct logical_volume *lv, struct lvinfo *info,
|
||||
int with_open_count)
|
||||
int with_open_count, int with_read_ahead)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s,
|
||||
struct lvinfo *info, int with_open_count)
|
||||
struct lvinfo *info, int with_open_count, int with_read_ahead)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -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
|
||||
@@ -425,7 +432,7 @@ int target_present(const char *target_name, int use_modprobe)
|
||||
* Returns 1 if info structure populated, else 0 on failure.
|
||||
*/
|
||||
static int _lv_info(struct cmd_context *cmd, const struct logical_volume *lv, int with_mknodes,
|
||||
struct lvinfo *info, int with_open_count, unsigned by_uuid_only)
|
||||
struct lvinfo *info, int with_open_count, int with_read_ahead, unsigned by_uuid_only)
|
||||
{
|
||||
struct dm_info dminfo;
|
||||
char *name = NULL;
|
||||
@@ -439,7 +446,8 @@ static int _lv_info(struct cmd_context *cmd, const struct logical_volume *lv, in
|
||||
|
||||
log_debug("Getting device info for %s", name);
|
||||
if (!dev_manager_info(lv->vg->cmd->mem, name, lv, with_mknodes,
|
||||
with_open_count, &dminfo)) {
|
||||
with_open_count, with_read_ahead, &dminfo,
|
||||
&info->read_ahead)) {
|
||||
if (name)
|
||||
dm_pool_free(cmd->mem, name);
|
||||
return_0;
|
||||
@@ -461,20 +469,20 @@ static int _lv_info(struct cmd_context *cmd, const struct logical_volume *lv, in
|
||||
}
|
||||
|
||||
int lv_info(struct cmd_context *cmd, const struct logical_volume *lv, struct lvinfo *info,
|
||||
int with_open_count)
|
||||
int with_open_count, int with_read_ahead)
|
||||
{
|
||||
return _lv_info(cmd, lv, 0, info, with_open_count, 0);
|
||||
return _lv_info(cmd, lv, 0, info, with_open_count, with_read_ahead, 0);
|
||||
}
|
||||
|
||||
int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s,
|
||||
struct lvinfo *info, int with_open_count)
|
||||
struct lvinfo *info, int with_open_count, int with_read_ahead)
|
||||
{
|
||||
struct logical_volume *lv;
|
||||
|
||||
if (!(lv = lv_from_lvid(cmd, lvid_s, 0)))
|
||||
return 0;
|
||||
|
||||
return _lv_info(cmd, lv, 0, info, with_open_count, 0);
|
||||
return _lv_info(cmd, lv, 0, info, with_open_count, with_read_ahead, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -507,10 +515,17 @@ 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;
|
||||
|
||||
if (!lv_info(cmd, lv, &info, 0))
|
||||
if (!lv_info(cmd, lv, &info, 0, 0))
|
||||
return_0;
|
||||
|
||||
if (!info.exists)
|
||||
@@ -532,7 +547,7 @@ static int _lv_active(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
{
|
||||
struct lvinfo info;
|
||||
|
||||
if (!_lv_info(cmd, lv, 0, &info, 0, by_uuid_only)) {
|
||||
if (!_lv_info(cmd, lv, 0, &info, 0, 0, by_uuid_only)) {
|
||||
stack;
|
||||
return -1;
|
||||
}
|
||||
@@ -544,7 +559,7 @@ static int _lv_open_count(struct cmd_context *cmd, struct logical_volume *lv)
|
||||
{
|
||||
struct lvinfo info;
|
||||
|
||||
if (!lv_info(cmd, lv, &info, 1)) {
|
||||
if (!lv_info(cmd, lv, &info, 1, 0)) {
|
||||
stack;
|
||||
return -1;
|
||||
}
|
||||
@@ -668,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)
|
||||
@@ -682,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;
|
||||
|
||||
@@ -772,7 +823,7 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!lv_info(cmd, lv, &info, 0))
|
||||
if (!lv_info(cmd, lv, &info, 0, 0))
|
||||
return_0;
|
||||
|
||||
if (!info.exists || info.suspended)
|
||||
@@ -832,7 +883,7 @@ static int _lv_resume(struct cmd_context *cmd, const char *lvid_s,
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!lv_info(cmd, lv, &info, 0))
|
||||
if (!lv_info(cmd, lv, &info, 0, 0))
|
||||
return_0;
|
||||
|
||||
if (!info.exists || !info.suspended)
|
||||
@@ -878,7 +929,7 @@ int lv_deactivate(struct cmd_context *cmd, const char *lvid_s)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!lv_info(cmd, lv, &info, 1))
|
||||
if (!lv_info(cmd, lv, &info, 1, 0))
|
||||
return_0;
|
||||
|
||||
if (!info.exists)
|
||||
@@ -949,7 +1000,7 @@ static int _lv_activate(struct cmd_context *cmd, const char *lvid_s,
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!lv_info(cmd, lv, &info, 0))
|
||||
if (!lv_info(cmd, lv, &info, 0, 0))
|
||||
return_0;
|
||||
|
||||
if (info.exists && !info.suspended && info.live_table)
|
||||
@@ -992,7 +1043,7 @@ int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (!_lv_info(cmd, lv, 1, &info, 0, 0))
|
||||
if (!_lv_info(cmd, lv, 1, &info, 0, 0, 0))
|
||||
return_0;
|
||||
|
||||
if (info.exists)
|
||||
|
||||
@@ -27,8 +27,12 @@ struct lvinfo {
|
||||
int read_only;
|
||||
int live_table;
|
||||
int inactive_table;
|
||||
uint32_t read_ahead;
|
||||
};
|
||||
|
||||
/* target attribute flags */
|
||||
#define MIRROR_LOG_CLUSTERED 0x00000001U
|
||||
|
||||
void set_activation(int activation);
|
||||
int activation(void);
|
||||
|
||||
@@ -36,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);
|
||||
@@ -62,9 +67,9 @@ int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv);
|
||||
* Returns 1 if info structure has been populated, else 0.
|
||||
*/
|
||||
int lv_info(struct cmd_context *cmd, const struct logical_volume *lv, struct lvinfo *info,
|
||||
int with_open_count);
|
||||
int with_open_count, int with_read_ahead);
|
||||
int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s,
|
||||
struct lvinfo *info, int with_open_count);
|
||||
struct lvinfo *info, int with_open_count, int with_read_ahead);
|
||||
|
||||
/*
|
||||
* Returns 1 if activate_lv has been set: 1 = activate; 0 = don't.
|
||||
|
||||
@@ -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);
|
||||
@@ -118,7 +116,8 @@ static struct dm_task *_setup_task(const char *name, const char *uuid,
|
||||
}
|
||||
|
||||
static int _info_run(const char *name, const char *dlid, struct dm_info *info,
|
||||
int mknodes, int with_open_count)
|
||||
uint32_t *read_ahead, int mknodes, int with_open_count,
|
||||
int with_read_ahead)
|
||||
{
|
||||
int r = 0;
|
||||
struct dm_task *dmt;
|
||||
@@ -126,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))
|
||||
@@ -141,6 +138,12 @@ static int _info_run(const char *name, const char *dlid, struct dm_info *info,
|
||||
if (!dm_task_get_info(dmt, info))
|
||||
goto_out;
|
||||
|
||||
if (with_read_ahead) {
|
||||
if (!dm_task_get_read_ahead(dmt, read_ahead))
|
||||
goto_out;
|
||||
} else if (read_ahead)
|
||||
*read_ahead = DM_READ_AHEAD_NONE;
|
||||
|
||||
r = 1;
|
||||
|
||||
out:
|
||||
@@ -153,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;
|
||||
|
||||
@@ -183,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, ¶ms);
|
||||
/* Skip if target type doesn't match */
|
||||
if (target_type && !strcmp(target_type, "mirror"))
|
||||
do {
|
||||
next = dm_get_next_target(dmt, next, &start, &length,
|
||||
&target_type, ¶ms);
|
||||
/* Skip if target type doesn't match */
|
||||
if (target_type && !strcmp(target_type, "mirror"))
|
||||
goto out;
|
||||
} while (next);
|
||||
} while (next);
|
||||
|
||||
/* FIXME Also check dependencies? */
|
||||
|
||||
@@ -201,27 +204,32 @@ int device_is_usable(dev_t dev)
|
||||
}
|
||||
|
||||
static int _info(const char *name, const char *dlid, int mknodes,
|
||||
int with_open_count, struct dm_info *info)
|
||||
int with_open_count, int with_read_ahead,
|
||||
struct dm_info *info, uint32_t *read_ahead)
|
||||
{
|
||||
if (!mknodes && dlid && *dlid) {
|
||||
if (_info_run(NULL, dlid, info, 0, with_open_count) &&
|
||||
if (_info_run(NULL, dlid, info, read_ahead, 0, with_open_count,
|
||||
with_read_ahead) &&
|
||||
info->exists)
|
||||
return 1;
|
||||
else if (_info_run(NULL, dlid + sizeof(UUID_PREFIX) - 1, info,
|
||||
0, with_open_count) &&
|
||||
read_ahead, 0, with_open_count,
|
||||
with_read_ahead) &&
|
||||
info->exists)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (name)
|
||||
return _info_run(name, NULL, info, mknodes, with_open_count);
|
||||
return _info_run(name, NULL, info, read_ahead, mknodes,
|
||||
with_open_count, with_read_ahead);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dev_manager_info(struct dm_pool *mem, const char *name,
|
||||
const struct logical_volume *lv, int with_mknodes,
|
||||
int with_open_count, struct dm_info *info)
|
||||
int with_open_count, int with_read_ahead,
|
||||
struct dm_info *info, uint32_t *read_ahead)
|
||||
{
|
||||
const char *dlid;
|
||||
|
||||
@@ -230,7 +238,8 @@ int dev_manager_info(struct dm_pool *mem, const char *name,
|
||||
return 0;
|
||||
}
|
||||
|
||||
return _info(name, dlid, with_mknodes, with_open_count, info);
|
||||
return _info(name, dlid, with_mknodes, with_open_count, with_read_ahead,
|
||||
info, read_ahead);
|
||||
}
|
||||
|
||||
/* FIXME Interface must cope with multiple targets */
|
||||
@@ -246,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");
|
||||
@@ -335,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");
|
||||
@@ -430,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;
|
||||
@@ -496,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 ? */
|
||||
|
||||
@@ -531,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;
|
||||
}
|
||||
@@ -630,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, &info)) {
|
||||
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",
|
||||
@@ -678,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;
|
||||
}
|
||||
@@ -830,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;
|
||||
@@ -843,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;
|
||||
}
|
||||
@@ -886,6 +879,9 @@ static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
|
||||
struct lv_layer *lvlayer;
|
||||
struct dm_tree_node *dnode;
|
||||
char *name, *dlid;
|
||||
uint32_t max_stripe_size = UINT32_C(0);
|
||||
uint32_t read_ahead = lv->read_ahead;
|
||||
uint32_t read_ahead_flags = UINT32_C(0);
|
||||
|
||||
if (!(name = build_dm_name(dm->mem, lv->vg->name, lv->name, layer)))
|
||||
return_0;
|
||||
@@ -932,8 +928,18 @@ static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
|
||||
break;
|
||||
if (lv_is_cow(lv) && !layer)
|
||||
break;
|
||||
if (max_stripe_size < seg->stripe_size)
|
||||
max_stripe_size = seg->stripe_size;
|
||||
}
|
||||
|
||||
if (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);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -961,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;
|
||||
@@ -984,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;
|
||||
}
|
||||
@@ -1013,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)
|
||||
|
||||
@@ -40,7 +40,8 @@ void dev_manager_exit(void);
|
||||
*/
|
||||
int dev_manager_info(struct dm_pool *mem, const char *name,
|
||||
const struct logical_volume *lv,
|
||||
int mknodes, int with_open_count, struct dm_info *info);
|
||||
int mknodes, int with_open_count, int with_read_ahead,
|
||||
struct dm_info *info, uint32_t *read_ahead);
|
||||
int dev_manager_snapshot_percent(struct dev_manager *dm,
|
||||
const struct logical_volume *lv,
|
||||
float *percent);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
382
lib/cache/lvmcache.c
vendored
382
lib/cache/lvmcache.c
vendored
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
*
|
||||
@@ -17,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 {
|
||||
***/
|
||||
@@ -633,7 +793,7 @@ static int _lvmcache_update_vgname(struct lvmcache_info *info,
|
||||
return 0;
|
||||
}
|
||||
/* Ensure orphans appear last on list_iterate */
|
||||
if (!*vgname)
|
||||
if (is_orphan_vg(vgname))
|
||||
list_add(&_vginfos, &vginfo->list);
|
||||
else
|
||||
list_add_h(&_vginfos, &vginfo->list);
|
||||
@@ -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),
|
||||
*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
19
lib/cache/lvmcache.h
vendored
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
*
|
||||
@@ -20,7 +20,8 @@
|
||||
#include "uuid.h"
|
||||
#include "label.h"
|
||||
|
||||
#define ORPHAN ""
|
||||
#define ORPHAN_PREFIX "#"
|
||||
#define ORPHAN_VG_NAME(fmt) ORPHAN_PREFIX "orphans_" fmt
|
||||
|
||||
#define CACHE_INVALID 0x00000001
|
||||
#define CACHE_LOCKED 0x00000002
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
@@ -153,6 +153,7 @@ static void _init_logging(struct cmd_context *cmd)
|
||||
static int _process_config(struct cmd_context *cmd)
|
||||
{
|
||||
mode_t old_umask;
|
||||
const char *read_ahead;
|
||||
|
||||
/* umask */
|
||||
cmd->default_settings.umask = find_config_tree_int(cmd,
|
||||
@@ -207,6 +208,16 @@ static int _process_config(struct cmd_context *cmd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
read_ahead = find_config_tree_str(cmd, "activation/readahead", DEFAULT_READ_AHEAD);
|
||||
if (!strcasecmp(read_ahead, "auto"))
|
||||
cmd->default_settings.read_ahead = DM_READ_AHEAD_AUTO;
|
||||
else if (!strcasecmp(read_ahead, "none"))
|
||||
cmd->default_settings.read_ahead = DM_READ_AHEAD_NONE;
|
||||
else {
|
||||
log_error("Invalid readahead specification");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -271,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;
|
||||
}
|
||||
|
||||
@@ -290,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;
|
||||
@@ -374,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;
|
||||
}
|
||||
@@ -389,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;
|
||||
@@ -413,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;
|
||||
@@ -531,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",
|
||||
@@ -683,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 "
|
||||
@@ -725,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;
|
||||
@@ -779,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 "
|
||||
@@ -987,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;
|
||||
@@ -1049,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);
|
||||
@@ -1091,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;
|
||||
|
||||
@@ -1112,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);
|
||||
|
||||
@@ -33,6 +33,8 @@ struct config_info {
|
||||
int suffix;
|
||||
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;
|
||||
@@ -93,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
|
||||
|
||||
@@ -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,
|
||||
@@ -156,7 +157,7 @@ static int _parse_config_file(struct parser *p, struct config_tree *cft)
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct config_tree *create_config_tree_from_string(struct cmd_context *cmd,
|
||||
struct config_tree *create_config_tree_from_string(struct cmd_context *cmd __attribute((unused)),
|
||||
const char *config_settings)
|
||||
{
|
||||
struct cs *c;
|
||||
@@ -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;
|
||||
|
||||
@@ -371,14 +366,14 @@ static int _line_append(struct output_line *outline, const char *fmt, ...)
|
||||
|
||||
va_start(ap, fmt);
|
||||
n = vsnprintf(&buf[0], sizeof buf - 1, fmt, ap);
|
||||
if (n < 0 || n > sizeof buf - 1) {
|
||||
if (n < 0 || n > (int) sizeof buf - 1) {
|
||||
log_error("vsnprintf failed for config line");
|
||||
return 0;
|
||||
}
|
||||
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;
|
||||
@@ -1248,13 +1245,13 @@ static char _token_type_to_char(int type)
|
||||
* Returns:
|
||||
* # of 'type' tokens in 'str'.
|
||||
*/
|
||||
static unsigned _count_tokens (const char *str, unsigned len, int type)
|
||||
static unsigned _count_tokens(const char *str, unsigned len, int type)
|
||||
{
|
||||
char c;
|
||||
|
||||
c = _token_type_to_char(type);
|
||||
|
||||
return(count_chars_len(str, len, c));
|
||||
return count_chars(str, len, c);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#define DEFAULT_FALLBACK_TO_LOCAL_LOCKING 1
|
||||
#define DEFAULT_FALLBACK_TO_CLUSTERED_LOCKING 1
|
||||
|
||||
#define DEFAULT_MIRRORLOG "disk"
|
||||
#define DEFAULT_MIRROR_LOG_FAULT_POLICY "allocate"
|
||||
#define DEFAULT_MIRROR_DEV_FAULT_POLICY "remove"
|
||||
#define DEFAULT_DMEVENTD_MIRROR_LIB "libdevmapper-event-lvm2mirror.so"
|
||||
@@ -62,6 +63,8 @@
|
||||
#define DEFAULT_PVMETADATASIZE 255
|
||||
#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
|
||||
@@ -101,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"
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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?
|
||||
*/
|
||||
|
||||
@@ -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, strdup(sl->str))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!str_list_add(mem, sllnew, dm_pool_strdup(mem, sl->str)))
|
||||
return_0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
@@ -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))) {
|
||||
|
||||
@@ -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,15 +350,18 @@ 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) &&
|
||||
((stat(name, &buf) < 0) || (buf.st_rdev != dev->dev))) {
|
||||
log_error("%s: stat failed: Has device name changed?", name);
|
||||
return 0;
|
||||
if (!(dev->flags & DEV_REGULAR)) {
|
||||
if (stat(name, &buf) < 0) {
|
||||
log_sys_error("%s: stat failed", name);
|
||||
return 0;
|
||||
}
|
||||
if (buf.st_rdev != dev->dev) {
|
||||
log_error("%s: device changed", name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef O_DIRECT_SUPPORT
|
||||
@@ -517,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);
|
||||
@@ -552,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;
|
||||
@@ -602,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;
|
||||
@@ -620,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;
|
||||
@@ -639,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,
|
||||
|
||||
@@ -17,25 +17,65 @@
|
||||
#include "metadata.h"
|
||||
#include "xlate.h"
|
||||
|
||||
#ifdef linux
|
||||
|
||||
/* Lifted from <linux/raid/md_p.h> because of difficulty including it */
|
||||
|
||||
#define MD_SB_MAGIC 0xa92b4efc
|
||||
#define MD_RESERVED_BYTES (64 * 1024)
|
||||
#define MD_RESERVED_BYTES (64 * 1024ULL)
|
||||
#define MD_RESERVED_SECTORS (MD_RESERVED_BYTES / 512)
|
||||
#define MD_NEW_SIZE_SECTORS(x) ((x & ~(MD_RESERVED_SECTORS - 1)) \
|
||||
- MD_RESERVED_SECTORS)
|
||||
|
||||
static int _dev_has_md_magic(struct device *dev, uint64_t sb_offset)
|
||||
{
|
||||
uint32_t md_magic;
|
||||
|
||||
/* Version 1 is little endian; version 0.90.0 is machine endian */
|
||||
if (dev_read(dev, sb_offset, sizeof(uint32_t), &md_magic) &&
|
||||
((md_magic == xlate32(MD_SB_MAGIC)) ||
|
||||
(md_magic == MD_SB_MAGIC)))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the position of the superblock.
|
||||
* It is always aligned to a 4K boundary and
|
||||
* depending on minor_version, it can be:
|
||||
* 0: At least 8K, but less than 12K, from end of device
|
||||
* 1: At start of device
|
||||
* 2: 4K from start of device.
|
||||
*/
|
||||
static uint64_t _v1_sb_offset(uint64_t size, unsigned minor_version)
|
||||
{
|
||||
uint64_t sb_offset;
|
||||
|
||||
switch(minor_version) {
|
||||
case 0:
|
||||
sb_offset = (size - 8 * 2) & ~(4 * 2 - 1ULL);
|
||||
break;
|
||||
case 1:
|
||||
sb_offset = 0;
|
||||
break;
|
||||
case 2:
|
||||
sb_offset = 4 * 2;
|
||||
break;
|
||||
}
|
||||
sb_offset <<= SECTOR_SHIFT;
|
||||
|
||||
return sb_offset;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns -1 on error
|
||||
*/
|
||||
int dev_is_md(struct device *dev, uint64_t *sb)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
#ifdef linux
|
||||
|
||||
int ret = 1;
|
||||
unsigned minor = 0;
|
||||
uint64_t size, sb_offset;
|
||||
uint32_t md_magic;
|
||||
|
||||
if (!dev_get_size(dev, &size)) {
|
||||
stack;
|
||||
@@ -50,22 +90,37 @@ int dev_is_md(struct device *dev, uint64_t *sb)
|
||||
return -1;
|
||||
}
|
||||
|
||||
sb_offset = MD_NEW_SIZE_SECTORS(size) << SECTOR_SHIFT;
|
||||
|
||||
/* Check if it is an md component device. */
|
||||
/* Version 1 is little endian; version 0.90.0 is machine endian */
|
||||
if (dev_read(dev, sb_offset, sizeof(uint32_t), &md_magic) &&
|
||||
((md_magic == xlate32(MD_SB_MAGIC)) ||
|
||||
(md_magic == MD_SB_MAGIC))) {
|
||||
if (sb)
|
||||
*sb = sb_offset;
|
||||
ret = 1;
|
||||
}
|
||||
/* Version 0.90.0 */
|
||||
sb_offset = MD_NEW_SIZE_SECTORS(size) << SECTOR_SHIFT;
|
||||
if (_dev_has_md_magic(dev, sb_offset))
|
||||
goto out;
|
||||
|
||||
/* Version 1, try v1.0 -> v1.2 */
|
||||
do {
|
||||
sb_offset = _v1_sb_offset(size, minor);
|
||||
if (_dev_has_md_magic(dev, sb_offset))
|
||||
goto out;
|
||||
} while (++minor <= 2);
|
||||
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
if (!dev_close(dev))
|
||||
stack;
|
||||
|
||||
#endif
|
||||
if (ret && sb)
|
||||
*sb = sb_offset;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int dev_is_md(struct device *dev __attribute((unused)),
|
||||
uint64_t *sb __attribute((unused)))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -27,16 +27,16 @@
|
||||
#define PART_OFFSET UINT64_C(0x1BE)
|
||||
|
||||
struct partition {
|
||||
uint8_t boot_ind;
|
||||
uint8_t head;
|
||||
uint8_t sector;
|
||||
uint8_t cyl;
|
||||
uint8_t sys_ind; /* partition type */
|
||||
uint8_t end_head;
|
||||
uint8_t end_sector;
|
||||
uint8_t end_cyl;
|
||||
uint32_t start_sect;
|
||||
uint32_t nr_sects;
|
||||
uint8_t boot_ind;
|
||||
uint8_t head;
|
||||
uint8_t sector;
|
||||
uint8_t cyl;
|
||||
uint8_t sys_ind; /* partition type */
|
||||
uint8_t end_head;
|
||||
uint8_t end_sector;
|
||||
uint8_t end_cyl;
|
||||
uint32_t start_sect;
|
||||
uint32_t nr_sects;
|
||||
} __attribute__((packed));
|
||||
|
||||
static int _is_partitionable(struct device *dev)
|
||||
@@ -62,10 +62,8 @@ static int _has_partition_table(struct device *dev)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!dev_read(dev, UINT64_C(0), sizeof(buf), &buf)) {
|
||||
stack;
|
||||
goto out;
|
||||
}
|
||||
if (!dev_read(dev, UINT64_C(0), sizeof(buf), &buf))
|
||||
goto_out;
|
||||
|
||||
/* FIXME Check for other types of partition table too */
|
||||
|
||||
|
||||
@@ -186,17 +186,17 @@ static const char *_display_size(const struct cmd_context *cmd,
|
||||
return size_buf;
|
||||
}
|
||||
|
||||
if (s < 10) {
|
||||
size *= UINT64_C(512);
|
||||
|
||||
if (s < 10)
|
||||
byte = cmd->current_settings.unit_factor;
|
||||
size *= UINT64_C(512);
|
||||
} else {
|
||||
size /= 2;
|
||||
else {
|
||||
suffix = 1;
|
||||
if (cmd->current_settings.unit_type == 'H')
|
||||
units = UINT64_C(1000);
|
||||
else
|
||||
units = UINT64_C(1024);
|
||||
byte = units * units * units * units * units;
|
||||
byte = units * units * units * units * units * units;
|
||||
s = 0;
|
||||
while (size_str[s] && size < byte)
|
||||
s++, byte /= units;
|
||||
@@ -246,7 +246,7 @@ void pvdisplay_colons(const struct physical_volume *pv)
|
||||
}
|
||||
|
||||
log_print("%s:%s:%" PRIu64 ":-1:%u:%u:-1:%" PRIu32 ":%u:%u:%u:%s",
|
||||
dev_name(pv->dev), pv->vg_name, pv->size,
|
||||
pv_dev_name(pv), pv->vg_name, pv->size,
|
||||
/* FIXME pv->pv_number, Derive or remove? */
|
||||
pv->status, /* FIXME Support old or new format here? */
|
||||
pv->status & ALLOCATABLE_PV, /* FIXME remove? */
|
||||
@@ -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,
|
||||
@@ -295,6 +295,7 @@ void pvdisplay_full(const struct cmd_context *cmd,
|
||||
const char *size;
|
||||
|
||||
uint32_t pe_free;
|
||||
uint64_t data_size, pvsize, unusable;
|
||||
|
||||
if (!pv)
|
||||
return;
|
||||
@@ -305,23 +306,25 @@ void pvdisplay_full(const struct cmd_context *cmd,
|
||||
}
|
||||
|
||||
log_print("--- %sPhysical volume ---", pv->pe_size ? "" : "NEW ");
|
||||
log_print("PV Name %s", dev_name(pv->dev));
|
||||
log_print("VG Name %s%s", pv->vg_name,
|
||||
log_print("PV Name %s", pv_dev_name(pv));
|
||||
log_print("VG Name %s%s",
|
||||
is_orphan(pv) ? "" : pv->vg_name,
|
||||
pv->status & EXPORTED_VG ? " (exported)" : "");
|
||||
|
||||
size = display_size(cmd, (uint64_t) pv->size);
|
||||
if (pv->pe_size && pv->pe_count) {
|
||||
data_size = (uint64_t) pv->pe_count * pv->pe_size;
|
||||
if (pv->size > data_size + pv->pe_start) {
|
||||
pvsize = pv->size;
|
||||
unusable = pvsize - data_size;
|
||||
} else {
|
||||
pvsize = data_size + pv->pe_start;
|
||||
unusable = pvsize - pv->size;
|
||||
}
|
||||
|
||||
/******** FIXME display LVM on-disk data size
|
||||
size2 = display_size(cmd, pv->size);
|
||||
********/
|
||||
|
||||
log_print("PV Size %s" " / not usable %s", /* [LVM: %s]", */
|
||||
size,
|
||||
display_size(cmd, (pv->size -
|
||||
(uint64_t) pv->pe_count * pv->pe_size)));
|
||||
|
||||
} else
|
||||
size = display_size(cmd, pvsize);
|
||||
if (data_size)
|
||||
log_print("PV Size %s / not usable %s", /* [LVM: %s]", */
|
||||
size, display_size(cmd, unusable));
|
||||
else
|
||||
log_print("PV Size %s", size);
|
||||
|
||||
/* PV number not part of LVM2 design
|
||||
@@ -358,12 +361,10 @@ 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 ", dev_name(pv->dev));
|
||||
log_print("PV Name %s ", pv_dev_name(pv));
|
||||
/* FIXME pv->pv_number); */
|
||||
log_print("PV UUID %s", *uuid ? uuid : "none");
|
||||
log_print("PV Status %sallocatable",
|
||||
@@ -379,7 +380,7 @@ void lvdisplay_colons(const struct logical_volume *lv)
|
||||
{
|
||||
int inkernel;
|
||||
struct lvinfo info;
|
||||
inkernel = lv_info(lv->vg->cmd, lv, &info, 1) && info.exists;
|
||||
inkernel = lv_info(lv->vg->cmd, lv, &info, 1, 0) && info.exists;
|
||||
|
||||
log_print("%s%s/%s:%s:%d:%d:-1:%d:%" PRIu64 ":%d:-1:%d:%d:%d:%d",
|
||||
lv->vg->cmd->dev_dir,
|
||||
@@ -405,12 +406,10 @@ 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) && info.exists;
|
||||
inkernel = lv_info(cmd, lv, &info, 1, 1) && info.exists;
|
||||
|
||||
log_print("--- Logical volume ---");
|
||||
|
||||
@@ -491,7 +490,15 @@ int lvdisplay_full(struct cmd_context *cmd,
|
||||
***********/
|
||||
|
||||
log_print("Allocation %s", get_alloc_string(lv->alloc));
|
||||
log_print("Read ahead sectors %u", lv->read_ahead);
|
||||
if (lv->read_ahead == DM_READ_AHEAD_AUTO)
|
||||
log_print("Read ahead sectors auto");
|
||||
else if (lv->read_ahead == DM_READ_AHEAD_NONE)
|
||||
log_print("Read ahead sectors 0");
|
||||
else
|
||||
log_print("Read ahead sectors %u", lv->read_ahead);
|
||||
|
||||
if (inkernel && lv->read_ahead != info.read_ahead)
|
||||
log_print("- currently set to %u", info.read_ahead);
|
||||
|
||||
if (lv->status & FIXED_MINOR) {
|
||||
if (lv->major >= 0)
|
||||
@@ -515,7 +522,7 @@ void display_stripe(const struct lv_segment *seg, uint32_t s, const char *pre)
|
||||
/* FIXME Re-check the conditions for 'Missing' */
|
||||
log_print("%sPhysical volume\t%s", pre,
|
||||
seg_pv(seg, s) ?
|
||||
dev_name(seg_dev(seg, s)) :
|
||||
pv_dev_name(seg_pv(seg, s)) :
|
||||
"Missing");
|
||||
|
||||
if (seg_pv(seg, s))
|
||||
@@ -567,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)
|
||||
@@ -595,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",
|
||||
@@ -645,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)));
|
||||
|
||||
@@ -653,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";
|
||||
@@ -688,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;
|
||||
|
||||
@@ -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;
|
||||
@@ -67,7 +68,7 @@ static int _errseg_target_present(const struct lv_segment *seg __attribute((unus
|
||||
#endif
|
||||
|
||||
static int _errseg_modules_needed(struct dm_pool *mem,
|
||||
const struct lv_segment *seg,
|
||||
const struct lv_segment *seg __attribute((unused)),
|
||||
struct list *modules)
|
||||
{
|
||||
if (!str_list_add(mem, modules, "error")) {
|
||||
@@ -77,7 +78,7 @@ static int _errseg_modules_needed(struct dm_pool *mem,
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void _errseg_destroy(const struct segment_type *segtype)
|
||||
{
|
||||
dm_free((void *)segtype);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
@@ -50,10 +50,8 @@ struct dev_filter *composite_filter_create(int n, struct dev_filter **filters)
|
||||
{
|
||||
struct dev_filter **filters_copy, *cft;
|
||||
|
||||
if (!filters) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
if (!filters)
|
||||
return_NULL;
|
||||
|
||||
if (!(filters_copy = dm_malloc(sizeof(*filters) * (n + 1)))) {
|
||||
log_error("composite filters allocation failed");
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
|
||||
#ifdef linux
|
||||
|
||||
static int _ignore_md(struct dev_filter *f, struct device *dev)
|
||||
static int _ignore_md(struct dev_filter *f __attribute((unused)),
|
||||
struct device *dev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "dev-cache.h"
|
||||
#include "filter-persistent.h"
|
||||
#include "lvm-file.h"
|
||||
#include "lvm-string.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
@@ -42,10 +43,8 @@ static int _init_hash(struct pfilter *pf)
|
||||
if (pf->devices)
|
||||
dm_hash_destroy(pf->devices);
|
||||
|
||||
if (!(pf->devices = dm_hash_create(128))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(pf->devices = dm_hash_create(128)))
|
||||
return_0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -99,13 +98,13 @@ int persistent_filter_load(struct dev_filter *f, struct config_tree **cft_out)
|
||||
{
|
||||
struct pfilter *pf = (struct pfilter *) f->private;
|
||||
struct config_tree *cft;
|
||||
struct stat info;
|
||||
struct stat info;
|
||||
int r = 0;
|
||||
|
||||
if (!stat(pf->file, &info))
|
||||
if (!stat(pf->file, &info))
|
||||
pf->ctime = info.st_ctime;
|
||||
else {
|
||||
log_very_verbose("%s: stat failed: %s", pf->file,
|
||||
log_very_verbose("%s: stat failed: %s", pf->file,
|
||||
strerror(errno));
|
||||
return_0;
|
||||
}
|
||||
@@ -144,6 +143,7 @@ static void _write_array(struct pfilter *pf, FILE *fp, const char *path,
|
||||
{
|
||||
void *d;
|
||||
int first = 1;
|
||||
char *buf, *str;
|
||||
struct dm_hash_node *n;
|
||||
|
||||
for (n = dm_hash_get_first(pf->devices); n;
|
||||
@@ -160,7 +160,13 @@ static void _write_array(struct pfilter *pf, FILE *fp, const char *path,
|
||||
first = 0;
|
||||
}
|
||||
|
||||
fprintf(fp, "\t\t\"%s\"", dm_hash_get_key(pf->devices, n));
|
||||
str = dm_hash_get_key(pf->devices, n);
|
||||
if (!(buf = alloca(escaped_len(str)))) {
|
||||
log_error("persistent filter device path stack "
|
||||
"allocation failed");
|
||||
return;
|
||||
}
|
||||
fprintf(fp, "\t\t\"%s\"", escape_double_quotes(buf, str));
|
||||
}
|
||||
|
||||
if (!first)
|
||||
@@ -293,10 +299,8 @@ struct dev_filter *persistent_filter_create(struct dev_filter *real,
|
||||
struct pfilter *pf;
|
||||
struct dev_filter *f = NULL;
|
||||
|
||||
if (!(pf = dm_malloc(sizeof(*pf)))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
if (!(pf = dm_malloc(sizeof(*pf))))
|
||||
return_NULL;
|
||||
memset(pf, 0, sizeof(*pf));
|
||||
|
||||
if (!(pf->file = dm_malloc(strlen(file) + 1)))
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
@@ -70,10 +70,8 @@ static int _extract_pattern(struct dm_pool *mem, const char *pat,
|
||||
/*
|
||||
* copy the regex
|
||||
*/
|
||||
if (!(r = dm_pool_strdup(mem, pat))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(r = dm_pool_strdup(mem, pat)))
|
||||
return_0;
|
||||
|
||||
/*
|
||||
* trim the trailing character, having checked it's sep.
|
||||
@@ -192,10 +190,8 @@ struct dev_filter *regex_filter_create(struct config_value *patterns)
|
||||
struct rfilter *rf;
|
||||
struct dev_filter *f;
|
||||
|
||||
if (!mem) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
if (!mem)
|
||||
return_NULL;
|
||||
|
||||
if (!(rf = dm_pool_alloc(mem, sizeof(*rf))))
|
||||
goto_bad;
|
||||
|
||||
@@ -20,12 +20,14 @@
|
||||
|
||||
#include <dirent.h>
|
||||
|
||||
static int _locate_sysfs_blocks(const char *proc, char *path, size_t len)
|
||||
static int _locate_sysfs_blocks(const char *proc, char *path, size_t len,
|
||||
unsigned *sysfs_depth)
|
||||
{
|
||||
char proc_mounts[PATH_MAX];
|
||||
int r = 0;
|
||||
FILE *fp;
|
||||
char *split[4], buffer[PATH_MAX + 16];
|
||||
const char *sys_mnt = NULL;
|
||||
struct stat info;
|
||||
|
||||
if (!*proc) {
|
||||
log_verbose("No proc filesystem found: skipping sysfs filter");
|
||||
@@ -46,10 +48,7 @@ static int _locate_sysfs_blocks(const char *proc, char *path, size_t len)
|
||||
while (fgets(buffer, sizeof(buffer), fp)) {
|
||||
if (dm_split_words(buffer, 4, 0, split) == 4 &&
|
||||
!strcmp(split[2], "sysfs")) {
|
||||
if (dm_snprintf(path, len, "%s/%s", split[1],
|
||||
"block") >= 0) {
|
||||
r = 1;
|
||||
}
|
||||
sys_mnt = split[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -57,7 +56,70 @@ static int _locate_sysfs_blocks(const char *proc, char *path, size_t len)
|
||||
if (fclose(fp))
|
||||
log_sys_error("fclose", proc_mounts);
|
||||
|
||||
return r;
|
||||
if (!sys_mnt) {
|
||||
log_error("Failed to find sysfs mount point");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* unified classification directory for all kernel subsystems
|
||||
*
|
||||
* /sys/subsystem/block/devices
|
||||
* |-- sda -> ../../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda
|
||||
* |-- sda1 -> ../../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1
|
||||
* `-- sr0 -> ../../../devices/pci0000:00/0000:00:1f.2/host1/target1:0:0/1:0:0:0/block/sr0
|
||||
*
|
||||
*/
|
||||
if (dm_snprintf(path, len, "%s/%s", sys_mnt,
|
||||
"subsystem/block/devices") >= 0) {
|
||||
if (!stat(path, &info)) {
|
||||
*sysfs_depth = 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* block subsystem as a class
|
||||
*
|
||||
* /sys/class/block
|
||||
* |-- sda -> ../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda
|
||||
* |-- sda1 -> ../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1
|
||||
* `-- sr0 -> ../../devices/pci0000:00/0000:00:1f.2/host1/target1:0:0/1:0:0:0/block/sr0
|
||||
*
|
||||
*/
|
||||
if (dm_snprintf(path, len, "%s/%s", sys_mnt, "class/block") >= 0) {
|
||||
if (!stat(path, &info)) {
|
||||
*sysfs_depth = 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* old block subsystem layout with nested directories
|
||||
*
|
||||
* /sys/block/
|
||||
* |-- sda
|
||||
* | |-- capability
|
||||
* | |-- dev
|
||||
* ...
|
||||
* | |-- sda1
|
||||
* | | |-- dev
|
||||
* ...
|
||||
* |
|
||||
* `-- sr0
|
||||
* |-- capability
|
||||
* |-- dev
|
||||
* ...
|
||||
*
|
||||
*/
|
||||
if (dm_snprintf(path, len, "%s/%s", sys_mnt, "block") >= 0) {
|
||||
if (!stat(path, &info)) {
|
||||
*sysfs_depth = 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
@@ -72,11 +134,14 @@ struct entry {
|
||||
struct dev_set {
|
||||
struct dm_pool *mem;
|
||||
const char *sys_block;
|
||||
unsigned sysfs_depth;
|
||||
int initialised;
|
||||
struct entry *slots[SET_BUCKETS];
|
||||
};
|
||||
|
||||
static struct dev_set *_dev_set_create(struct dm_pool *mem, const char *sys_block)
|
||||
static struct dev_set *_dev_set_create(struct dm_pool *mem,
|
||||
const char *sys_block,
|
||||
unsigned sysfs_depth)
|
||||
{
|
||||
struct dev_set *ds;
|
||||
|
||||
@@ -85,6 +150,7 @@ static struct dev_set *_dev_set_create(struct dm_pool *mem, const char *sys_bloc
|
||||
|
||||
ds->mem = mem;
|
||||
ds->sys_block = dm_pool_strdup(mem, sys_block);
|
||||
ds->sysfs_depth = sysfs_depth;
|
||||
ds->initialised = 0;
|
||||
|
||||
return ds;
|
||||
@@ -168,23 +234,23 @@ static int _read_dev(const char *file, dev_t *result)
|
||||
/*
|
||||
* Recurse through sysfs directories, inserting any devs found.
|
||||
*/
|
||||
static int _read_devs(struct dev_set *ds, const char *dir)
|
||||
static int _read_devs(struct dev_set *ds, const char *dir, unsigned sysfs_depth)
|
||||
{
|
||||
struct dirent *d;
|
||||
DIR *dr;
|
||||
unsigned char dtype;
|
||||
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,
|
||||
@@ -194,42 +260,33 @@ static int _read_devs(struct dev_set *ds, const char *dir)
|
||||
continue;
|
||||
}
|
||||
|
||||
dtype = d->d_type;
|
||||
|
||||
if (dtype == DT_UNKNOWN) {
|
||||
if (lstat(path, &info) >= 0) {
|
||||
if (S_ISLNK(info.st_mode))
|
||||
dtype = DT_LNK;
|
||||
else if (S_ISDIR(info.st_mode))
|
||||
dtype = DT_DIR;
|
||||
else if (S_ISREG(info.st_mode))
|
||||
dtype = DT_REG;
|
||||
}
|
||||
/* devices have a "dev" file */
|
||||
if (dm_snprintf(file, sizeof(file), "%s/dev", path) < 0) {
|
||||
log_error("sysfs path name too long: %s in %s",
|
||||
d->d_name, dir);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dtype == DT_DIR) {
|
||||
if (!_read_devs(ds, path)) {
|
||||
r = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!stat(file, &info)) {
|
||||
/* recurse if we found a device and expect subdirs */
|
||||
if (sysfs_depth)
|
||||
_read_devs(ds, path, sysfs_depth - 1);
|
||||
|
||||
if ((dtype == DT_REG && !strcmp(d->d_name, "dev")))
|
||||
if (!_read_dev(path, &dev) || !_set_insert(ds, dev)) {
|
||||
r = 0;
|
||||
break;
|
||||
}
|
||||
/* add the device we have found */
|
||||
if (_read_dev(file, &dev))
|
||||
_set_insert(ds, dev);
|
||||
}
|
||||
}
|
||||
|
||||
if (closedir(dr))
|
||||
log_sys_error("closedir", dir);
|
||||
if (closedir(dr))
|
||||
log_sys_error("closedir", dir);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int _init_devs(struct dev_set *ds)
|
||||
{
|
||||
if (!_read_devs(ds, ds->sys_block)) {
|
||||
if (!_read_devs(ds, ds->sys_block, ds->sysfs_depth)) {
|
||||
ds->initialised = -1;
|
||||
return 0;
|
||||
}
|
||||
@@ -267,11 +324,12 @@ static void _destroy(struct dev_filter *f)
|
||||
struct dev_filter *sysfs_filter_create(const char *proc)
|
||||
{
|
||||
char sys_block[PATH_MAX];
|
||||
unsigned sysfs_depth;
|
||||
struct dm_pool *mem;
|
||||
struct dev_set *ds;
|
||||
struct dev_filter *f;
|
||||
|
||||
if (!_locate_sysfs_blocks(proc, sys_block, sizeof(sys_block)))
|
||||
if (!_locate_sysfs_blocks(proc, sys_block, sizeof(sys_block), &sysfs_depth))
|
||||
return NULL;
|
||||
|
||||
if (!(mem = dm_pool_create("sysfs", 256))) {
|
||||
@@ -279,7 +337,7 @@ struct dev_filter *sysfs_filter_create(const char *proc)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(ds = _dev_set_create(mem, sys_block))) {
|
||||
if (!(ds = _dev_set_create(mem, sys_block, sysfs_depth))) {
|
||||
log_error("sysfs dev_set creation failed");
|
||||
goto bad;
|
||||
}
|
||||
@@ -299,7 +357,7 @@ struct dev_filter *sysfs_filter_create(const char *proc)
|
||||
|
||||
#else
|
||||
|
||||
struct dev_filter *sysfs_filter_create(const char *proc)
|
||||
struct dev_filter *sysfs_filter_create(const char *proc __attribute((unused)))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -77,10 +77,11 @@ 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}
|
||||
};
|
||||
|
||||
static int _passes_lvm_type_device_filter(struct dev_filter *f,
|
||||
static int _passes_lvm_type_device_filter(struct dev_filter *f __attribute((unused)),
|
||||
struct device *dev)
|
||||
{
|
||||
const char *name = dev_name(dev);
|
||||
@@ -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;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
|
||||
# Copyright (C) 2004 Red Hat, Inc. All rights reserved.
|
||||
#
|
||||
# This file is part of the LVM2.
|
||||
# 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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -415,19 +413,17 @@ static struct disk_list *__read_disk(const struct format_type *fmt,
|
||||
struct disk_list *read_disk(const struct format_type *fmt, struct device *dev,
|
||||
struct dm_pool *mem, const char *vg_name)
|
||||
{
|
||||
struct disk_list *r;
|
||||
struct disk_list *dl;
|
||||
|
||||
if (!dev_open(dev)) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
if (!dev_open(dev))
|
||||
return_NULL;
|
||||
|
||||
r = __read_disk(fmt, dev, mem, vg_name);
|
||||
dl = __read_disk(fmt, dev, mem, vg_name);
|
||||
|
||||
if (!dev_close(dev))
|
||||
stack;
|
||||
|
||||
return r;
|
||||
return dl;
|
||||
}
|
||||
|
||||
static void _add_pv_to_list(struct list *head, struct disk_list *data)
|
||||
@@ -480,7 +476,7 @@ int read_pvs_in_vg(const struct format_type *fmt, const char *vg_name,
|
||||
}
|
||||
|
||||
/* Did we find the whole VG? */
|
||||
if (!vg_name || !*vg_name ||
|
||||
if (!vg_name || is_orphan_vg(vg_name) ||
|
||||
(data && *data->pvd.vg_name &&
|
||||
list_size(head) == data->vgd.pv_cur))
|
||||
return 1;
|
||||
@@ -519,7 +515,7 @@ static int _write_vgd(struct disk_list *data)
|
||||
|
||||
_xlate_vgd(vgd);
|
||||
if (!dev_write(data->dev, pos, sizeof(*vgd), vgd))
|
||||
fail;
|
||||
return_0;
|
||||
|
||||
_xlate_vgd(vgd);
|
||||
|
||||
@@ -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);
|
||||
@@ -653,7 +649,7 @@ static int _write_pvd(struct disk_list *data)
|
||||
/*
|
||||
* assumes the device has been opened.
|
||||
*/
|
||||
static int __write_all_pvd(const struct format_type *fmt,
|
||||
static int __write_all_pvd(const struct format_type *fmt __attribute((unused)),
|
||||
struct disk_list *data)
|
||||
{
|
||||
const char *pv_name = dev_name(data->dev);
|
||||
@@ -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));
|
||||
|
||||
@@ -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,24 +165,21 @@ static struct volume_group *_build_vg(struct format_instance *fid,
|
||||
return vg;
|
||||
|
||||
bad:
|
||||
stack;
|
||||
dm_pool_free(mem, vg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct volume_group *_format1_vg_read(struct format_instance *fid,
|
||||
const char *vg_name,
|
||||
struct metadata_area *mda)
|
||||
struct metadata_area *mda __attribute((unused)))
|
||||
{
|
||||
struct dm_pool *mem = dm_pool_create("lvm1 vg_read", 1024 * 10);
|
||||
struct list pvs;
|
||||
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,25 +241,21 @@ 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;
|
||||
}
|
||||
|
||||
static int _format1_vg_write(struct format_instance *fid, struct volume_group *vg,
|
||||
struct metadata_area *mda)
|
||||
struct metadata_area *mda __attribute((unused)))
|
||||
{
|
||||
struct dm_pool *mem = dm_pool_create("lvm1 vg_write", 1024 * 10);
|
||||
struct list pvds;
|
||||
int r = 0;
|
||||
|
||||
if (!mem) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!mem)
|
||||
return_0;
|
||||
|
||||
list_init(&pvds);
|
||||
|
||||
@@ -278,13 +263,13 @@ 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;
|
||||
}
|
||||
|
||||
static int _format1_pv_read(const struct format_type *fmt, const char *pv_name,
|
||||
struct physical_volume *pv, struct list *mdas)
|
||||
struct physical_volume *pv, struct list *mdas __attribute((unused)))
|
||||
{
|
||||
struct dm_pool *mem = dm_pool_create("lvm1 pv_read", 1024);
|
||||
struct disk_list *dl;
|
||||
@@ -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;
|
||||
|
||||
@@ -325,9 +302,9 @@ static int _format1_pv_read(const struct format_type *fmt, const char *pv_name,
|
||||
static int _format1_pv_setup(const struct format_type *fmt,
|
||||
uint64_t pe_start, uint32_t extent_count,
|
||||
uint32_t extent_size,
|
||||
int pvmetadatacopies,
|
||||
uint64_t pvmetadatasize, struct list *mdas,
|
||||
struct physical_volume *pv, struct volume_group *vg)
|
||||
int pvmetadatacopies __attribute((unused)),
|
||||
uint64_t pvmetadatasize __attribute((unused)), struct list *mdas __attribute((unused)),
|
||||
struct physical_volume *pv, struct volume_group *vg __attribute((unused)))
|
||||
{
|
||||
if (pv->size > MAX_PV_SIZE)
|
||||
pv->size--;
|
||||
@@ -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)) ||
|
||||
@@ -381,7 +356,7 @@ static int _format1_lv_setup(struct format_instance *fid, struct logical_volume
|
||||
}
|
||||
|
||||
static int _format1_pv_write(const struct format_type *fmt, struct physical_volume *pv,
|
||||
struct list *mdas, int64_t sector)
|
||||
struct list *mdas __attribute((unused)), int64_t sector __attribute((unused)))
|
||||
{
|
||||
struct dm_pool *mem;
|
||||
struct disk_list *dl;
|
||||
@@ -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,
|
||||
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;
|
||||
}
|
||||
@@ -487,26 +456,23 @@ static struct metadata_area_ops _metadata_format1_ops = {
|
||||
};
|
||||
|
||||
static struct format_instance *_format1_create_instance(const struct format_type *fmt,
|
||||
const char *vgname,
|
||||
const char *vgid,
|
||||
void *private)
|
||||
const char *vgname __attribute((unused)),
|
||||
const char *vgid __attribute((unused)),
|
||||
void *private __attribute((unused)))
|
||||
{
|
||||
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;
|
||||
@@ -516,7 +482,7 @@ static struct format_instance *_format1_create_instance(const struct format_type
|
||||
return fid;
|
||||
}
|
||||
|
||||
static void _format1_destroy_instance(struct format_instance *fid)
|
||||
static void _format1_destroy_instance(struct format_instance *fid __attribute((unused)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -547,16 +513,16 @@ 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->features = FMT_RESTRICTED_LVIDS | FMT_ORPHAN_ALLOCATABLE;
|
||||
fmt->orphan_vg_name = FMT_LVM1_ORPHAN_VG_NAME;
|
||||
fmt->features = FMT_RESTRICTED_LVIDS | FMT_ORPHAN_ALLOCATABLE |
|
||||
FMT_RESTRICTED_READAHEAD;
|
||||
fmt->private = NULL;
|
||||
|
||||
if (!(fmt->labeller = lvm1_labeller_create(fmt))) {
|
||||
|
||||
@@ -17,6 +17,10 @@
|
||||
#define _LVM_FORMAT1_H
|
||||
|
||||
#include "metadata.h"
|
||||
#include "lvmcache.h"
|
||||
|
||||
#define FMT_LVM1_NAME "lvm1"
|
||||
#define FMT_LVM1_ORPHAN_VG_NAME ORPHAN_VG_NAME(FMT_LVM1_NAME)
|
||||
|
||||
#ifdef LVM1_INTERNAL
|
||||
struct format_type *init_lvm1_format(struct cmd_context *cmd);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
@@ -25,6 +25,8 @@
|
||||
#include "segtype.h"
|
||||
#include "pv_alloc.h"
|
||||
#include "display.h"
|
||||
#include "lvmcache.h"
|
||||
#include "metadata.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
@@ -59,8 +61,10 @@ int import_pv(const struct format_type *fmt, struct dm_pool *mem,
|
||||
memcpy(&pv->id, pvd->pv_uuid, ID_LEN);
|
||||
|
||||
pv->dev = dev;
|
||||
if (!(pv->vg_name = dm_pool_strdup(mem, (char *)pvd->vg_name))) {
|
||||
stack;
|
||||
if (!*pvd->vg_name)
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -74,7 +78,7 @@ int import_pv(const struct format_type *fmt, struct dm_pool *mem,
|
||||
strncmp(vg->system_id, (char *)pvd->system_id, sizeof(pvd->system_id)))
|
||||
log_very_verbose("System ID %s on %s differs from %s for "
|
||||
"volume group", pvd->system_id,
|
||||
dev_name(pv->dev), vg->system_id);
|
||||
pv_dev_name(pv), vg->system_id);
|
||||
|
||||
/*
|
||||
* If exported, we still need to flag in pv->status too because
|
||||
@@ -92,32 +96,30 @@ int import_pv(const struct format_type *fmt, struct dm_pool *mem,
|
||||
pv->pe_count = pvd->pe_total;
|
||||
pv->pe_alloc_count = 0;
|
||||
|
||||
/* Fix up pv size if missing */
|
||||
if (!pv->size) {
|
||||
/* Fix up pv size if missing or impossibly large */
|
||||
if (!pv->size || pv->size > (1ULL << 62)) {
|
||||
if (!dev_get_size(dev, &pv->size)) {
|
||||
log_error("%s: Couldn't get size.", dev_name(pv->dev));
|
||||
log_error("%s: Couldn't get size.", pv_dev_name(pv));
|
||||
return 0;
|
||||
}
|
||||
log_verbose("Fixing up missing format1 size (%s) "
|
||||
"for PV %s", display_size(fmt->cmd, pv->size),
|
||||
dev_name(pv->dev));
|
||||
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",
|
||||
dev_name(pv->dev));
|
||||
pv_dev_name(pv));
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -134,7 +136,7 @@ static int _system_id(struct cmd_context *cmd, char *s, const char *prefix)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int export_pv(struct cmd_context *cmd, struct dm_pool *mem,
|
||||
int export_pv(struct cmd_context *cmd, struct dm_pool *mem __attribute((unused)),
|
||||
struct volume_group *vg,
|
||||
struct pv_disk *pvd, struct physical_volume *pv)
|
||||
{
|
||||
@@ -146,11 +148,9 @@ int export_pv(struct cmd_context *cmd, struct dm_pool *mem,
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -164,10 +164,8 @@ int export_pv(struct cmd_context *cmd, struct dm_pool *mem,
|
||||
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)) {
|
||||
@@ -181,18 +179,14 @@ int export_pv(struct cmd_context *cmd, struct dm_pool *mem,
|
||||
/* 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 &&
|
||||
@@ -224,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';
|
||||
|
||||
@@ -283,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)
|
||||
@@ -312,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;
|
||||
|
||||
@@ -346,7 +332,11 @@ int import_lv(struct dm_pool *mem, struct logical_volume *lv, struct lv_disk *lv
|
||||
else
|
||||
lv->alloc = ALLOC_NORMAL;
|
||||
|
||||
lv->read_ahead = lvd->lv_read_ahead;
|
||||
if (!lvd->lv_read_ahead)
|
||||
lv->read_ahead = lv->vg->cmd->default_settings.read_ahead;
|
||||
else
|
||||
lv->read_ahead = lvd->lv_read_ahead;
|
||||
|
||||
lv->size = lvd->lv_size;
|
||||
lv->le_count = lvd->lv_allocated_le;
|
||||
|
||||
@@ -354,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;
|
||||
}
|
||||
@@ -383,7 +374,12 @@ static void _export_lv(struct lv_disk *lvd, struct volume_group *vg,
|
||||
lvd->lv_dev = MKDEV(LVM_BLK_MAJOR, lvnum_from_lvid(&lv->lvid));
|
||||
}
|
||||
|
||||
lvd->lv_read_ahead = lv->read_ahead;
|
||||
if (lv->read_ahead == DM_READ_AHEAD_AUTO ||
|
||||
lv->read_ahead == DM_READ_AHEAD_NONE)
|
||||
lvd->lv_read_ahead = 0;
|
||||
else
|
||||
lvd->lv_read_ahead = lv->read_ahead;
|
||||
|
||||
lvd->lv_stripes =
|
||||
list_item(lv->segments.n, struct lv_segment)->area_count;
|
||||
lvd->lv_stripesize =
|
||||
@@ -444,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);
|
||||
@@ -470,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++;
|
||||
@@ -499,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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -520,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;
|
||||
@@ -588,7 +562,7 @@ int export_lvs(struct disk_list *dl, struct volume_group *vg,
|
||||
/*
|
||||
* FIXME: More inefficient code.
|
||||
*/
|
||||
int import_snapshots(struct dm_pool *mem, struct volume_group *vg,
|
||||
int import_snapshots(struct dm_pool *mem __attribute((unused)), struct volume_group *vg,
|
||||
struct list *pvds)
|
||||
{
|
||||
struct logical_volume *lvs[MAX_LV];
|
||||
@@ -644,8 +618,8 @@ int import_snapshots(struct dm_pool *mem, struct volume_group *vg,
|
||||
continue;
|
||||
|
||||
/* insert the snapshot */
|
||||
if (!vg_add_snapshot(vg->fid, NULL, org, cow, NULL,
|
||||
org->le_count,
|
||||
if (!vg_add_snapshot(NULL, org, cow, NULL,
|
||||
org->le_count,
|
||||
lvd->lv_chunk_size)) {
|
||||
log_err("Couldn't add snapshot.");
|
||||
return 0;
|
||||
@@ -662,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);
|
||||
@@ -679,7 +651,7 @@ int export_uuids(struct disk_list *dl, struct volume_group *vg)
|
||||
* This calculates the nasty pv_number field
|
||||
* used by LVM1.
|
||||
*/
|
||||
void export_numbers(struct list *pvds, struct volume_group *vg)
|
||||
void export_numbers(struct list *pvds, struct volume_group *vg __attribute((unused)))
|
||||
{
|
||||
struct disk_list *dl;
|
||||
int pv_num = 1;
|
||||
@@ -710,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;
|
||||
|
||||
@@ -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.");
|
||||
|
||||
@@ -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
|
||||
@@ -139,7 +137,7 @@ int calculate_extent_count(struct physical_volume *pv, uint32_t extent_size,
|
||||
|
||||
if (pvd->pe_total < PE_SIZE_PV_SIZE_REL) {
|
||||
log_error("Too few extents on %s. Try smaller extent size.",
|
||||
dev_name(pv->dev));
|
||||
pv_dev_name(pv));
|
||||
dm_free(pvd);
|
||||
return 0;
|
||||
}
|
||||
@@ -160,7 +158,7 @@ int calculate_extent_count(struct physical_volume *pv, uint32_t extent_size,
|
||||
|
||||
if (pvd->pe_total > MAX_PE_TOTAL) {
|
||||
log_error("Metadata extent limit (%u) exceeded for %s - "
|
||||
"%u required", MAX_PE_TOTAL, dev_name(pv->dev),
|
||||
"%u required", MAX_PE_TOTAL, pv_dev_name(pv),
|
||||
pvd->pe_total);
|
||||
dm_free(pvd);
|
||||
return 0;
|
||||
|
||||
@@ -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>
|
||||
@@ -30,7 +30,7 @@ static void _not_supported(const char *op)
|
||||
op);
|
||||
}
|
||||
|
||||
static int _lvm1_can_handle(struct labeller *l, void *buf, uint64_t sector)
|
||||
static int _lvm1_can_handle(struct labeller *l __attribute((unused)), void *buf, uint64_t sector)
|
||||
{
|
||||
struct pv_disk *pvd = (struct pv_disk *) buf;
|
||||
uint32_t version;
|
||||
@@ -48,7 +48,7 @@ static int _lvm1_can_handle(struct labeller *l, void *buf, uint64_t sector)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _lvm1_write(struct label *label, void *buf)
|
||||
static int _lvm1_write(struct label *label __attribute((unused)), void *buf __attribute((unused)))
|
||||
{
|
||||
_not_supported("write");
|
||||
return 0;
|
||||
@@ -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;
|
||||
@@ -85,14 +87,14 @@ static int _lvm1_read(struct labeller *l, struct device *dev, void *buf,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _lvm1_initialise_label(struct labeller *l, struct label *label)
|
||||
static int _lvm1_initialise_label(struct labeller *l __attribute((unused)), struct label *label)
|
||||
{
|
||||
strcpy(label->type, "LVM1");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void _lvm1_destroy_label(struct labeller *l, struct label *label)
|
||||
static void _lvm1_destroy_label(struct labeller *l __attribute((unused)), struct label *label __attribute((unused)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved.
|
||||
# Copyright (C) 2004 Red Hat, Inc. All rights reserved.
|
||||
#
|
||||
# This file is part of the LVM2.
|
||||
# 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
|
||||
|
||||
@@ -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.
|
||||
@@ -33,8 +33,8 @@
|
||||
#define CPOUT_64(x, y) {(y) = xlate64_be((x));}
|
||||
|
||||
static int __read_pool_disk(const struct format_type *fmt, struct device *dev,
|
||||
struct dm_pool *mem, struct pool_list *pl,
|
||||
const char *vg_name)
|
||||
struct dm_pool *mem __attribute((unused)), struct pool_list *pl,
|
||||
const char *vg_name __attribute((unused)))
|
||||
{
|
||||
char buf[512] __attribute((aligned(8)));
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,51 +126,39 @@ 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;
|
||||
}
|
||||
|
||||
static struct volume_group *_pool_vg_read(struct format_instance *fid,
|
||||
const char *vg_name,
|
||||
struct metadata_area *mda)
|
||||
struct metadata_area *mda __attribute((unused)))
|
||||
{
|
||||
struct dm_pool *mem = dm_pool_create("pool vg_read", 1024);
|
||||
struct list pds;
|
||||
@@ -182,43 +168,41 @@ 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);
|
||||
return vg;
|
||||
}
|
||||
|
||||
static int _pool_pv_setup(const struct format_type *fmt,
|
||||
uint64_t pe_start, uint32_t extent_count,
|
||||
uint32_t extent_size,
|
||||
int pvmetadatacopies,
|
||||
uint64_t pvmetadatasize, struct list *mdas,
|
||||
struct physical_volume *pv, struct volume_group *vg)
|
||||
static int _pool_pv_setup(const struct format_type *fmt __attribute((unused)),
|
||||
uint64_t pe_start __attribute((unused)),
|
||||
uint32_t extent_count __attribute((unused)),
|
||||
uint32_t extent_size __attribute((unused)),
|
||||
int pvmetadatacopies __attribute((unused)),
|
||||
uint64_t pvmetadatasize __attribute((unused)),
|
||||
struct list *mdas __attribute((unused)),
|
||||
struct physical_volume *pv __attribute((unused)),
|
||||
struct volume_group *vg __attribute((unused)))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _pool_pv_read(const struct format_type *fmt, const char *pv_name,
|
||||
struct physical_volume *pv, struct list *mdas)
|
||||
struct physical_volume *pv,
|
||||
struct list *mdas __attribute((unused)))
|
||||
{
|
||||
struct dm_pool *mem = dm_pool_create("pool pv_read", 1024);
|
||||
struct pool_list *pl;
|
||||
@@ -227,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;
|
||||
|
||||
@@ -268,9 +244,9 @@ static struct metadata_area_ops _metadata_format_pool_ops = {
|
||||
/* *INDENT-ON* */
|
||||
|
||||
static struct format_instance *_pool_create_instance(const struct format_type *fmt,
|
||||
const char *vgname,
|
||||
const char *vgid,
|
||||
void *private)
|
||||
const char *vgname __attribute((unused)),
|
||||
const char *vgid __attribute((unused)),
|
||||
void *private __attribute((unused)))
|
||||
{
|
||||
struct format_instance *fid;
|
||||
struct metadata_area *mda;
|
||||
@@ -299,7 +275,7 @@ static struct format_instance *_pool_create_instance(const struct format_type *f
|
||||
return fid;
|
||||
}
|
||||
|
||||
static void _pool_destroy_instance(struct format_instance *fid)
|
||||
static void _pool_destroy_instance(struct format_instance *fid __attribute((unused)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -338,6 +314,7 @@ struct format_type *init_format(struct cmd_context *cmd)
|
||||
fmt->ops = &_format_pool_ops;
|
||||
fmt->name = FMT_POOL_NAME;
|
||||
fmt->alias = NULL;
|
||||
fmt->orphan_vg_name = FMT_POOL_ORPHAN_VG_NAME;
|
||||
fmt->features = 0;
|
||||
fmt->private = NULL;
|
||||
|
||||
|
||||
@@ -18,6 +18,9 @@
|
||||
|
||||
#include "metadata.h"
|
||||
|
||||
#define FMT_POOL_NAME "pool"
|
||||
#define FMT_POOL_ORPHAN_VG_NAME ORPHAN_VG_NAME(FMT_POOL_NAME)
|
||||
|
||||
#ifdef POOL_INTERNAL
|
||||
struct format_type *init_pool_format(struct cmd_context *cmd);
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "str_list.h"
|
||||
#include "display.h"
|
||||
#include "segtype.h"
|
||||
#include "toolcontext.h"
|
||||
|
||||
/* This file contains only imports at the moment... */
|
||||
|
||||
@@ -77,11 +78,12 @@ int import_pool_lvs(struct volume_group *vg, struct dm_pool *mem, struct list *p
|
||||
lv->size = 0;
|
||||
lv->name = NULL;
|
||||
lv->le_count = 0;
|
||||
lv->read_ahead = 0;
|
||||
lv->read_ahead = vg->cmd->default_settings.read_ahead;
|
||||
lv->snapshot = NULL;
|
||||
list_init(&lv->snapshot_segs);
|
||||
list_init(&lv->segments);
|
||||
list_init(&lv->tags);
|
||||
list_init(&lv->segs_using_this_lv);
|
||||
|
||||
list_iterate_items(pl, pls) {
|
||||
lv->size += pl->pd.pl_blocks;
|
||||
@@ -89,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,
|
||||
@@ -176,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;
|
||||
}
|
||||
@@ -214,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))) {
|
||||
@@ -228,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));
|
||||
@@ -252,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;
|
||||
@@ -272,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;
|
||||
@@ -300,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -29,7 +29,7 @@ static void _pool_not_supported(const char *op)
|
||||
op);
|
||||
}
|
||||
|
||||
static int _pool_can_handle(struct labeller *l, void *buf, uint64_t sector)
|
||||
static int _pool_can_handle(struct labeller *l __attribute((unused)), void *buf, uint64_t sector)
|
||||
{
|
||||
|
||||
struct pool_disk pd;
|
||||
@@ -50,7 +50,7 @@ static int _pool_can_handle(struct labeller *l, void *buf, uint64_t sector)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _pool_write(struct label *label, void *buf)
|
||||
static int _pool_write(struct label *label __attribute((unused)), void *buf __attribute((unused)))
|
||||
{
|
||||
_pool_not_supported("write");
|
||||
return 0;
|
||||
@@ -64,14 +64,14 @@ static int _pool_read(struct labeller *l, struct device *dev, void *buf,
|
||||
return read_pool_label(&pl, l, dev, buf, label);
|
||||
}
|
||||
|
||||
static int _pool_initialise_label(struct labeller *l, struct label *label)
|
||||
static int _pool_initialise_label(struct labeller *l __attribute((unused)), struct label *label)
|
||||
{
|
||||
strcpy(label->type, "POOL");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void _pool_destroy_label(struct labeller *l, struct label *label)
|
||||
static void _pool_destroy_label(struct labeller *l __attribute((unused)), struct label *label __attribute((unused)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,29 +297,27 @@ 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",
|
||||
dev_name(pv->dev));
|
||||
pv_dev_name(pv));
|
||||
return 0;
|
||||
}
|
||||
if (cmd->fmt != info->fmt) {
|
||||
log_error("PV %s is a different format (seqno %s)",
|
||||
dev_name(pv->dev), info->fmt->name);
|
||||
pv_dev_name(pv), info->fmt->name);
|
||||
return 0;
|
||||
}
|
||||
if (!vg->fid->fmt->ops->
|
||||
pv_setup(vg->fid->fmt, UINT64_C(0), 0, 0, 0,
|
||||
UINT64_C(0), &vg->fid->metadata_areas, pv, vg)) {
|
||||
log_error("Format-specific setup for %s failed",
|
||||
dev_name(pv->dev));
|
||||
pv_dev_name(pv));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "lvm-string.h"
|
||||
#include "segtype.h"
|
||||
#include "text_export.h"
|
||||
#include "version.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <time.h>
|
||||
@@ -36,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); \
|
||||
@@ -134,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;
|
||||
@@ -194,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 */
|
||||
}
|
||||
|
||||
@@ -270,6 +267,19 @@ int out_hint(struct formatter *f, const char *fmt, ...)
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Appends a comment
|
||||
*/
|
||||
static int _out_comment(struct formatter *f, const char *comment, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int r;
|
||||
|
||||
_out_with_comment(f, comment, fmt, ap);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* The normal output function.
|
||||
*/
|
||||
@@ -286,16 +296,22 @@ 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);
|
||||
|
||||
outf(f, "# Generated by LVM2: %s", ctime(&t));
|
||||
outf(f, "# Generated by LVM2 version %s: %s", LVM_VERSION, ctime(&t));
|
||||
outf(f, CONTENTS_FIELD " = \"" CONTENTS_VALUE "\"");
|
||||
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,
|
||||
@@ -309,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);
|
||||
}
|
||||
|
||||
@@ -336,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);
|
||||
|
||||
@@ -360,7 +368,7 @@ static int _print_vg(struct formatter *f, struct volume_group *vg)
|
||||
static const char *_get_pv_name(struct formatter *f, struct physical_volume *pv)
|
||||
{
|
||||
return (pv) ? (const char *)
|
||||
dm_hash_lookup(f->pv_names, dev_name(pv->dev)) : "Missing";
|
||||
dm_hash_lookup(f->pv_names, pv_dev_name(pv)) : "Missing";
|
||||
}
|
||||
|
||||
static int _print_pvs(struct formatter *f, struct volume_group *vg)
|
||||
@@ -368,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 {");
|
||||
@@ -376,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\"", dev_name(pv->dev))) {
|
||||
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, "}");
|
||||
@@ -442,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, "}");
|
||||
@@ -484,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),
|
||||
@@ -520,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);
|
||||
}
|
||||
|
||||
@@ -545,8 +534,17 @@ static int _print_lv(struct formatter *f, struct logical_volume *lv)
|
||||
outf(f, "allocation_policy = \"%s\"",
|
||||
get_alloc_string(lv->alloc));
|
||||
|
||||
if (lv->read_ahead)
|
||||
switch (lv->read_ahead) {
|
||||
case DM_READ_AHEAD_NONE:
|
||||
_out_comment(f, "# None", "read_ahead = -1");
|
||||
break;
|
||||
case DM_READ_AHEAD_AUTO:
|
||||
/* No output - use default */
|
||||
break;
|
||||
default:
|
||||
outf(f, "read_ahead = %u", lv->read_ahead);
|
||||
}
|
||||
|
||||
if (lv->major >= 0)
|
||||
outf(f, "major = %d", lv->major);
|
||||
if (lv->minor >= 0)
|
||||
@@ -556,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);
|
||||
@@ -587,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);
|
||||
@@ -636,7 +628,7 @@ static int _build_pv_names(struct formatter *f, struct volume_group *vg)
|
||||
if (!(name = dm_pool_strdup(f->mem, buffer)))
|
||||
return_0;
|
||||
|
||||
if (!dm_hash_insert(f->pv_names, dev_name(pv->dev), name))
|
||||
if (!dm_hash_insert(f->pv_names, pv_dev_name(pv), name))
|
||||
return_0;
|
||||
}
|
||||
|
||||
@@ -648,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;
|
||||
@@ -698,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;
|
||||
@@ -725,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));
|
||||
|
||||
@@ -744,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;
|
||||
@@ -757,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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -83,6 +80,13 @@ static int _text_vg_setup(struct format_instance *fid __attribute((unused)),
|
||||
return 1;
|
||||
}
|
||||
|
||||
static uint64_t _mda_free_sectors_raw(struct metadata_area *mda)
|
||||
{
|
||||
struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
|
||||
|
||||
return mdac->free_sectors;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if metadata area belongs to vg
|
||||
*/
|
||||
@@ -140,8 +144,8 @@ static int _pv_analyze_mda_raw (const struct format_type * fmt,
|
||||
int i;
|
||||
uint64_t offset;
|
||||
uint64_t offset2;
|
||||
uint64_t size;
|
||||
uint64_t size2;
|
||||
size_t size;
|
||||
size_t size2;
|
||||
char *buf=NULL;
|
||||
struct device_area *area;
|
||||
struct mda_context *mdac;
|
||||
@@ -149,9 +153,8 @@ static int _pv_analyze_mda_raw (const struct format_type * fmt,
|
||||
|
||||
mdac = (struct mda_context *) mda->metadata_locn;
|
||||
|
||||
log_print("Found text metadata area, offset=%"PRIu64", size=%"PRIu64,
|
||||
mdac->area.start,
|
||||
mdac->area.size);
|
||||
log_print("Found text metadata area: offset=%" PRIu64 ", size=%"
|
||||
PRIu64, mdac->area.start, mdac->area.size);
|
||||
area = &mdac->area;
|
||||
|
||||
if (!dev_open(area->dev))
|
||||
@@ -201,12 +204,12 @@ static int _pv_analyze_mda_raw (const struct format_type * fmt,
|
||||
/*
|
||||
* FIXME: We could add more sophisticated metadata detection
|
||||
*/
|
||||
if (maybe_config_section(buf, size+size2)) {
|
||||
if (maybe_config_section(buf, size + size2)) {
|
||||
/* FIXME: Validate region, pull out timestamp?, etc */
|
||||
/* FIXME: Do something with this region */
|
||||
log_verbose ("Found LVM2 metadata record at "
|
||||
"offset=%"PRIu64", size=%"PRIu64", "
|
||||
"offset2=%"PRIu64" size2=%"PRIu64,
|
||||
"offset=%"PRIu64", size=%"PRIsize_t", "
|
||||
"offset2=%"PRIu64" size2=%"PRIsize_t,
|
||||
offset, size, offset2, size2);
|
||||
offset = prev_sector;
|
||||
size = SECTOR_SIZE;
|
||||
@@ -244,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) {
|
||||
@@ -291,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;
|
||||
}
|
||||
@@ -343,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;
|
||||
@@ -374,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;
|
||||
}
|
||||
@@ -416,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;
|
||||
@@ -447,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));
|
||||
@@ -477,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),
|
||||
@@ -538,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);
|
||||
@@ -583,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,
|
||||
@@ -596,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,
|
||||
@@ -646,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;
|
||||
@@ -753,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];
|
||||
@@ -795,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
|
||||
@@ -840,8 +813,8 @@ static struct volume_group *_vg_read_precommit_file(struct format_instance *fid,
|
||||
return vg;
|
||||
}
|
||||
|
||||
static int _vg_write_file(struct format_instance *fid, struct volume_group *vg,
|
||||
struct metadata_area *mda)
|
||||
static int _vg_write_file(struct format_instance *fid __attribute((unused)),
|
||||
struct volume_group *vg, struct metadata_area *mda)
|
||||
{
|
||||
struct text_context *tc = (struct text_context *) mda->metadata_locn;
|
||||
|
||||
@@ -905,7 +878,7 @@ static int _vg_write_file(struct format_instance *fid, struct volume_group *vg,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _vg_commit_file_backup(struct format_instance *fid,
|
||||
static int _vg_commit_file_backup(struct format_instance *fid __attribute((unused)),
|
||||
struct volume_group *vg,
|
||||
struct metadata_area *mda)
|
||||
{
|
||||
@@ -972,7 +945,8 @@ static int _vg_commit_file(struct format_instance *fid, struct volume_group *vg,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _vg_remove_file(struct format_instance *fid, struct volume_group *vg,
|
||||
static int _vg_remove_file(struct format_instance *fid __attribute((unused)),
|
||||
struct volume_group *vg __attribute((unused)),
|
||||
struct metadata_area *mda)
|
||||
{
|
||||
struct text_context *tc = (struct text_context *) mda->metadata_locn;
|
||||
@@ -1031,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))
|
||||
@@ -1043,7 +1017,8 @@ static int _scan_file(const struct format_type *fmt)
|
||||
|
||||
const char *vgname_from_mda(const struct format_type *fmt,
|
||||
struct device_area *dev_area, struct id *vgid,
|
||||
uint32_t *vgstatus, char **creation_host)
|
||||
uint32_t *vgstatus, char **creation_host,
|
||||
uint64_t *mda_free_sectors)
|
||||
{
|
||||
struct raw_locn *rlocn;
|
||||
struct mda_header *mdah;
|
||||
@@ -1052,11 +1027,13 @@ const char *vgname_from_mda(const struct format_type *fmt,
|
||||
unsigned int len = 0;
|
||||
char buf[NAME_LEN + 1] __attribute((aligned(8)));
|
||||
char uuid[64] __attribute((aligned(8)));
|
||||
uint64_t buffer_size, current_usage;
|
||||
|
||||
if (!dev_open(dev_area->dev)) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
if (mda_free_sectors)
|
||||
*mda_free_sectors = ((dev_area->size - MDA_HEADER_SIZE) / 2) >> SECTOR_SHIFT;
|
||||
|
||||
if (!dev_open(dev_area->dev))
|
||||
return_NULL;
|
||||
|
||||
if (!(mdah = _raw_read_mda_header(fmt, dev_area)))
|
||||
goto_out;
|
||||
@@ -1102,21 +1079,31 @@ 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
|
||||
" for %s (%s)",
|
||||
" (in area at %" PRIu64 " size %" PRIu64
|
||||
") for %s (%s)",
|
||||
dev_name(dev_area->dev), dev_area->start + rlocn->offset,
|
||||
rlocn->size, vgname, uuid);
|
||||
rlocn->size, dev_area->start, dev_area->size, vgname, uuid);
|
||||
|
||||
if (mda_free_sectors) {
|
||||
current_usage = (rlocn->size + SECTOR_SIZE - UINT64_C(1)) -
|
||||
(rlocn->size + SECTOR_SIZE - UINT64_C(1)) % SECTOR_SIZE;
|
||||
buffer_size = mdah->size - MDA_HEADER_SIZE;
|
||||
|
||||
if (current_usage * 2 >= buffer_size)
|
||||
*mda_free_sectors = UINT64_C(0);
|
||||
else
|
||||
*mda_free_sectors = ((buffer_size - 2 * current_usage) / 2) >> SECTOR_SHIFT;
|
||||
}
|
||||
|
||||
out:
|
||||
if (!dev_close(dev_area->dev))
|
||||
@@ -1143,10 +1130,10 @@ static int _scan_raw(const struct format_type *fmt)
|
||||
list_iterate_items(rl, raw_list) {
|
||||
/* FIXME We're reading mdah twice here... */
|
||||
if ((vgname = vgname_from_mda(fmt, &rl->dev_area, &vgid, &vgstatus,
|
||||
NULL))) {
|
||||
NULL, NULL))) {
|
||||
if ((vg = _vg_read_raw_area(&fid, vgname,
|
||||
&rl->dev_area, 0)))
|
||||
lvmcache_update_vg(vg);
|
||||
lvmcache_update_vg(vg, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1164,7 +1151,8 @@ static int _mda_setup(const struct format_type *fmt,
|
||||
uint64_t pe_start, uint64_t pe_end,
|
||||
int pvmetadatacopies,
|
||||
uint64_t pvmetadatasize, struct list *mdas,
|
||||
struct physical_volume *pv, struct volume_group *vg)
|
||||
struct physical_volume *pv,
|
||||
struct volume_group *vg __attribute((unused)))
|
||||
{
|
||||
uint64_t mda_adjustment, disk_size, alignment;
|
||||
uint64_t start1, mda_size1; /* First area - start of disk */
|
||||
@@ -1182,7 +1170,7 @@ static int _mda_setup(const struct format_type *fmt,
|
||||
|
||||
if (pe_end > disk_size) {
|
||||
log_error("Physical extents end beyond end of device %s!",
|
||||
dev_name(pv->dev));
|
||||
pv_dev_name(pv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1203,7 +1191,7 @@ static int _mda_setup(const struct format_type *fmt,
|
||||
/* Ensure it's not going to be bigger than the disk! */
|
||||
if (start1 + mda_size1 > disk_size) {
|
||||
log_warn("WARNING: metadata area fills disk leaving no "
|
||||
"space for data on %s.", dev_name(pv->dev));
|
||||
"space for data on %s.", pv_dev_name(pv));
|
||||
/* Leave some free space for rounding */
|
||||
/* Avoid empty data area as could cause tools problems */
|
||||
mda_size1 = disk_size - start1 - alignment * 2;
|
||||
@@ -1303,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)
|
||||
@@ -1342,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) {
|
||||
@@ -1359,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;
|
||||
@@ -1375,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;
|
||||
}
|
||||
@@ -1424,20 +1403,17 @@ 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? */
|
||||
if (info->vginfo && info->vginfo->vgname && *info->vginfo->vgname &&
|
||||
if (info->vginfo && info->vginfo->vgname &&
|
||||
!is_orphan_vg(info->vginfo->vgname) &&
|
||||
get_pv_from_vg_by_id(info->fmt, info->vginfo->vgname,
|
||||
info->vginfo->vgid, info->dev->pvid, pv)) {
|
||||
return 1;
|
||||
@@ -1448,7 +1424,7 @@ static int _text_pv_read(const struct format_type *fmt, const char *pv_name,
|
||||
lvmcache_label_scan(fmt->cmd, 2);
|
||||
|
||||
if (info->vginfo && info->vginfo->vgname &&
|
||||
*info->vginfo->vgname &&
|
||||
!is_orphan_vg(info->vginfo->vgname) &&
|
||||
get_pv_from_vg_by_id(info->fmt, info->vginfo->vgname,
|
||||
info->vginfo->vgid,
|
||||
info->dev->pvid, pv)) {
|
||||
@@ -1460,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 */
|
||||
@@ -1555,6 +1531,7 @@ static struct metadata_area_ops _metadata_text_raw_ops = {
|
||||
.vg_precommit = _vg_precommit_raw,
|
||||
.vg_commit = _vg_commit_raw,
|
||||
.vg_revert = _vg_revert_raw,
|
||||
.mda_free_sectors = _mda_free_sectors_raw,
|
||||
.mda_in_vg = _mda_in_vg_raw,
|
||||
.pv_analyze_mda = _pv_analyze_mda_raw,
|
||||
};
|
||||
@@ -1583,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++;
|
||||
@@ -1615,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));
|
||||
@@ -1646,7 +1619,7 @@ static int _text_pv_setup(const struct format_type *fmt,
|
||||
vg->extent_size;
|
||||
if (pe_count > UINT32_MAX) {
|
||||
log_error("PV %s too large for extent size %s.",
|
||||
dev_name(pv->dev),
|
||||
pv_dev_name(pv),
|
||||
display_size(vg->cmd, (uint64_t) vg->extent_size));
|
||||
return 0;
|
||||
}
|
||||
@@ -1660,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;
|
||||
@@ -1705,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);
|
||||
@@ -1724,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);
|
||||
@@ -1740,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));
|
||||
@@ -1759,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) {
|
||||
@@ -1771,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));
|
||||
@@ -1807,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.");
|
||||
@@ -1929,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;
|
||||
|
||||
@@ -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
|
||||
@@ -57,6 +61,7 @@ void del_mdas(struct list *mdas);
|
||||
|
||||
const char *vgname_from_mda(const struct format_type *fmt,
|
||||
struct device_area *dev_area, struct id *vgid,
|
||||
uint32_t *vgstatus, char **creation_host);
|
||||
uint32_t *vgstatus, char **creation_host,
|
||||
uint64_t *mda_free_sectors);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -111,7 +127,8 @@ static int _read_id(struct id *id, struct config_node *cn, const char *path)
|
||||
|
||||
static int _read_pv(struct format_instance *fid, struct dm_pool *mem,
|
||||
struct volume_group *vg, struct config_node *pvn,
|
||||
struct config_node *vgn, struct dm_hash_table *pv_hash)
|
||||
struct config_node *vgn __attribute((unused)),
|
||||
struct dm_hash_table *pv_hash)
|
||||
{
|
||||
struct physical_volume *pv;
|
||||
struct pv_list *pvl;
|
||||
@@ -119,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;
|
||||
|
||||
@@ -130,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.");
|
||||
@@ -163,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));
|
||||
|
||||
@@ -201,7 +212,7 @@ static int _read_pv(struct format_instance *fid, struct dm_pool *mem,
|
||||
if ((cn = find_config_node(pvn, "tags")) &&
|
||||
!(read_tags(mem, &pv->tags, cn->v))) {
|
||||
log_error("Couldn't read tags for physical volume %s in %s.",
|
||||
dev_name(pv->dev), vg->name);
|
||||
pv_dev_name(pv), vg->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -214,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 */
|
||||
if (!pv->size && pv->dev) {
|
||||
if (!dev_get_size(pv->dev, &pv->size)) {
|
||||
log_error("%s: Couldn't get size.", dev_name(pv->dev));
|
||||
return 0;
|
||||
}
|
||||
log_verbose("Fixing up missing format1 size (%s) "
|
||||
"for PV %s", display_size(fid->fmt->cmd, pv->size),
|
||||
dev_name(pv->dev));
|
||||
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",
|
||||
dev_name(pv->dev));
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@@ -299,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,
|
||||
@@ -318,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")) &&
|
||||
@@ -342,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;
|
||||
}
|
||||
|
||||
@@ -383,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, 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, 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'.",
|
||||
@@ -425,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++;
|
||||
}
|
||||
@@ -453,42 +457,36 @@ 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;
|
||||
}
|
||||
|
||||
static int _read_lvnames(struct format_instance *fid, struct dm_pool *mem,
|
||||
static int _read_lvnames(struct format_instance *fid __attribute((unused)),
|
||||
struct dm_pool *mem,
|
||||
struct volume_group *vg, struct config_node *lvn,
|
||||
struct config_node *vgn, struct dm_hash_table *pv_hash)
|
||||
struct config_node *vgn __attribute((unused)),
|
||||
struct dm_hash_table *pv_hash __attribute((unused)))
|
||||
{
|
||||
struct logical_volume *lv;
|
||||
struct lv_list *lvl;
|
||||
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.");
|
||||
@@ -514,20 +512,31 @@ static int _read_lvnames(struct format_instance *fid, struct dm_pool *mem,
|
||||
}
|
||||
|
||||
lv->alloc = get_alloc_from_string(cv->v.str);
|
||||
if (lv->alloc == ALLOC_INVALID) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (lv->alloc == ALLOC_INVALID)
|
||||
return_0;
|
||||
}
|
||||
|
||||
/* read_ahead defaults to 0 */
|
||||
if (!_read_int32(lvn, "read_ahead", &lv->read_ahead))
|
||||
lv->read_ahead = 0;
|
||||
/* If not present, choice of auto or none is configurable */
|
||||
lv->read_ahead = vg->cmd->default_settings.read_ahead;
|
||||
else {
|
||||
switch (lv->read_ahead) {
|
||||
case 0:
|
||||
lv->read_ahead = DM_READ_AHEAD_AUTO;
|
||||
break;
|
||||
case (uint32_t) -1:
|
||||
lv->read_ahead = DM_READ_AHEAD_NONE;
|
||||
break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
lv->snapshot = NULL;
|
||||
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")) &&
|
||||
@@ -544,9 +553,11 @@ static int _read_lvnames(struct format_instance *fid, struct dm_pool *mem,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _read_lvsegs(struct format_instance *fid, struct dm_pool *mem,
|
||||
static int _read_lvsegs(struct format_instance *fid __attribute((unused)),
|
||||
struct dm_pool *mem,
|
||||
struct volume_group *vg, struct config_node *lvn,
|
||||
struct config_node *vgn, struct dm_hash_table *pv_hash)
|
||||
struct config_node *vgn __attribute((unused)),
|
||||
struct dm_hash_table *pv_hash)
|
||||
{
|
||||
struct logical_volume *lv;
|
||||
struct lv_list *lvl;
|
||||
@@ -572,10 +583,8 @@ static int _read_lvsegs(struct format_instance *fid, struct dm_pool *mem,
|
||||
|
||||
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;
|
||||
|
||||
@@ -625,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;
|
||||
@@ -650,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 */
|
||||
@@ -731,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;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -831,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 */
|
||||
|
||||
@@ -75,6 +75,7 @@ struct mda_lists {
|
||||
|
||||
struct mda_context {
|
||||
struct device_area area;
|
||||
uint64_t free_sectors;
|
||||
struct raw_locn rlocn; /* Store inbetween write and commit */
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
@@ -162,6 +162,7 @@ int add_mda(const struct format_type *fmt, struct dm_pool *mem, struct list *mda
|
||||
mdac->area.dev = dev;
|
||||
mdac->area.start = start;
|
||||
mdac->area.size = size;
|
||||
mdac->free_sectors = UINT64_C(0);
|
||||
memset(&mdac->rlocn, 0, sizeof(mdac->rlocn));
|
||||
|
||||
list_add(mdas, &mdal->list);
|
||||
@@ -206,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;
|
||||
|
||||
@@ -238,8 +241,9 @@ 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,
|
||||
&vgid, &vgstatus, &creation_host)) &&
|
||||
if ((vgname = vgname_from_mda(info->fmt, &mdac->area,
|
||||
&vgid, &vgstatus, &creation_host,
|
||||
&mdac->free_sectors)) &&
|
||||
!lvmcache_update_vgname_and_id(info, vgname,
|
||||
(char *) &vgid, vgstatus,
|
||||
creation_host))
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved.
|
||||
# Copyright (C) 2004 Red Hat, Inc. All rights reserved.
|
||||
#
|
||||
# This file is part of the LVM2.
|
||||
# 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
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef CLUSTER_LOCKING_INTERNAL
|
||||
int lock_resource(struct cmd_context *cmd, const char *resource, int flags);
|
||||
int lock_resource(struct cmd_context *cmd, const char *resource, uint32_t flags);
|
||||
void locking_end(void);
|
||||
int locking_init(int type, struct config_tree *cf, uint32_t *flags);
|
||||
#endif
|
||||
@@ -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;
|
||||
}
|
||||
@@ -295,7 +295,7 @@ static int _cluster_free_request(lvm_response_t * response, int num)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _lock_for_cluster(unsigned char cmd, unsigned int flags, char *name)
|
||||
static int _lock_for_cluster(unsigned char cmd, uint32_t flags, const char *name)
|
||||
{
|
||||
int status;
|
||||
int i;
|
||||
@@ -330,11 +330,14 @@ static int _lock_for_cluster(unsigned char cmd, unsigned int flags, 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
|
||||
* the cluster because they might have side-effects.
|
||||
*/
|
||||
if (cmd == CLVMD_CMD_LOCK_VG ||
|
||||
(flags & LCK_TYPE_MASK) == LCK_EXCL ||
|
||||
(flags & LCK_LOCAL) ||
|
||||
!(flags & LCK_CLUSTER_VG))
|
||||
if (strncmp(name, "P_", 2) &&
|
||||
(cmd == CLVMD_CMD_LOCK_VG ||
|
||||
(flags & LCK_TYPE_MASK) == LCK_EXCL ||
|
||||
(flags & LCK_LOCAL) ||
|
||||
!(flags & LCK_CLUSTER_VG)))
|
||||
node = ".";
|
||||
|
||||
status = _cluster_request(cmd, node, args, len,
|
||||
@@ -368,13 +371,15 @@ static int _lock_for_cluster(unsigned char cmd, unsigned int flags, char *name)
|
||||
/* API entry point for LVM */
|
||||
#ifdef CLUSTER_LOCKING_INTERNAL
|
||||
static int _lock_resource(struct cmd_context *cmd, const char *resource,
|
||||
int flags)
|
||||
uint32_t flags)
|
||||
#else
|
||||
int lock_resource(struct cmd_context *cmd, const char *resource, int flags)
|
||||
int lock_resource(struct cmd_context *cmd, const char *resource, uint32_t flags)
|
||||
#endif
|
||||
{
|
||||
char lockname[PATH_MAX];
|
||||
int cluster_cmd = 0;
|
||||
const char *lock_scope;
|
||||
const char *lock_type = "";
|
||||
|
||||
assert(strlen(resource) < sizeof(lockname));
|
||||
assert(resource);
|
||||
@@ -382,12 +387,15 @@ int lock_resource(struct cmd_context *cmd, const char *resource, int flags)
|
||||
switch (flags & LCK_SCOPE_MASK) {
|
||||
case LCK_VG:
|
||||
/* If the VG name is empty then lock the unused PVs */
|
||||
if (!*resource)
|
||||
if (!*resource) /* FIXME Deprecated */
|
||||
dm_snprintf(lockname, sizeof(lockname), "P_orphans");
|
||||
else if (*resource == '#')
|
||||
dm_snprintf(lockname, sizeof(lockname), "P_%s", resource + 1);
|
||||
else
|
||||
dm_snprintf(lockname, sizeof(lockname), "V_%s",
|
||||
resource);
|
||||
|
||||
lock_scope = "VG";
|
||||
cluster_cmd = CLVMD_CMD_LOCK_VG;
|
||||
flags &= LCK_TYPE_MASK;
|
||||
break;
|
||||
@@ -395,6 +403,7 @@ int lock_resource(struct cmd_context *cmd, const char *resource, int flags)
|
||||
case LCK_LV:
|
||||
cluster_cmd = CLVMD_CMD_LOCK_LV;
|
||||
strcpy(lockname, resource);
|
||||
lock_scope = "LV";
|
||||
flags &= 0xffdf; /* Mask off HOLD flag */
|
||||
break;
|
||||
|
||||
@@ -404,9 +413,46 @@ int lock_resource(struct cmd_context *cmd, const char *resource, int flags)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Send a message to the cluster manager */
|
||||
log_very_verbose("Locking %s at 0x%x", lockname, flags);
|
||||
switch(flags & LCK_TYPE_MASK) {
|
||||
case LCK_UNLOCK:
|
||||
lock_type = "UN";
|
||||
break;
|
||||
case LCK_NULL:
|
||||
lock_type = "NL";
|
||||
break;
|
||||
case LCK_READ:
|
||||
lock_type = "CR";
|
||||
break;
|
||||
case LCK_PREAD:
|
||||
lock_type = "PR";
|
||||
break;
|
||||
case LCK_WRITE:
|
||||
lock_type = "PW";
|
||||
break;
|
||||
case LCK_EXCL:
|
||||
lock_type = "EX";
|
||||
break;
|
||||
default:
|
||||
log_error("Unrecognised lock type: %u",
|
||||
flags & LCK_TYPE_MASK);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If we are unlocking a VG, then trigger remote metadata backups */
|
||||
if (cluster_cmd == CLVMD_CMD_LOCK_VG && ((flags & LCK_TYPE_MASK) == LCK_UNLOCK)) {
|
||||
log_very_verbose("Requesing backup of VG metadata for %s", resource);
|
||||
_lock_for_cluster(CLVMD_CMD_VG_BACKUP, LCK_CLUSTER_VG, resource);
|
||||
}
|
||||
|
||||
log_very_verbose("Locking %s %s %s %s%s%s%s (0x%x)", lock_scope, lockname,
|
||||
lock_type,
|
||||
flags & LCK_NONBLOCK ? "" : "B",
|
||||
flags & LCK_HOLD ? "H" : "",
|
||||
flags & LCK_LOCAL ? "L" : "",
|
||||
flags & LCK_CLUSTER_VG ? "C" : "",
|
||||
flags);
|
||||
|
||||
/* Send a message to the cluster manager */
|
||||
return _lock_for_cluster(cluster_cmd, flags, lockname);
|
||||
}
|
||||
|
||||
@@ -433,7 +479,7 @@ void reset_locking(void)
|
||||
|
||||
_clvmd_sock = _open_local_sock();
|
||||
if (_clvmd_sock == -1)
|
||||
stack;
|
||||
stack;
|
||||
}
|
||||
|
||||
#ifdef CLUSTER_LOCKING_INTERNAL
|
||||
|
||||
@@ -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.
|
||||
@@ -23,12 +23,12 @@ static void *_locking_lib = NULL;
|
||||
static void (*_reset_fn) (void) = NULL;
|
||||
static void (*_end_fn) (void) = NULL;
|
||||
static int (*_lock_fn) (struct cmd_context * cmd, const char *resource,
|
||||
int flags) = NULL;
|
||||
uint32_t flags) = NULL;
|
||||
static int (*_init_fn) (int type, struct config_tree * cft,
|
||||
uint32_t *flags) = NULL;
|
||||
|
||||
static int _lock_resource(struct cmd_context *cmd, const char *resource,
|
||||
int flags)
|
||||
uint32_t flags)
|
||||
{
|
||||
if (_lock_fn)
|
||||
return _lock_fn(cmd, resource, flags);
|
||||
@@ -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")) ||
|
||||
|
||||
@@ -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>
|
||||
@@ -124,7 +123,7 @@ static void _install_ctrl_c_handler()
|
||||
siginterrupt(SIGINT, 1);
|
||||
}
|
||||
|
||||
static int _lock_file(const char *file, int flags)
|
||||
static int _lock_file(const char *file, uint32_t flags)
|
||||
{
|
||||
int operation;
|
||||
int r = 1;
|
||||
@@ -204,58 +203,52 @@ static int _lock_file(const char *file, int flags)
|
||||
}
|
||||
|
||||
static int _file_lock_resource(struct cmd_context *cmd, const char *resource,
|
||||
int flags)
|
||||
uint32_t flags)
|
||||
{
|
||||
char lockfile[PATH_MAX];
|
||||
|
||||
assert(resource);
|
||||
|
||||
switch (flags & LCK_SCOPE_MASK) {
|
||||
case LCK_VG:
|
||||
if (!*resource)
|
||||
if (!*resource) /* FIXME Deprecated */
|
||||
dm_snprintf(lockfile, sizeof(lockfile),
|
||||
"%s/P_orphans", _lock_dir);
|
||||
else if (*resource == '#')
|
||||
dm_snprintf(lockfile, sizeof(lockfile),
|
||||
"%s/P_%s", _lock_dir, resource + 1);
|
||||
else
|
||||
dm_snprintf(lockfile, sizeof(lockfile),
|
||||
"%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) {
|
||||
case LCK_UNLOCK:
|
||||
log_debug("Unlocking LV %s", resource);
|
||||
log_very_verbose("Unlocking LV %s", resource);
|
||||
if (!lv_resume_if_active(cmd, resource))
|
||||
return 0;
|
||||
break;
|
||||
case LCK_NULL:
|
||||
log_debug("Locking LV %s (NL)", resource);
|
||||
log_very_verbose("Locking LV %s (NL)", resource);
|
||||
if (!lv_deactivate(cmd, resource))
|
||||
return 0;
|
||||
break;
|
||||
case LCK_READ:
|
||||
log_debug("Locking LV %s (R)", resource);
|
||||
log_very_verbose("Locking LV %s (R)", resource);
|
||||
if (!lv_activate_with_filter(cmd, resource, 0))
|
||||
return 0;
|
||||
break;
|
||||
case LCK_PREAD:
|
||||
log_very_verbose("Locking LV %s (PR) - ignored", resource);
|
||||
break;
|
||||
case LCK_WRITE:
|
||||
log_debug("Locking LV %s (W)", resource);
|
||||
log_very_verbose("Locking LV %s (W)", resource);
|
||||
if (!lv_suspend_if_active(cmd, resource))
|
||||
return 0;
|
||||
break;
|
||||
case LCK_EXCL:
|
||||
log_debug("Locking LV %s (EX)", resource);
|
||||
log_very_verbose("Locking LV %s (EX)", resource);
|
||||
if (!lv_activate_with_filter(cmd, resource, 1))
|
||||
return 0;
|
||||
break;
|
||||
|
||||
@@ -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>
|
||||
@@ -118,7 +119,7 @@ void sigint_restore(void)
|
||||
sigaction(SIGINT, &_oldhandler, NULL);
|
||||
}
|
||||
|
||||
static void _block_signals(int flags __attribute((unused)))
|
||||
static void _block_signals(uint32_t flags __attribute((unused)))
|
||||
{
|
||||
sigset_t set;
|
||||
|
||||
@@ -156,7 +157,7 @@ static void _unblock_signals(void)
|
||||
return;
|
||||
}
|
||||
|
||||
static void _lock_memory(int flags)
|
||||
static void _lock_memory(uint32_t flags)
|
||||
{
|
||||
if (!(_locking.flags & LCK_PRE_MEMLOCK))
|
||||
return;
|
||||
@@ -165,7 +166,7 @@ static void _lock_memory(int flags)
|
||||
memlock_inc();
|
||||
}
|
||||
|
||||
static void _unlock_memory(int flags)
|
||||
static void _unlock_memory(uint32_t flags)
|
||||
{
|
||||
if (!(_locking.flags & LCK_PRE_MEMLOCK))
|
||||
return;
|
||||
@@ -187,7 +188,7 @@ void reset_locking(void)
|
||||
_unblock_signals();
|
||||
}
|
||||
|
||||
static void _update_vg_lock_count(int flags)
|
||||
static void _update_vg_lock_count(uint32_t flags)
|
||||
{
|
||||
if ((flags & LCK_SCOPE_MASK) != LCK_VG)
|
||||
return;
|
||||
@@ -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 "
|
||||
@@ -288,7 +289,7 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname)
|
||||
char path[PATH_MAX];
|
||||
|
||||
/* We'll allow operations on orphans */
|
||||
if (!*vgname)
|
||||
if (is_orphan_vg(vgname))
|
||||
return 1;
|
||||
|
||||
if (dm_snprintf(path, sizeof(path), "%s/lvm/VGs/%s", cmd->proc_dir,
|
||||
@@ -313,28 +314,42 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname)
|
||||
* VG locking is by VG name.
|
||||
* FIXME This should become VG uuid.
|
||||
*/
|
||||
static int _lock_vol(struct cmd_context *cmd, const char *resource, int flags)
|
||||
static int _lock_vol(struct cmd_context *cmd, const char *resource, uint32_t flags)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
_block_signals(flags);
|
||||
_lock_memory(flags);
|
||||
|
||||
if (!(_locking.lock_resource(cmd, resource, flags))) {
|
||||
_unlock_memory(flags);
|
||||
_unblock_signals();
|
||||
return 0;
|
||||
assert(resource);
|
||||
|
||||
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, int flags)
|
||||
int lock_vol(struct cmd_context *cmd, const char *vol, uint32_t flags)
|
||||
{
|
||||
char resource[258] __attribute((aligned(8)));
|
||||
|
||||
if (flags == LCK_NONE) {
|
||||
log_debug("Internal error: %s: LCK_NONE lock requested", vol);
|
||||
return 1;
|
||||
}
|
||||
|
||||
switch (flags & LCK_SCOPE_MASK) {
|
||||
case LCK_VG:
|
||||
/* Lock VG to change on-disk metadata. */
|
||||
@@ -397,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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,14 +28,14 @@ int locking_is_clustered(void);
|
||||
/*
|
||||
* LCK_VG:
|
||||
* Lock/unlock on-disk volume group data
|
||||
* Use "" to lock orphan PVs
|
||||
* Use VG_ORPHANS to lock orphan PVs
|
||||
* char *vol holds volume group name
|
||||
*
|
||||
* LCK_LV:
|
||||
* Lock/unlock an individual logical volume
|
||||
* char *vol holds lvid
|
||||
*/
|
||||
int lock_vol(struct cmd_context *cmd, const char *vol, int flags);
|
||||
int lock_vol(struct cmd_context *cmd, const char *vol, uint32_t flags);
|
||||
|
||||
/*
|
||||
* Does the LVM1 driver have this VG active?
|
||||
@@ -45,42 +45,49 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
|
||||
/*
|
||||
* Lock type - these numbers are the same as VMS and the IBM DLM
|
||||
*/
|
||||
#define LCK_TYPE_MASK 0x00000007
|
||||
#define LCK_TYPE_MASK 0x00000007U
|
||||
|
||||
#define LCK_NULL 0x00000000 /* LCK$_NLMODE */
|
||||
#define LCK_READ 0x00000001 /* LCK$_CRMODE */
|
||||
#define LCK_NULL 0x00000000U /* LCK$_NLMODE */
|
||||
#define LCK_READ 0x00000001U /* LCK$_CRMODE */
|
||||
/* LCK$_CWMODE */
|
||||
#define LCK_PREAD 0x00000003 /* LCK$_PRMODE */
|
||||
#define LCK_WRITE 0x00000004 /* LCK$_PWMODE */
|
||||
#define LCK_EXCL 0x00000005 /* LCK$_EXMODE */
|
||||
#define LCK_UNLOCK 0x00000006 /* This is ours */
|
||||
#define LCK_PREAD 0x00000003U /* LCK$_PRMODE */
|
||||
#define LCK_WRITE 0x00000004U /* LCK$_PWMODE */
|
||||
#define LCK_EXCL 0x00000005U /* LCK$_EXMODE */
|
||||
#define LCK_UNLOCK 0x00000006U /* This is ours */
|
||||
|
||||
/*
|
||||
* Lock scope
|
||||
*/
|
||||
#define LCK_SCOPE_MASK 0x00000008
|
||||
#define LCK_VG 0x00000000
|
||||
#define LCK_LV 0x00000008
|
||||
#define LCK_SCOPE_MASK 0x00000008U
|
||||
#define LCK_VG 0x00000000U
|
||||
#define LCK_LV 0x00000008U
|
||||
|
||||
/*
|
||||
* Lock bits
|
||||
*/
|
||||
#define LCK_NONBLOCK 0x00000010 /* Don't block waiting for lock? */
|
||||
#define LCK_HOLD 0x00000020 /* Hold lock when lock_vol returns? */
|
||||
#define LCK_LOCAL 0x00000040 /* Don't propagate to other nodes */
|
||||
#define LCK_CLUSTER_VG 0x00000080 /* VG is clustered */
|
||||
#define LCK_NONBLOCK 0x00000010U /* Don't block waiting for lock? */
|
||||
#define LCK_HOLD 0x00000020U /* Hold lock when lock_vol returns? */
|
||||
#define LCK_LOCAL 0x00000040U /* Don't propagate to other nodes */
|
||||
#define LCK_CLUSTER_VG 0x00000080U /* VG is clustered */
|
||||
|
||||
/*
|
||||
* Additional lock bits for cluster communication
|
||||
*/
|
||||
#define LCK_PARTIAL_MODE 0x00000001 /* Running in partial mode */
|
||||
#define LCK_MIRROR_NOSYNC_MODE 0x00000002 /* Mirrors don't require sync */
|
||||
#define LCK_DMEVENTD_MONITOR_MODE 0x00000004 /* Register with dmeventd */
|
||||
#define LCK_PARTIAL_MODE 0x00000001U /* Running in partial mode */
|
||||
#define LCK_MIRROR_NOSYNC_MODE 0x00000002U /* Mirrors don't require sync */
|
||||
#define LCK_DMEVENTD_MONITOR_MODE 0x00000004U /* Register with dmeventd */
|
||||
|
||||
/*
|
||||
* Special cases of VG locks.
|
||||
*/
|
||||
#define VG_ORPHANS "#orphans"
|
||||
#define VG_GLOBAL "#global"
|
||||
|
||||
/*
|
||||
* Common combinations
|
||||
*/
|
||||
#define LCK_NONE (LCK_VG | LCK_NULL)
|
||||
|
||||
#define LCK_VG_READ (LCK_VG | LCK_READ | LCK_HOLD)
|
||||
#define LCK_VG_WRITE (LCK_VG | LCK_WRITE | LCK_HOLD)
|
||||
#define LCK_VG_UNLOCK (LCK_VG | LCK_UNLOCK)
|
||||
@@ -92,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))
|
||||
@@ -113,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);
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#include "config.h"
|
||||
|
||||
typedef int (*lock_resource_fn) (struct cmd_context * cmd, const char *resource,
|
||||
int flags);
|
||||
uint32_t flags);
|
||||
|
||||
typedef void (*fin_lock_fn) (void);
|
||||
typedef void (*reset_lock_fn) (void);
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -37,19 +36,10 @@ static void _no_reset_locking(void)
|
||||
}
|
||||
|
||||
static int _no_lock_resource(struct cmd_context *cmd, const char *resource,
|
||||
int flags)
|
||||
uint32_t flags)
|
||||
{
|
||||
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) {
|
||||
@@ -76,7 +66,7 @@ static int _no_lock_resource(struct cmd_context *cmd, const char *resource,
|
||||
return 1;
|
||||
}
|
||||
|
||||
int init_no_locking(struct locking_type *locking, struct cmd_context *cmd)
|
||||
int init_no_locking(struct locking_type *locking, struct cmd_context *cmd __attribute((unused)))
|
||||
{
|
||||
locking->lock_resource = _no_lock_resource;
|
||||
locking->reset_locking = _no_reset_locking;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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,
|
||||
@@ -48,9 +48,6 @@ struct alloc_handle *allocate_extents(struct volume_group *vg,
|
||||
uint32_t stripes,
|
||||
uint32_t mirrors, uint32_t log_count,
|
||||
uint32_t extents,
|
||||
struct physical_volume *mirrored_pv,
|
||||
uint32_t mirrored_pe,
|
||||
uint32_t status,
|
||||
struct list *allocatable_pvs,
|
||||
alloc_policy_t alloc,
|
||||
struct list *parallel_areas);
|
||||
@@ -60,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
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user