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

Compare commits

..

345 Commits

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

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

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

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

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

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

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

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

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

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


Author: Jun'ichi Nomura <j-nomura@ce.jp.nec.com>
Committer: Jim Meyering <meyering@redhat.com>
2007-12-05 09:49:08 +00:00
Patrick Caulfield
8f21c9a920 When we unlock a VG tell the clvmds to see if a backup of the metadata needs
to be done.
2007-12-04 15:39:26 +00:00
Alasdair Kergon
0ba7d05ea7 fixme 2007-12-03 22:53:04 +00:00
Alasdair Kergon
5a4c5b4155 fixes 2007-12-03 22:48:36 +00:00
Alasdair Kergon
55323fb497 fix changed parms 2007-12-03 18:00:38 +00:00
Alasdair Kergon
7c082d2471 missing #include 2007-12-03 17:56:36 +00:00
Alasdair Kergon
f3cafcf983 fix 2007-11-30 16:44:42 +00:00
Alasdair Kergon
75073e4aa6 readahead support completed - untested 2007-11-30 16:42:26 +00:00
Alasdair Kergon
a3c23f650c read_ahead node ops 2007-11-30 14:59:57 +00:00
Alasdair Kergon
0545cd5879 uncomment libdevmapper readahead calls 2007-11-29 15:04:12 +00:00
Alasdair Kergon
c96506f22c refine specification of dmsetup readahead 2007-11-29 14:44:28 +00:00
Alasdair Kergon
49b2006824 add read_ahead functions to library and dmsetup --readahead
(Not live yet.)
2007-11-27 20:57:05 +00:00
Petr Rockai
8c6f96faab Fix a possible double-free in libdevmapper-event. 2007-11-27 12:26:06 +00:00
Alasdair Kergon
a0e648abfd drop mirrored_pv/mirrored_pe from alloc handle 2007-11-22 14:54:35 +00:00
Alasdair Kergon
6350cd12fc Start refactoring pvmove allocation code. 2007-11-22 13:57:21 +00:00
Alasdair Kergon
f2fab0677b FIXMEs for case where dm itself has device open 2007-11-22 01:25:06 +00:00
Alasdair Kergon
edffc52927 note pvmove breakage 2007-11-19 18:24:08 +00:00
Alasdair Kergon
d6e5e3d103 Decode cluster locking state in log message. (untested)
Change file locking state messages from debug to very verbose.
2007-11-16 21:16:20 +00:00
Alasdair Kergon
5be7a0ebf7 move pvresize_single back under tools 2007-11-15 22:11:18 +00:00
Alasdair Kergon
7f722fe7d3 Fix --addtag to drop @ prefix from name 2007-11-15 21:59:11 +00:00
Alasdair Kergon
a01732ee9b more vg_read lock fixes 2007-11-15 21:30:52 +00:00
Patrick Caulfield
85ac11b69b If the pre_command fails then go back and wait patiently for the next
pre function rather than retrying it until we get stuck!
2007-11-15 10:16:14 +00:00
Alasdair Kergon
590cfb77a5 define LCK_NONE for cases when vg_lock_and_read already holds lock
(temporary - library will use internal ref counting instead)
2007-11-15 02:55:22 +00:00
Alasdair Kergon
f01dd16a27 another vg_lock_and_read 2007-11-15 02:53:49 +00:00
Alasdair Kergon
df49287e5f Convert some vg_reads into vg_lock_and_reads 2007-11-15 02:20:03 +00:00
Alasdair Kergon
c8ec8391ee Avoid nested vg_reads when processing PVs in VGs and fix associated locking. 2007-11-14 18:41:05 +00:00
Patrick Caulfield
3499e48064 Make it compile with new lv_info_by_lvid() prototype 2007-11-14 13:37:51 +00:00
Alasdair Kergon
2e379cb8a5 Accept sizes with --readahead argument.
Store size arguments as sectors internally.
2007-11-14 00:08:25 +00:00
Alasdair Kergon
f8ee3c2369 fix precedence 2007-11-12 21:50:21 +00:00
Alasdair Kergon
c74fa11518 readahead activation code (but no dm support yet) 2007-11-12 20:51:54 +00:00
Alasdair Kergon
ceec4455df Add DM_READ_AHEAD_MINIMUM_FLAG 2007-11-12 20:47:18 +00:00
Dave Wysochanski
17c9975c0b Fix compile warnings / minor errors introduced recently. 2007-11-12 20:02:55 +00:00
Alasdair Kergon
6c1cdff912 Remove new mirror logs when creation fails. 2007-11-12 14:36:57 +00:00
Alasdair Kergon
79f53f569d Attempt to remove incomplete LVs with lvcreate zeroing/activation problems. 2007-11-12 13:34:14 +00:00
Alasdair Kergon
ccb85cc719 Define DM_READ_AHEAD_AUTO and DM_READ_AHEAD_NONE. 2007-11-09 16:52:36 +00:00
Alasdair Kergon
c0eff8a07f Enhance the management of readahead settings. 2007-11-09 16:51:54 +00:00
Alasdair Kergon
954626f157 Prevent lvconvert -s from using same LV as origin and snapshot. 2007-11-07 16:33:12 +00:00
Alasdair Kergon
17e7dfa4bd Add pv_mda_free and vg_mda_free fields to reports for raw text format. 2007-11-05 17:17:55 +00:00
Alasdair Kergon
971f233fb7 attempt to fix human-readable unit output when number of sectors is odd 2007-11-05 17:13:54 +00:00
Alasdair Kergon
b12bc692af fix inverted orphan test 2007-11-05 17:12:50 +00:00
Alasdair Kergon
730301b34d adjust sizes for metadata 2007-11-05 02:10:39 +00:00
Alasdair Kergon
c443bcf43c Show 'not usable' space when PV is too large for device in pvdisplay.
Ignore and fix up any excessive device size found in metadata.
2007-11-05 01:47:49 +00:00
Alasdair Kergon
b77e7eeddc Add LVM2 version to 'Generated by' comment in metadata. 2007-11-04 19:16:34 +00:00
Alasdair Kergon
031b7b57a1 fix new lvremove checks - mustn't fail when activation is disabled 2007-11-04 16:28:57 +00:00
Alasdair Kergon
5123fab525 Fix error message when fixing up PV size in lvm2 metadata (2.02.11). 2007-11-04 15:43:50 +00:00
Alasdair Kergon
705b96c6f9 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.
2007-11-02 20:40:05 +00:00
Bryn M. Reeves
9ec582002b Convert pvchange, pvdisplay, pvscan to use is_orphan() 2007-11-02 14:54:40 +00:00
Bryn M. Reeves
ee79277774 Add is_orphan_vg() and change all hardcoded checks to use it. 2007-11-02 13:06:42 +00:00
Alasdair Kergon
db02dc218e explanation of md superblock location & avoid compilation warnings 2007-10-24 11:24:24 +00:00
Alasdair Kergon
b66ce1089e Detect md superblocks version 1.0, 1.1 and 1.2. 2007-10-24 00:51:05 +00:00
Alasdair Kergon
ec0e70b599 refactor dev-md.c, separating out the magic number detection 2007-10-24 00:30:30 +00:00
Dave Wysochanski
a273482f9d Remove comment about allocation of pv->vg_name. 2007-10-12 21:08:38 +00:00
Dave Wysochanski
76cf8c4cf7 Add _alloc_pv() and _free_pv() from _pv_create() code and fix error paths.
Modified original patch by Jun'ichi Nomura <j-nomura@ce.jp.nec.com>
2007-10-12 18:37:19 +00:00
Dave Wysochanski
9691ecc839 Add pv_dev_name() to access PV device name.
Patch by Jun'ichi Nomura <j-nomura@ce.jp.nec.com>
2007-10-12 14:29:32 +00:00
Dave Wysochanski
59b2a86359 Accessor functions for PV will not modify the given PV.
So we can add 'const' to it.
Patch by Jun'ichi Nomura <j-nomura@ce.jp.nec.com>
2007-10-12 14:08:10 +00:00
Dave Wysochanski
fe7cd72cff Non-functional change - refactor lv_create_empty().
Remove struct format_instance param - we can safely obtain
this from vg->fid inside the function.
2007-10-11 19:20:38 +00:00
Dave Wysochanski
f0761fc570 Non-functional change - refactor vg_add_snapshot fid parameter. 2007-10-11 18:51:21 +00:00
Alasdair Kergon
90990aa19d Handle new sysfs subsystem/block/devices directory structure. 2007-10-10 11:31:21 +00:00
Alasdair Kergon
a3d3ce82e4 Fix configure --with-dmeventd-path substitution. 2007-10-10 00:02:03 +00:00
Jim Meyering
b8e48113a3 Run tests with LVM_SYSTEM_DIR pointing to private root and /dev dirs.
This makes the tests more reproducible and helps isolate
them from any existing LVM set-up.
* test/Makefile.in (abs_builddir): Define.
(init.sh): Emit definition of abs_builddir.
* test/lvm-utils.sh (unsafe_losetup_): Keep only the portable,
iterative approach.
(dmsetup_has_dm_devdir_support_): New function.
(init_root_dir_): New function.
Invoke init_root_dir_ for all but the first test.
* test/test-lib.sh (this_test_): Adapt to test-name change.
Invoke lvm-utils.sh much later (after tmpdir creation), and
only if the current test is not being skipped.
Remove useless abs_top_srcdir definition.
Rename t0->test_dir_rand_.
* test/t-lvcreate-pvtags.sh: Skip this test if the available
version of dmsetup is not new enough.
Use global, $G_dev_, rather than hard-coded "/dev".
* test/t-lvcreate-usage.sh: Make --verbose output more useful.


Author: Jim Meyering <jim@meyering.net>
Committer: Jim Meyering <meyering@redhat.com>
2007-10-09 13:13:06 +00:00
Jim Meyering
d4b1003a97 Allow $DM_DEV_DIR envvar to override default of "/dev".
* dmsetup/dmsetup.c (DEV_PATH): Remove definition.
(parse_loop_device_name): Add parameter: dev_dir.
Declare the "dev" parameter to be "const".
Use dev_dir, not DEV_PATH.  Handle the case in which dev_dir
does not end in a "/".
(_get_abspath): Declare "path" parameter "const", to match.
(_process_losetup_switches): Add parameter: dev_dir.
Pass dev_dir to parse_loop_device_name.
(_process_switches): Add parameter: dev_dir.
Pass dev_dir to _process_losetup_switches.
(main): Set dev_dir from the DM_DEV_DIR envvar, else to "/dev".
Call dm_set_dev_dir.
* lib/libdm-common.c (dm_set_dev_dir): Rewrite to be careful
about boundary conditions, now that dev_dir may be tainted.
* man/dmsetup.8: Mention $DM_DEV_DIR.


Author: Jim Meyering <meyering@redhat.com>
2007-10-09 12:14:48 +00:00
Jim Meyering
efd83567c9 Fix the fsadm build failure without using -llvm.
* lib/misc/util.c (last_path_component): Move definition to ...
* lib/misc/last-path-component.h (last_path_component): ...here.
New file.  Make the function "static inline".
* include/.symlinks: Add last-path-component.h.
* lib/misc/util.h (last_path_component): Remove declaration.
* tools/fsadm/fsadm.c: Include "last-path-component.h".
* tools/lvmcmdline.c: Likewise.

Author: Jim Meyering <meyering@redhat.com>
2007-10-03 16:10:04 +00:00
Jim Meyering
5563f373f7 Revert last change. fsadm must not depend on -llvm.
Author: Jim Meyering <meyering@redhat.com>
2007-10-03 16:08:18 +00:00
Petr Rockai
15a36619fe a) use dmsetup version to check for dmsetup, but if it fails, set
DMSETUP=: to disable dmsetup checks (but let the script run
nevertheless); warn the user if this is the case
b) put the non-root and dmsetup warnings both at start and end of
output
2007-10-03 15:00:51 +00:00
Jim Meyering
38e54b626e Arrange for "make clean" to remove the symlink, too.
* make.tmpl.in ($(VERSIONED_SHLIB)): Move rule to...
* lib/Makefile.in ($(VERSIONED_SHLIB)): ...here, removing the
$(interface)/ prefix.
Reported by Milan Broz.

Author: Jim Meyering <meyering@redhat.com>
2007-10-03 10:48:27 +00:00
Jim Meyering
8aa30fb56a Avoid link failure when building fsadm.
* tools/fsadm/Makefile.in (LVMLIBS): Define.
(fsadm): Link with $(LVMLIBS).

Author: Nix <nix@esperi.org.uk>
2007-10-03 09:46:57 +00:00
Petr Rockai
b764becd1b Fix underquotations in lvm_dump.sh. 2007-10-02 16:09:46 +00:00
Petr Rockai
219370932e Fix a bug in lvm_dump.sh checks for lvm/dmsetup binaries quote the
invocations a bit more (although i'm fairly sure there are still
quotes missing somewhere due to the eval in log).
2007-10-02 15:48:58 +00:00
Dave Wysochanski
90afae186c Remove unused pargc parameter 2007-10-01 15:01:26 +00:00
Jim Meyering
84e49a809d doc/testing.txt: Fix typo: s/this/thing/.
Author: Jim Meyering <jim@meyering.net>
2007-09-25 08:28:57 +00:00
Dave Wysochanski
1cfb9ff46a Some const fixups for previous checkins 2007-09-24 21:30:00 +00:00
Jim Meyering
f35026c74f Avoid over-quoting in shell scripts.
Do not use "..." around the RHS of VAR= assignment,
nor on the argument of "case ... in ...".


Author: Jim Meyering <jim@meyering.net>
2007-09-24 19:19:18 +00:00
Dave Wysochanski
5f2d3da8c5 Refactor lvcreate mirror parameter validation. 2007-09-24 13:29:49 +00:00
Dave Wysochanski
4e61f32a28 Refactor lvcreate stripe parameter validation. 2007-09-24 13:25:31 +00:00
Dave Wysochanski
d7814c7011 add tests to validate lvextend %PVS 2007-09-21 21:14:25 +00:00
Jim Meyering
aa40668e84 Don't emit a trailing newline to stderr.
* tools/lvmcmdline.c (_short_usage): Remove trailing "\n".
Spotted by Alasdair G. Kergon.


Author: Jim Meyering <jim@meyering.net>
2007-09-21 18:43:55 +00:00
Jim Meyering
3767e6e96f Print --help output to stdout, not stderr.
* tools/lvmcmdline.c (_usage): Use log_print, not log_error.


Author: Jim Meyering <jim@meyering.net>
2007-09-21 18:06:56 +00:00
Jim Meyering
44976cef6c After a diagnostic, suggest --help, rather than printing all --help output.
Print just one line:
Use `COMMAND --help' for more information.
after "real" diagnostic(s), rather than all of the usage lines.
Otherwise, the 30-40+ lines of --help output could obscure the real diagnostic.


Author: Jim Meyering <jim@meyering.net>
2007-09-21 18:06:33 +00:00
Jim Meyering
eba4417947 Rename test scripts not to include the 4-digit number.
Author: Jim Meyering <jim@meyering.net>
2007-09-21 17:12:13 +00:00
Jim Meyering
c99204d370 Correct typo in comments: s/is part of the LVM2/is part of LVM2/.
Signed-off-by: Jim Meyering <jim@meyering.net>


Author: Jim Meyering <jim@meyering.net>
2007-09-21 10:16:45 +00:00
Dave Wysochanski
1bfc4335bb Add %PVS extents option to lvresize, lvextend, and lvcreate. 2007-09-20 21:39:08 +00:00
Jim Meyering
6b9c7485f1 test/t3000-lvcreate-pvtags.sh: Use better test names.
Author: Jim Meyering <jim@meyering.net>
2007-09-18 21:07:21 +00:00
Jim Meyering
737f3d78f2 * configure.in (AC_CONFIG_FILES): Remove the test/*/Makefile names
corresponding to the recently-removed directories.
* configure: Regenerate.
Reported by Dave Wysochanski.


Author: Jim Meyering <jim@meyering.net>
2007-09-18 18:26:32 +00:00
Jim Meyering
b1d5e1b5e3 test/Makefile.in (lvm-wrapper): Use $(DMDIR)/lib/, not $(DMDIR)/lib/ioctl/.
Author: Jim Meyering <jim@meyering.net>
2007-09-18 14:29:06 +00:00
Jim Meyering
8d92a5cc14 Clean-up and wording changes; add copyright notices.
* test/Makefile.in (srcdir, top_srcdir): Use @srcdir@, etc.
(top_builddir, abs_srcdir, abs_top_builddir, abs_top_srcdir): Likewise.
(so_name): Remove definition.
(.bin-dir-stamp): No longer create symlink in $(DMDIR) tree.
Prompted by suggestions from Alasdair Kergon.
* test/t1000-lvcreate-usage.sh (cleanup_): Redirect to a file,
rather than to /dev/null.
Change wording of some test titles.
Suggestions from Alasdair Kergon.

* test/Makefile.in: Add a copyright notice.
* test/lvm-utils.sh: Likewise.
* test/mkdtemp: Likewise.
* test/t0000-basic.sh: Likewise.
* test/t1000-lvcreate-usage.sh: Likewise.
* test/t3000-lvcreate-pvtags.sh: Likewise.
* test/t4000-pv-range-overflow.sh: Likewise.
* test/test-lib.sh: Likewise.


Author: Jim Meyering <jim@meyering.net>
2007-09-18 14:02:22 +00:00
Jim Meyering
fc455df92c Test how lvcreate handles its command-line options.
* test/t1000-lvcreate-usage.sh: New tests.
* test/Makefile.in (T): Add it.
Derived from test cases by Dave Wysochanski.


Author: Jim Meyering <jim@meyering.net>
2007-09-18 14:01:46 +00:00
Jim Meyering
c0076ebfa1 Clean up shared-lib support in test/.
* test/Makefile.in (so_name): Use @DMDIR@.
(.bin-dir-stamp): Create symlink only if @DMDIR@ is nonempty.
(lvm-wrapper): Emit LD_LIBRARY_PATH setting only if @DMDIR@ is nonempty.
Based on a patch from Jun'ichi Nomura.


Author: Jim Meyering <jim@meyering.net>
2007-09-18 14:01:24 +00:00
Jim Meyering
5d607aa3cd Allow relative dir name in: --with-dmdir=../device-mapper
* configure.in: Convert a relative dmdir directory name to the required
absolute form, e.g. in ./configure --with-dmdir=../device-mapper
Suggestion from Jun'ichi Nomura.
* configure: Regenerate.


Author: Jim Meyering <jim@meyering.net>
2007-09-18 14:01:08 +00:00
Jim Meyering
fa1b9a4098 Add testing framework, along with first few tests.
* Makefile.in (check): New target.
* configure.in (AC_CONFIG_FILES): Add test/Makefile.
* configure: Regenerate.
* test/.gitignore: New file.
* test/Makefile.in: New file.
* test/lvm-utils.sh: New script.
* test/mkdtemp (die, rand_bytes, mkdtemp): New script.
* test/t0000-basic.sh: New tests.
* test/t3000-lvcreate-pvtags.sh: New, failing test.
Derived from a script by Jun'ichi Nomura.
* test/t4000-pv-range-overflow.sh: New test.
* test/test-lib.sh: Testing framework, based on the one from git.


Author: Jim Meyering <jim@meyering.net>
2007-09-18 14:00:42 +00:00
Jim Meyering
c8c4dbb409 Create a symlink, e.g., libdevmapper.so.1.02, in the build dir,
alongside the .so file.  This helps build dynamically linked LVM.

* lib/Makefile.in (VERSIONED_SHLIB): Define.
* make.tmpl.in (TARGETS): Append $(VERSIONED_SHLIB).
($(VERSIONED_SHLIB)): New rule.


Author: Jim Meyering <jim@meyering.net>
2007-09-18 13:02:58 +00:00
Alasdair Kergon
16628e6cea Moved the obsolete test subdirectory to old-tests.
If you're using the CVS repository you'll need to remove it and check
it out again when we repopulate it.
2007-09-17 19:51:02 +00:00
Alasdair Kergon
7067c12991 Remove no-longer-correct restrictions on PV arg count with stripes/mirrors.
[E.g. They fail if tags or --alloc anywhere used.]
2007-09-17 17:18:37 +00:00
Alasdair Kergon
7b47e241e0 clarification 2007-09-17 17:06:31 +00:00
Alasdair Kergon
d1e46207a5 Fix strdup memory leak in str_list_dup(). 2007-09-17 16:02:46 +00:00
Jim Meyering
2a04b97cbd configure: regenerate, to remove vestige of an upcoming patch 2007-09-12 18:23:02 +00:00
Jim Meyering
e6c8ef59e0 Avoid static link failure with some SELinux libraries.
Author: Jim Meyering <jim@meyering.net>
2007-09-12 16:54:23 +00:00
Jim Meyering
d3380f41de Diagnose invalid PE values given on the pvmove command line (64-bit systems).
* tools/toollib.c (xstrtouint32): New function.
(_parse_pes): Use xstrtouint32; don't cast strtoul's unsigned
long to uint32_t.  Detect overflow.


Author: Jim Meyering <jim@meyering.net>
2007-09-11 20:12:54 +00:00
Dave Wysochanski
4ef1633969 Undo previous checkin - output format not good, info already available in other form(s) 2007-09-11 13:49:52 +00:00
Dave Wysochanski
57e593aab2 Add pvseg_free field to 'pvs' output 2007-09-10 20:05:29 +00:00
Jim Meyering
6461caacbb Include strerror string in dev_open_flags' stat failure message.
* lib/device/dev-io.c (dev_open_flags):
Use log_sys_error after failed stat to report strerror(errno).
Use a slightly different diagnostic to report mismatched device number.
2007-09-07 11:24:19 +00:00
Dave Wysochanski
e5531e2a93 Fix last checkin 2007-09-06 22:35:01 +00:00
Dave Wysochanski
329402a614 Fixup _lvresize error return codes and modularize function 2007-09-06 21:08:16 +00:00
Dave Wysochanski
4656ed462e prepare to move guts of vgrename into library function 2007-08-31 19:09:49 +00:00
Dave Wysochanski
96ddad91a9 move guts of pvresize into library 2007-08-30 20:30:41 +00:00
Dave Wysochanski
5eb40588d2 prepare to move guts of pvresize into library 2007-08-30 20:16:01 +00:00
Alasdair Kergon
58def149aa Avoid error when --corelog is provided without --mirrorlog. (2.02.28)
Correct --mirrorlog argument name in man pages (not --log).
2007-08-30 19:34:19 +00:00
Jonathan Earl Brassow
0ee5743d75 - I neglected to update this file on last check-in, which fixed
the MIRROR_NOTSYNCED flag being passed on to a linear lv when
  converting from a mirror.
2007-08-30 18:53:32 +00:00
Jonathan Earl Brassow
7c266f3e81 When mirrors are created with the --nosync option, a status flag
(MIRROR_NOTSYNCED) is added to the LVM metadata.  This flag is
not cleared when converting to linear.  Subsequently, if you
up-convert the linear to a mirror, the flag remains - even though
an up-convert will always force a complete resync.
2007-08-29 20:19:11 +00:00
Dave Wysochanski
d7ce981cd1 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.
Update vgremove man page for '-f'.
2007-08-28 16:14:49 +00:00
Alasdair Kergon
eadadf6299 post-release 2007-08-24 21:05:15 +00:00
Alasdair Kergon
8ac9fabd07 pre-release 2007-08-24 21:01:52 +00:00
Patrick Caulfield
44c2b4b281 Fix clvmd logging so you can get lvm-level debugging out of it. 2007-08-24 08:29:39 +00:00
Patrick Caulfield
4cd97611e5 Locking P_global causes a cache refresh. 2007-08-23 15:43:20 +00:00
Alasdair Kergon
da27380ab5 Introduce VG_GLOBAL lock type for vgscan/pvscan to trigger clvmd -R. 2007-08-23 15:02:26 +00:00
Patrick Caulfield
756e539661 Force a device scan after init_full_scan_done() per agk. 2007-08-23 12:44:09 +00:00
Patrick Caulfield
cde44e3172 Call init_full_scan_done() when refreshing the cache. This should fix clvmd -R. 2007-08-23 12:19:13 +00:00
Alasdair Kergon
e79a4b34b0 Change lvconvert_mirrors to use mirror segtype not striped. 2007-08-22 20:03:46 +00:00
Alasdair Kergon
e9f0bdd72c Fix lvconvert_mirrors detection of number of existing mirrors. 2007-08-22 19:32:39 +00:00
Alasdair Kergon
d080291150 Clean up numerous compiler warnings that crept in recently.
Remove several unused parameters from _allocate().
2007-08-22 14:38:18 +00:00
Jim Meyering
06c69c56ba Avoid static link failure with some SELinux libraries. 2007-08-21 20:32:29 +00:00
Alasdair Kergon
d79710ba9d Fix (C) ! 2007-08-21 19:56:18 +00:00
Alasdair Kergon
c9bc7dd0b6 Clean up mirrorlog argument processing.
Only permit --force, --verbose and --debug arguments to be repeated.
2007-08-21 19:46:36 +00:00
Alasdair Kergon
ebc26c7421 Remove obsolete dmfs code from tree and update INSTALL. 2007-08-21 18:41:58 +00:00
Dave Wysochanski
3769425f6b Move guts of vgremove into lvm library.
Include archiver.h in metadata.c as a result of prior move.
2007-08-21 17:38:20 +00:00
Alasdair Kergon
a50957443e post-release 2007-08-21 17:03:07 +00:00
Dave Wysochanski
63fa007af0 Prepare to move guts of vgremove into lvm library.
Fixup force_t.
2007-08-21 16:40:33 +00:00
251 changed files with 13706 additions and 5837 deletions

View File

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

View File

@@ -1 +1 @@
2.02.28-cvs (2007-07-17)
2.02.35-cvs (2008-04-15)

230
WHATS_NEW
View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -115,8 +115,15 @@ 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();
else if (strncmp(lockname, "P_", 2) == 0)
lvmcache_drop_metadata(lockname + 2);
break;
case CLVMD_CMD_LOCK_LV:
@@ -148,6 +155,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 +266,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 +296,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;

View File

@@ -37,6 +37,7 @@
#include <getopt.h>
#include <syslog.h>
#include <errno.h>
#include <limits.h>
#include <libdlm.h>
#include "clvmd-comms.h"
@@ -146,8 +147,10 @@ static void usage(char *prog, FILE *file)
fprintf(file, "\n");
fprintf(file, " -V Show version of clvmd\n");
fprintf(file, " -h Show this help information\n");
fprintf(file, " -d Don't fork, run in the foreground\n");
fprintf(file, " -d Set debug level\n");
fprintf(file, " If starting clvmd then don't fork, run in the foreground\n");
fprintf(file, " -R Tell all running clvmds in the cluster to reload their device cache\n");
fprintf(file, " -C Sets debug level (from -d) on all clvmd instances clusterwide\n");
fprintf(file, " -t<secs> Command timeout (default 60 seconds)\n");
fprintf(file, " -T<secs> Startup timeout (default none)\n");
fprintf(file, "\n");
@@ -630,7 +633,7 @@ static void main_loop(int local_sock, int cmd_timeout)
}
if (FD_ISSET(thisfd->fd, &in)) {
struct local_client *newfd;
struct local_client *newfd = NULL;
int ret;
/* Do callback */
@@ -901,8 +904,7 @@ static int read_from_local_sock(struct local_client *thisfd)
}
/* Free the command buffer */
if (thisfd->bits.localsock.cmd)
free(thisfd->bits.localsock.cmd);
free(thisfd->bits.localsock.cmd);
/* Clear out the cross-link */
if (thisfd->bits.localsock.pipe_client != NULL)
@@ -937,8 +939,7 @@ static int read_from_local_sock(struct local_client *thisfd)
}
/* Free any old buffer space */
if (thisfd->bits.localsock.cmd)
free(thisfd->bits.localsock.cmd);
free(thisfd->bits.localsock.cmd);
/* See if we have the whole message */
argslen =
@@ -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));

View File

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

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 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();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,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)/$<

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -25,7 +25,8 @@ devices {
# list of regular expressions in turn and the first match is used.
preferred_names = [ ]
# preferred_names = [ "^/dev/mpath/", "^/dev/[hs]d" ]
# Try to avoid using undescriptive /dev/dm-N names, if present.
# preferred_names = [ "^/dev/mpath/", "^/dev/mapper/mpath", "^/dev/[hs]d" ]
# A filter that tells LVM2 to only use a restricted set of devices.
# The filter consists of an array of regular expressions. These
@@ -291,6 +292,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 +385,20 @@ activation {
# dmeventd {
# mirror_library is the library used when monitoring a mirror device.
#
# "libdevmapper-event-lvm2mirror.so" attempts to recover from failures.
# It removes failed devices from a volume group and reconfigures a
# mirror as necessary.
#
# "libdevmapper-event-lvm2mirror.so" attempts to recover from
# failures. It removes failed devices from a volume group and
# reconfigures a mirror as necessary. If no mirror library is
# provided, mirrors are not monitored through dmeventd.
# mirror_library = "libdevmapper-event-lvm2mirror.so"
# snapshot_library is the library used when monitoring a snapshot device.
#
# "libdevmapper-event-lvm2snapshot.so" monitors the filling of
# snapshots and emits a warning through syslog, when the use of
# snapshot exceedes 80%. The warning is repeated when 85%, 90% and
# 95% of the snapshot are filled.
# snapshot_library = "libdevmapper-event-lvm2snapshot.so"
#}

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -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;
}
@@ -658,6 +673,38 @@ int lvs_in_vg_opened(const struct volume_group *vg)
return count;
}
/*
* Determine whether an LV is active locally or in a cluster.
* Assumes vg lock held.
* Returns:
* 0 - not active locally or on any node in cluster
* 1 - active either locally or some node in the cluster
*/
int lv_is_active(struct logical_volume *lv)
{
if (_lv_active(lv->vg->cmd, lv, 0))
return 1;
if (!vg_is_clustered(lv->vg))
return 0;
/*
* FIXME: Cluster does not report per-node LV activation status.
* Currently the best we can do is try exclusive local activation.
* If that succeeds, we know the LV is not active elsewhere in the
* cluster.
*/
if (activate_lv_excl(lv->vg->cmd, lv)) {
deactivate_lv(lv->vg->cmd, lv);
return 0;
}
/*
* Exclusive local activation failed so assume it is active elsewhere.
*/
return 1;
}
/*
* Returns 0 if an attempt to (un)monitor the device failed.
* Returns 1 otherwise.
@@ -668,9 +715,10 @@ int monitor_dev_for_events(struct cmd_context *cmd,
#ifdef DMEVENTD
int i, pending = 0, monitored;
int r = 1;
struct list *tmp;
struct list *tmp, *snh, *snht;
struct lv_segment *seg;
int (*monitor_fn) (struct lv_segment *s, int e);
uint32_t s;
/* skip dmeventd code altogether */
if (dmeventd_monitor_mode() == DMEVENTD_MONITOR_IGNORE)
@@ -682,9 +730,44 @@ int monitor_dev_for_events(struct cmd_context *cmd,
if (monitor && !dmeventd_monitor_mode())
return 1;
/*
* In case of a snapshot device, we monitor lv->snapshot->lv,
* not the actual LV itself.
*/
if (lv_is_cow(lv))
return monitor_dev_for_events(cmd, lv->snapshot->lv, monitor);
/*
* In case this LV is a snapshot origin, we instead monitor
* each of its respective snapshots (the origin itself does
* not need to be monitored).
*
* TODO: This may change when snapshots of mirrors are allowed.
*/
if (lv_is_origin(lv)) {
list_iterate_safe(snh, snht, &lv->snapshot_segs)
if (!monitor_dev_for_events(cmd, list_struct_base(snh,
struct lv_segment, origin_list)->cow, monitor))
r = 0;
return r;
}
list_iterate(tmp, &lv->segments) {
seg = list_item(tmp, struct lv_segment);
/* Recurse for AREA_LV */
for (s = 0; s < seg->area_count; s++) {
if (seg_type(seg, s) != AREA_LV)
continue;
if (!monitor_dev_for_events(cmd, seg_lv(seg, s),
monitor)) {
log_error("Failed to %smonitor %s",
monitor ? "" : "un",
seg_lv(seg, s)->name);
r = 0;
}
}
if (!seg_monitored(seg) || (seg->status & PVMOVE))
continue;
@@ -772,7 +855,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 +915,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 +961,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 +1032,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 +1075,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)

View File

@@ -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.
@@ -86,6 +91,7 @@ int lvs_in_vg_activated(struct volume_group *vg);
int lvs_in_vg_activated_by_uuid_only(struct volume_group *vg);
int lvs_in_vg_opened(const struct volume_group *vg);
int lv_is_active(struct logical_volume *lv);
int monitor_dev_for_events(struct cmd_context *cmd,
struct logical_volume *lv, int do_reg);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -100,10 +100,8 @@ static struct dm_task *_setup_task(const char *name, const char *uuid,
{
struct dm_task *dmt;
if (!(dmt = dm_task_create(task))) {
stack;
return NULL;
}
if (!(dmt = dm_task_create(task)))
return_NULL;
if (name)
dm_task_set_name(dmt, name);
@@ -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, &params);
/* Skip if target type doesn't match */
if (target_type && !strcmp(target_type, "mirror"))
do {
next = dm_get_next_target(dmt, next, &start, &length,
&target_type, &params);
/* Skip if target type doesn't match */
if (target_type && !strcmp(target_type, "mirror"))
goto out;
} while (next);
} while (next);
/* FIXME Also check dependencies? */
@@ -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)

View File

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

View File

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

396
lib/cache/lvmcache.c vendored
View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -17,6 +17,7 @@
#include "lvmcache.h"
#include "toolcontext.h"
#include "dev-cache.h"
#include "locking.h"
#include "metadata.h"
#include "filter.h"
#include "memlock.h"
@@ -29,6 +30,7 @@ static struct dm_hash_table *_lock_hash = NULL;
static struct list _vginfos;
static int _has_scanned = 0;
static int _vgs_locked = 0;
static int _vg_global_lock_held = 0; /* Global lock held when cache wiped? */
int lvmcache_init(void)
{
@@ -46,9 +48,98 @@ int lvmcache_init(void)
if (!(_lock_hash = dm_hash_create(128)))
return 0;
if (_vg_global_lock_held)
lvmcache_lock_vgname(VG_GLOBAL, 0);
return 1;
}
/* Volume Group metadata cache functions */
static void _free_cached_vgmetadata(struct lvmcache_vginfo *vginfo)
{
if (!vginfo || !vginfo->vgmetadata)
return;
dm_free(vginfo->vgmetadata);
vginfo->vgmetadata = NULL;
log_debug("Metadata cache: VG %s wiped.", vginfo->vgname);
}
static void _store_metadata(struct lvmcache_vginfo *vginfo,
struct volume_group *vg, unsigned precommitted)
{
int size;
if (vginfo->vgmetadata)
_free_cached_vgmetadata(vginfo);
if (!(size = export_vg_to_buffer(vg, &vginfo->vgmetadata))) {
stack;
return;
}
vginfo->precommitted = precommitted;
log_debug("Metadata cache: VG %s stored (%d bytes%s).", vginfo->vgname,
size, precommitted ? ", precommitted" : "");
}
static void _update_cache_info_lock_state(struct lvmcache_info *info,
int locked,
int *cached_vgmetadata_valid)
{
int was_locked = (info->status & CACHE_LOCKED) ? 1 : 0;
/*
* Cache becomes invalid whenever lock state changes
*/
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_drop_metadata(const char *vgname)
{
struct lvmcache_vginfo *vginfo;
if (!(vginfo = vginfo_from_vgname(vgname, NULL)))
return;
_free_cached_vgmetadata(vginfo);
}
void lvmcache_lock_vgname(const char *vgname, int read_only __attribute((unused)))
{
if (!_lock_hash && !lvmcache_init()) {
@@ -56,9 +147,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 +169,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 +199,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 +272,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 +281,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 +331,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 +404,38 @@ int lvmcache_label_scan(struct cmd_context *cmd, int full_scan)
return r;
}
struct volume_group *lvmcache_get_vg(const char *vgid, unsigned precommitted)
{
struct lvmcache_vginfo *vginfo;
struct volume_group *vg;
struct format_instance *fid;
if (!vgid || !(vginfo = vginfo_from_vgid(vgid)) || !vginfo->vgmetadata)
return NULL;
if (!_vginfo_is_valid(vginfo))
return NULL;
if ((precommitted && !vginfo->precommitted) ||
(!precommitted && vginfo->precommitted))
return NULL;
if (!(fid = vginfo->fmt->ops->create_instance(vginfo->fmt,
vginfo->vgname,
vgid, NULL)))
return_NULL;
if (!(vg = import_vg_from_buffer(vginfo->vgmetadata, fid)) ||
!vg_validate(vg)) {
_free_cached_vgmetadata(vginfo);
return_NULL;
}
log_debug("Using cached 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 +449,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 +472,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 +498,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 +514,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 +525,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 +539,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 +550,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 +592,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 +617,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 +737,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 +761,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 +780,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 +807,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 +816,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 +874,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 +916,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 +948,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 +1007,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 +1058,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 +1105,14 @@ void lvmcache_destroy(void)
}
if (_lock_hash) {
dm_hash_iter(_lock_hash, (dm_hash_iterate_fn) _lvmcache_destroy_lockname);
dm_hash_iterate(n, _lock_hash)
_lvmcache_destroy_lockname(n);
dm_hash_destroy(_lock_hash);
_lock_hash = NULL;
}
list_init(&_vginfos);
if (retain_orphans)
init_lvmcache_orphans(cmd);
}

19
lib/cache/lvmcache.h vendored
View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -20,7 +20,8 @@
#include "uuid.h"
#include "label.h"
#define ORPHAN ""
#define ORPHAN_PREFIX "#"
#define ORPHAN_VG_NAME(fmt) ORPHAN_PREFIX "orphans_" fmt
#define CACHE_INVALID 0x00000001
#define CACHE_LOCKED 0x00000002
@@ -43,6 +44,8 @@ struct lvmcache_vginfo {
char _padding[7];
struct lvmcache_vginfo *next; /* Another VG with same name? */
char *creation_host;
char *vgmetadata; /* Copy of VG metadata as format_text string */
unsigned precommitted; /* Is vgmetadata live or precommitted? */
};
/* One per device */
@@ -59,7 +62,7 @@ struct lvmcache_info {
};
int lvmcache_init(void);
void lvmcache_destroy(void);
void lvmcache_destroy(struct cmd_context *cmd, int retain_orphans);
/* Set full_scan to 1 to reread every filtered device label or
* 2 to rescan /dev for new devices */
@@ -70,13 +73,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 +91,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 +109,8 @@ struct list *lvmcache_get_vgids(struct cmd_context *cmd, int full_scan);
struct list *lvmcache_get_pvids(struct cmd_context *cmd, const char *vgname,
const char *vgid);
/* Returns cached volume group metadata. */
struct volume_group *lvmcache_get_vg(const char *vgid, unsigned precommitted);
void lvmcache_drop_metadata(const char *vgname);
#endif

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -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);

View File

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

View File

@@ -34,7 +34,8 @@
enum {
TOK_INT,
TOK_FLOAT,
TOK_STRING,
TOK_STRING, /* Single quotes */
TOK_STRING_ESCAPED, /* Double quotes */
TOK_EQ,
TOK_SECTION_B,
TOK_SECTION_E,
@@ -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);
}
/*

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -170,10 +170,8 @@ static int _aligned_io(struct device_area *where, void *buffer,
struct device_area widened;
if (!(where->dev->flags & DEV_REGULAR) &&
!_get_block_size(where->dev, &block_size)) {
stack;
return 0;
}
!_get_block_size(where->dev, &block_size))
return_0;
if (!block_size)
block_size = lvm_getpagesize();
@@ -200,10 +198,8 @@ static int _aligned_io(struct device_area *where, void *buffer,
/* channel the io through the bounce buffer */
if (!_io(&widened, bounce, 0)) {
if (!should_write) {
stack;
return 0;
}
if (!should_write)
return_0;
/* FIXME pre-extend the file */
memset(bounce, '\n', widened.size);
}
@@ -340,7 +336,7 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
if (dev->open_count && !need_excl) {
/* FIXME Ensure we never get here */
log_debug("WARNING: %s already opened read-only",
log_debug("WARNING: %s already opened read-only",
dev_name(dev));
dev->open_count++;
}
@@ -354,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,

View File

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

View File

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

View File

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

View File

@@ -51,7 +51,8 @@ static int _errseg_add_target_line(struct dev_manager *dm __attribute((unused)),
return dm_tree_node_add_error_target(node, len);
}
static int _errseg_target_present(const struct lv_segment *seg __attribute((unused)))
static int _errseg_target_present(const struct lv_segment *seg __attribute((unused)),
unsigned *attributes __attribute((unused)))
{
static int _errseg_checked = 0;
static int _errseg_present = 0;
@@ -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);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -18,13 +18,10 @@
#include "limits.h"
#include "display.h"
#include "toolcontext.h"
#include "lvmcache.h"
#include "lvm1-label.h"
#include "format1.h"
#include "segtype.h"
#define FMT_LVM1_NAME "lvm1"
/* VG consistency checks */
static int _check_vgs(struct list *pvs, int *partial)
{
@@ -168,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))) {

View File

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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -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;

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -19,7 +19,7 @@
#include "label.h"
#include "metadata.h"
#include "xlate.h"
#include "lvmcache.h"
#include "format1.h"
#include <sys/stat.h>
#include <fcntl.h>
@@ -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;
}

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -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;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -24,8 +24,6 @@
#include "format_pool.h"
#include "pool_label.h"
#define FMT_POOL_NAME "pool"
/* Must be called after pvs are imported */
static struct user_subpool *_build_usp(struct list *pls, struct dm_pool *mem,
int *sps)
@@ -128,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;

View File

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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -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;
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -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;
}

View File

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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -78,17 +78,13 @@ static char *_build_desc(struct dm_pool *mem, const char *line, int before)
size_t len = strlen(line) + 32;
char *buffer;
if (!(buffer = dm_pool_zalloc(mem, strlen(line) + 32))) {
stack;
return NULL;
}
if (!(buffer = dm_pool_zalloc(mem, strlen(line) + 32)))
return_NULL;
if (snprintf(buffer, len,
"Created %s executing '%s'",
before ? "*before*" : "*after*", line) < 0) {
stack;
return NULL;
}
before ? "*before*" : "*after*", line) < 0)
return_NULL;
return buffer;
}
@@ -97,10 +93,8 @@ static int __archive(struct volume_group *vg)
{
char *desc;
if (!(desc = _build_desc(vg->cmd->mem, vg->cmd->cmd_line, 1))) {
stack;
return 0;
}
if (!(desc = _build_desc(vg->cmd->mem, vg->cmd->cmd_line, 1)))
return_0;
return archive_vg(vg, vg->cmd->archive_params->dir, desc,
vg->cmd->archive_params->keep_days,
@@ -121,9 +115,9 @@ int archive(struct volume_group *vg)
return 0;
/* Trap a read-only file system */
if ((access(vg->cmd->archive_params->dir, R_OK | W_OK | X_OK) == -1) &&
if ((access(vg->cmd->archive_params->dir, R_OK | W_OK | X_OK) == -1) &&
(errno == EROFS))
return 0;
return 0;
log_verbose("Archiving volume group \"%s\" metadata (seqno %u).", vg->name,
vg->seqno);
@@ -196,10 +190,8 @@ static int __backup(struct volume_group *vg)
char name[PATH_MAX];
char *desc;
if (!(desc = _build_desc(vg->cmd->mem, vg->cmd->cmd_line, 0))) {
stack;
return 0;
}
if (!(desc = _build_desc(vg->cmd->mem, vg->cmd->cmd_line, 0)))
return_0;
if (dm_snprintf(name, sizeof(name), "%s/%s",
vg->cmd->backup_params->dir, vg->name) < 0) {
@@ -227,9 +219,9 @@ int backup(struct volume_group *vg)
return 0;
/* Trap a read-only file system */
if ((access(vg->cmd->backup_params->dir, R_OK | W_OK | X_OK) == -1) &&
if ((access(vg->cmd->backup_params->dir, R_OK | W_OK | X_OK) == -1) &&
(errno == EROFS))
return 0;
return 0;
if (!__backup(vg)) {
log_error("Backup of volume group %s metadata failed.",
@@ -305,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);
}

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -36,9 +36,6 @@
#include <dirent.h>
#include <ctype.h>
#define FMT_TEXT_NAME "lvm2"
#define FMT_TEXT_ALIAS "text"
static struct mda_header *_raw_read_mda_header(const struct format_type *fmt,
struct device_area *dev_area);
@@ -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;

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -86,6 +86,22 @@ static int _check_version(struct config_tree *cft)
return 1;
}
static int _is_converting(struct logical_volume *lv)
{
struct lv_segment *seg;
if (lv->status & MIRRORED) {
seg = first_seg(lv);
/* Can't use is_temporary_mirror() because the metadata for
* seg_lv may not be read in and flags may not be set yet. */
if (seg_type(seg, 0) == AREA_LV &&
strstr(seg_lv(seg, 0)->name, MIRROR_SYNC_LAYER))
return 1;
}
return 0;
}
static int _read_id(struct id *id, struct config_node *cn, const char *path)
{
struct config_value *cv;
@@ -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 */

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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 == '#' || (flags & LCK_CACHE))
dm_snprintf(lockname, sizeof(lockname), "P_%s", resource);
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,48 @@ 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 clustered VG, then trigger remote metadata backups */
if (cluster_cmd == CLVMD_CMD_LOCK_VG &&
((flags & LCK_TYPE_MASK) == LCK_UNLOCK) &&
(flags & LCK_CLUSTER_VG)) {
log_very_verbose("Requesing backup of VG metadata for %s", resource);
_lock_for_cluster(CLVMD_CMD_VG_BACKUP, LCK_CLUSTER_VG, resource);
}
log_very_verbose("Locking %s %s %s %s%s%s%s (0x%x)", lock_scope, lockname,
lock_type,
flags & LCK_NONBLOCK ? "" : "B",
flags & LCK_HOLD ? "H" : "",
flags & LCK_LOCAL ? "L" : "",
flags & LCK_CLUSTER_VG ? "C" : "",
flags);
/* Send a message to the cluster manager */
return _lock_for_cluster(cluster_cmd, flags, lockname);
}
@@ -433,7 +481,7 @@ void reset_locking(void)
_clvmd_sock = _open_local_sock();
if (_clvmd_sock == -1)
stack;
stack;
}
#ifdef CLUSTER_LOCKING_INTERNAL

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -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")) ||

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -124,7 +124,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 +204,56 @@ 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 (flags & LCK_CACHE) {
lvmcache_drop_metadata(resource);
break;
}
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;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -21,6 +21,7 @@
#include "toolcontext.h"
#include "memlock.h"
#include "defaults.h"
#include "lvmcache.h"
#include <signal.h>
#include <sys/stat.h>
@@ -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,43 @@ 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 &&
!(flags & LCK_CACHE)) {
if ((flags & LCK_TYPE_MASK) == LCK_UNLOCK)
lvmcache_unlock_vgname(resource);
else
lvmcache_lock_vgname(resource, (flags & LCK_TYPE_MASK)
== LCK_READ);
}
_update_vg_lock_count(flags);
}
_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 +413,23 @@ int suspend_lvs(struct cmd_context *cmd, struct list *lvs)
}
/* Lock a list of LVs */
int activate_lvs_excl(struct cmd_context *cmd, struct list *lvs)
int activate_lvs(struct cmd_context *cmd, struct list *lvs, unsigned exclusive)
{
struct list *lvh;
struct lv_list *lvl;
list_iterate_items(lvl, lvs) {
if (!activate_lv_excl(cmd, lvl->lv)) {
if (!exclusive) {
if (!activate_lv(cmd, lvl->lv)) {
log_error("Failed to activate %s", lvl->lv->name);
return 0;
}
} else if (!activate_lv_excl(cmd, lvl->lv)) {
log_error("Failed to activate %s", lvl->lv->name);
list_uniterate(lvh, lvs, &lvl->list) {
lvl = list_item(lvh, struct lv_list);
activate_lv(cmd, lvl->lv);
}
return 0;
}
}

View File

@@ -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,45 +45,54 @@ 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 */
#define LCK_CACHE 0x00000100U /* Operation on cache using P_ lock */
/*
* 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)
#define LCK_VG_DROP_CACHE (LCK_VG | LCK_WRITE | LCK_CACHE)
#define LCK_LV_EXCLUSIVE (LCK_LV | LCK_EXCL | LCK_NONBLOCK)
#define LCK_LV_SUSPEND (LCK_LV | LCK_WRITE | LCK_NONBLOCK)
@@ -92,7 +101,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))
@@ -109,11 +118,13 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
lock_lv_vol(cmd, lv, LCK_LV_ACTIVATE | LCK_HOLD | LCK_LOCAL)
#define deactivate_lv_local(cmd, lv) \
lock_lv_vol(cmd, lv, LCK_LV_DEACTIVATE | LCK_LOCAL)
#define drop_cached_metadata(vg) \
lock_vol((vg)->cmd, (vg)->name, LCK_VG_DROP_CACHE)
/* Process list of LVs */
int suspend_lvs(struct cmd_context *cmd, struct list *lvs);
int resume_lvs(struct cmd_context *cmd, struct list *lvs);
int activate_lvs_excl(struct cmd_context *cmd, struct list *lvs);
int activate_lvs(struct cmd_context *cmd, struct list *lvs, unsigned exclusive);
/* Interrupt handling */
void sigint_clear(void);

View File

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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -18,7 +18,6 @@
#include "locking_types.h"
#include "lvm-string.h"
#include "activate.h"
#include "lvmcache.h"
#include <signal.h>
@@ -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;

View File

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

View File

@@ -33,9 +33,9 @@ struct lv_segment *alloc_snapshot_seg(struct logical_volume *lv,
int set_lv_segment_area_pv(struct lv_segment *seg, uint32_t area_num,
struct physical_volume *pv, uint32_t pe);
void set_lv_segment_area_lv(struct lv_segment *seg, uint32_t area_num,
struct logical_volume *lv, uint32_t le,
uint32_t flags);
int set_lv_segment_area_lv(struct lv_segment *seg, uint32_t area_num,
struct logical_volume *lv, uint32_t le,
uint32_t flags);
int move_lv_segment_area(struct lv_segment *seg_to, uint32_t area_to,
struct lv_segment *seg_from, uint32_t area_from);
void release_lv_segment_area(struct lv_segment *seg, uint32_t s,
@@ -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);

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