1
0
mirror of git://sourceware.org/git/lvm2.git synced 2026-02-06 20:32:50 +03:00

Compare commits

...

116 Commits

Author SHA1 Message Date
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
144 changed files with 5530 additions and 3143 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-08-24)
2.02.29-cvs (2007-08-24)

View File

@@ -1,3 +1,61 @@
Version 2.02.29 -
==================================
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.
Tests are run with LVM_SYSTEM_DIR pointing to private root and /dev dirs.
Fix a bug in lvm_dump.sh checks for lvm/dmsetup binaries.
Fix underquotations in lvm_dump.sh.
Refactor lvcreate stripe and mirror parameter validation.
All tools: print --help output to stdout, not stderr.
After a diagnostic, suggest --help, rather than printing all --help output.
Add %PVS extents option to lvresize, lvextend, and lvcreate.
Moved the obsolete test subdirectory to old-tests.
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.

View File

@@ -1,6 +1,12 @@
Version 1.02.23 -
==================================
Avoid static link failure with some SELinux libraries.
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.
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

4293
configure vendored

File diff suppressed because it is too large Load Diff

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
@@ -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
@@ -617,36 +635,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
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
tools/fsadm/Makefile
])
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

@@ -153,6 +153,10 @@ int do_command(struct local_client *client, struct clvm_header *msg, int msglen,
*retlen = strlen(*buf)+1;
break;
case CLVMD_CMD_VG_BACKUP:
lvm_do_backup(&args[2]);
break;
default:
/* Won't get here because command is validated in pre_command */
break;
@@ -260,6 +264,7 @@ int do_pre_command(struct local_client *client)
case CLVMD_CMD_REFRESH:
case CLVMD_CMD_GET_CLUSTERNAME:
case CLVMD_CMD_SET_DEBUG:
case CLVMD_CMD_VG_BACKUP:
break;
default:
@@ -289,6 +294,7 @@ int do_post_command(struct local_client *client)
break;
case CLVMD_CMD_LOCK_VG:
case CLVMD_CMD_VG_BACKUP:
/* Nothing to do here */
break;

View File

@@ -1379,8 +1379,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,7 +1411,7 @@ 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);

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-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -46,6 +46,7 @@
#include "log.h"
#include "activate.h"
#include "locking.h"
#include "archiver.h"
#include "defaults.h"
static struct cmd_context *cmd = NULL;
@@ -53,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;
@@ -223,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)
@@ -269,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) {
@@ -339,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:
@@ -414,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;
@@ -550,7 +556,7 @@ static void lvm2_log_fn(int level, const char *file, int line,
{
/* Send messages to the normal LVM2 logging system too,
so we get debug output when it's asked for.
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);
@@ -600,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)
{
@@ -614,6 +638,9 @@ int init_lvm(int using_gulm)
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

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

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

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

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

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

@@ -291,6 +291,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.

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

@@ -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;
}
@@ -425,7 +425,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 +439,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 +462,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);
}
/*
@@ -510,7 +511,7 @@ int lv_mirror_percent(struct cmd_context *cmd, struct logical_volume *lv,
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 +533,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 +545,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;
}
@@ -772,7 +773,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 +833,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 +879,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 +950,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 +993,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,6 +27,7 @@ struct lvinfo {
int read_only;
int live_table;
int inactive_table;
uint32_t read_ahead;
};
void set_activation(int activation);
@@ -62,9 +63,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.

View File

@@ -118,7 +118,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;
@@ -141,6 +142,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:
@@ -201,27 +208,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 +242,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 */
@@ -631,7 +644,7 @@ static int _add_dev_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
return_0;
log_debug("Getting device info for %s [%s]", name, dlid);
if (!_info(name, dlid, 0, 1, &info)) {
if (!_info(name, dlid, 0, 1, 0, &info, NULL)) {
log_error("Failed to get info for %s [%s].", name, dlid);
return 0;
}
@@ -886,6 +899,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 +948,17 @@ 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)
read_ahead = max_stripe_size;
else
read_ahead_flags = DM_READ_AHEAD_MINIMUM_FLAG;
dm_tree_node_set_read_ahead(dnode, read_ahead, read_ahead_flags);
return 1;
}

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

@@ -633,7 +633,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);
@@ -649,7 +649,7 @@ static int _lvmcache_update_vgname(struct lvmcache_info *info,
vginfo->fmt = info->fmt;
log_debug("lvmcache: %s: now %s%s%s%s%s", dev_name(info->dev),
*vgname ? "in VG " : "orphaned", vgname,
!is_orphan_vg(vgname) ? "in VG " : "orphaned", vgname,
vginfo->vgid[0] ? " (" : "",
vginfo->vgid[0] ? vginfo->vgid : "",
vginfo->vgid[0] ? ")" : "");

View File

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

View File

@@ -33,6 +33,7 @@ struct config_info {
int suffix;
int archive; /* should we archive ? */
int backup; /* should we backup ? */
int read_ahead; /* DM_READ_AHEAD_NONE or _AUTO */
const char *msg_prefix;
struct format_type *fmt;
uint64_t unit_factor;

View File

@@ -63,6 +63,7 @@
#define DEFAULT_PVMETADATASIZE 255
#define DEFAULT_PVMETADATACOPIES 1
#define DEFAULT_LABELSECTOR UINT64_C(1)
#define DEFAULT_READ_AHEAD "auto"
#define DEFAULT_MSG_PREFIX " "
#define DEFAULT_CMD_NAME 0

View File

@@ -74,7 +74,7 @@ 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))) {
if (!str_list_add(mem, sllnew, dm_pool_strdup(mem, sl->str))) {
stack;
return 0;
}

View File

@@ -359,10 +359,15 @@ int dev_open_flags(struct device *dev, int flags, int direct, int 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

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

@@ -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? */
@@ -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,24 @@ 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("PV Name %s", pv_dev_name(pv));
log_print("VG Name %s%s", 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
@@ -363,7 +365,7 @@ int pvdisplay_short(const struct cmd_context *cmd __attribute((unused)),
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 +381,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,
@@ -410,7 +412,7 @@ int lvdisplay_full(struct cmd_context *cmd,
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 +493,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 +525,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))

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,13 +234,13 @@ 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 stat info;
char path[PATH_MAX];
char file[PATH_MAX];
dev_t dev = { 0 };
int r = 1;
@@ -194,31 +260,22 @@ 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))
@@ -229,7 +286,7 @@ static int _read_devs(struct dev_set *ds, const char *dir)
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;
}

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

@@ -415,19 +415,19 @@ 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;
}
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 +480,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;

View File

@@ -556,7 +556,8 @@ struct format_type *init_format(struct cmd_context *cmd)
fmt->ops = &_format1_ops;
fmt->name = FMT_LVM1_NAME;
fmt->alias = NULL;
fmt->features = FMT_RESTRICTED_LVIDS | FMT_ORPHAN_ALLOCATABLE;
fmt->features = FMT_RESTRICTED_LVIDS | FMT_ORPHAN_ALLOCATABLE |
FMT_RESTRICTED_READAHEAD;
fmt->private = NULL;
if (!(fmt->labeller = lvm1_labeller_create(fmt))) {

View File

@@ -25,6 +25,7 @@
#include "segtype.h"
#include "pv_alloc.h"
#include "display.h"
#include "lvmcache.h"
#include <time.h>
@@ -59,8 +60,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 = ORPHAN;
else if (!(pv->vg_name = dm_pool_strdup(mem, (char *)pvd->vg_name))) {
log_error("Volume Group name allocation failed.");
return 0;
}
@@ -74,7 +77,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,22 +95,22 @@ 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));
}
}
@@ -346,7 +349,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;
@@ -383,7 +390,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 =
@@ -644,7 +656,7 @@ int import_snapshots(struct dm_pool *mem __attribute((unused)), struct volume_gr
continue;
/* insert the snapshot */
if (!vg_add_snapshot(vg->fid, NULL, org, cow, NULL,
if (!vg_add_snapshot(NULL, org, cow, NULL,
org->le_count,
lvd->lv_chunk_size)) {
log_err("Couldn't add snapshot.");

View File

@@ -139,7 +139,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 +160,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

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

@@ -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,7 +78,7 @@ 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);

View File

@@ -307,19 +307,19 @@ int backup_restore_vg(struct cmd_context *cmd, struct volume_group *vg)
pv = pvl->pv;
if (!(info = info_from_pvid(pv->dev->pvid))) {
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;
}
}

View File

@@ -20,6 +20,7 @@
#include "lvm-string.h"
#include "segtype.h"
#include "text_export.h"
#include "version.h"
#include <stdarg.h>
#include <time.h>
@@ -270,6 +271,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.
*/
@@ -290,7 +304,7 @@ static int _print_header(struct formatter *f,
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);
@@ -360,7 +374,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)
@@ -391,7 +405,7 @@ static int _print_pvs(struct formatter *f, struct volume_group *vg)
}
outf(f, "id = \"%s\"", buffer);
if (!out_hint(f, "device = \"%s\"", dev_name(pv->dev))) {
if (!out_hint(f, "device = \"%s\"", pv_dev_name(pv))) {
stack;
return 0;
}
@@ -545,8 +559,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)
@@ -636,7 +659,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;
}

View File

@@ -83,6 +83,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
*/
@@ -1043,7 +1050,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,6 +1060,10 @@ 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 (mda_free_sectors)
*mda_free_sectors = ((dev_area->size - MDA_HEADER_SIZE) / 2) >> SECTOR_SHIFT;
if (!dev_open(dev_area->dev)) {
stack;
@@ -1114,9 +1126,21 @@ const char *vgname_from_mda(const struct format_type *fmt,
}
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,7 +1167,7 @@ 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);
@@ -1183,7 +1207,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;
}
@@ -1204,7 +1228,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;
@@ -1438,7 +1462,8 @@ static int _text_pv_read(const struct format_type *fmt, const char *pv_name,
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;
@@ -1449,7 +1474,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)) {
@@ -1556,6 +1581,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,
};
@@ -1647,7 +1673,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;
}

View File

@@ -57,6 +57,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

@@ -202,7 +202,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;
}
@@ -215,22 +215,22 @@ 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) {
/* 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.", 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) "
log_verbose("Fixing up missing size (%s) "
"for PV %s", display_size(fid->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));
}
}
@@ -523,9 +523,21 @@ static int _read_lvnames(struct format_instance *fid __attribute((unused)),
}
}
/* 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 -1:
lv->read_ahead = DM_READ_AHEAD_NONE;
break;
default:
;
}
}
lv->snapshot = NULL;
list_init(&lv->snapshot_segs);

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

@@ -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);
@@ -239,7 +240,8 @@ 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)) &&
&vgid, &vgstatus, &creation_host,
&mdac->free_sectors)) &&
!lvmcache_update_vgname_and_id(info, vgname,
(char *) &vgid, vgstatus,
creation_host))

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

@@ -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, uint32_t flags, char *name)
static int _lock_for_cluster(unsigned char cmd, uint32_t flags, const char *name)
{
int status;
int i;
@@ -378,6 +378,8 @@ int lock_resource(struct cmd_context *cmd, const char *resource, uint32_t flags)
{
char lockname[PATH_MAX];
int cluster_cmd = 0;
const char *lock_scope;
const char *lock_type = "";
assert(strlen(resource) < sizeof(lockname));
assert(resource);
@@ -393,6 +395,7 @@ int lock_resource(struct cmd_context *cmd, const char *resource, uint32_t flags)
dm_snprintf(lockname, sizeof(lockname), "V_%s",
resource);
lock_scope = "VG";
cluster_cmd = CLVMD_CMD_LOCK_VG;
flags &= LCK_TYPE_MASK;
break;
@@ -400,6 +403,7 @@ int lock_resource(struct cmd_context *cmd, const char *resource, uint32_t flags)
case LCK_LV:
cluster_cmd = CLVMD_CMD_LOCK_LV;
strcpy(lockname, resource);
lock_scope = "LV";
flags &= 0xffdf; /* Mask off HOLD flag */
break;
@@ -409,9 +413,46 @@ int lock_resource(struct cmd_context *cmd, const char *resource, uint32_t flags)
return 0;
}
/* Send a message to the cluster manager */
log_very_verbose("Locking %s at 0x%x", lockname, flags);
switch(flags & LCK_TYPE_MASK) {
case LCK_UNLOCK:
lock_type = "UN";
break;
case LCK_NULL:
lock_type = "NL";
break;
case LCK_READ:
lock_type = "CR";
break;
case LCK_PREAD:
lock_type = "PR";
break;
case LCK_WRITE:
lock_type = "PW";
break;
case LCK_EXCL:
lock_type = "EX";
break;
default:
log_error("Unrecognised lock type: %u",
flags & LCK_TYPE_MASK);
return 0;
}
/* If we are unlocking a VG, then trigger remote metadata backups */
if (cluster_cmd == CLVMD_CMD_LOCK_VG && ((flags & LCK_TYPE_MASK) == LCK_UNLOCK)) {
log_very_verbose("Requesing backup of VG metadata for %s", resource);
_lock_for_cluster(CLVMD_CMD_VG_BACKUP, LCK_CLUSTER_VG, resource);
}
log_very_verbose("Locking %s %s %s %s%s%s%s (0x%x)", lock_scope, lockname,
lock_type,
flags & LCK_NONBLOCK ? "" : "B",
flags & LCK_HOLD ? "H" : "",
flags & LCK_LOCAL ? "L" : "",
flags & LCK_CLUSTER_VG ? "C" : "",
flags);
/* Send a message to the cluster manager */
return _lock_for_cluster(cluster_cmd, flags, lockname);
}

View File

@@ -208,8 +208,6 @@ static int _file_lock_resource(struct cmd_context *cmd, const char *resource,
{
char lockfile[PATH_MAX];
assert(resource);
switch (flags & LCK_SCOPE_MASK) {
case LCK_VG:
if (!*resource) /* FIXME Deprecated */
@@ -238,27 +236,30 @@ static int _file_lock_resource(struct cmd_context *cmd, const char *resource,
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

@@ -288,7 +288,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,
@@ -318,6 +318,8 @@ static int _lock_vol(struct cmd_context *cmd, const char *resource, uint32_t fla
_block_signals(flags);
_lock_memory(flags);
assert(resource);
if (!(_locking.lock_resource(cmd, resource, flags))) {
_unlock_memory(flags);
_unblock_signals();
@@ -335,6 +337,11 @@ 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. */

View File

@@ -86,6 +86,8 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
/*
* 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)

View File

@@ -48,8 +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,
struct list *allocatable_pvs,
alloc_policy_t alloc,
struct list *parallel_areas);

View File

@@ -414,8 +414,6 @@ struct alloc_handle {
uint32_t log_count; /* Number of parallel 1-extent logs */
uint32_t total_area_len; /* Total number of parallel extents */
struct physical_volume *mirrored_pv; /* FIXME Remove this */
uint32_t mirrored_pe; /* FIXME Remove this */
struct list *parallel_areas; /* PVs to avoid */
struct alloced_area log_area; /* Extent used for log */
@@ -441,8 +439,6 @@ static struct alloc_handle *_alloc_init(struct cmd_context *cmd,
uint32_t mirrors,
uint32_t stripes,
uint32_t log_count,
struct physical_volume *mirrored_pv,
uint32_t mirrored_pe,
struct list *parallel_areas)
{
struct alloc_handle *ah;
@@ -453,15 +449,8 @@ static struct alloc_handle *_alloc_init(struct cmd_context *cmd,
return NULL;
}
if ((stripes > 1 || mirrors > 1) && mirrored_pv) {
log_error("Can't mix striping or mirroring with "
"creation of a mirrored PV yet");
return NULL;
}
if (log_count && (stripes > 1 || mirrored_pv)) {
log_error("Can't mix striping or pvmove with "
"a mirror log yet.");
if (log_count && stripes > 1) {
log_error("Can't mix striping with a mirror log yet.");
return NULL;
}
@@ -469,8 +458,6 @@ static struct alloc_handle *_alloc_init(struct cmd_context *cmd,
area_count = 0;
else if (mirrors > 1)
area_count = mirrors;
else if (mirrored_pv)
area_count = 1;
else
area_count = stripes;
@@ -497,8 +484,6 @@ static struct alloc_handle *_alloc_init(struct cmd_context *cmd,
for (s = 0; s < ah->area_count; s++)
list_init(&ah->alloced_areas[s]);
ah->mirrored_pv = mirrored_pv;
ah->mirrored_pe = mirrored_pe;
ah->parallel_areas = parallel_areas;
return ah;
@@ -526,7 +511,7 @@ static int _log_parallel_areas(struct dm_pool *mem, struct list *parallel_areas)
list_iterate_items(spvs, parallel_areas) {
list_iterate_items(pvl, &spvs->pvs) {
if (!dm_pool_grow_object(mem, dev_name(pvl->pv->dev), strlen(dev_name(pvl->pv->dev)))) {
if (!dm_pool_grow_object(mem, pv_dev_name(pvl->pv), strlen(pv_dev_name(pvl->pv)))) {
log_error("dm_pool_grow_object failed");
dm_pool_abandon_object(mem);
return 0;
@@ -1087,7 +1072,7 @@ static int _allocate(struct alloc_handle *ah,
return 1;
}
if (ah->mirrored_pv || (ah->alloc == ALLOC_CONTIGUOUS))
if (ah->alloc == ALLOC_CONTIGUOUS)
can_split = 0;
if (lv && !list_empty(&lv->segments))
@@ -1193,8 +1178,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,
struct list *allocatable_pvs,
alloc_policy_t alloc,
struct list *parallel_areas)
@@ -1220,11 +1203,8 @@ struct alloc_handle *allocate_extents(struct volume_group *vg,
alloc = vg->alloc;
if (!(ah = _alloc_init(vg->cmd, vg->cmd->mem, segtype, alloc, mirrors,
stripes, log_count, mirrored_pv,
mirrored_pe, parallel_areas))) {
stack;
return NULL;
}
stripes, log_count, parallel_areas)))
return_NULL;
if (!segtype_is_virtual(segtype) &&
!_allocate(ah, vg, lv, (lv ? lv->le_count : 0) + extents,
@@ -1427,12 +1407,13 @@ int lv_extend(struct logical_volume *lv,
if (segtype_is_virtual(segtype))
return lv_add_virtual_segment(lv, status, extents, segtype);
/* FIXME Temporary restriction during code reorganisation */
if (mirrored_pv)
alloc = ALLOC_CONTIGUOUS;
if (!(ah = allocate_extents(lv->vg, lv, segtype, stripes, mirrors, 0,
extents, mirrored_pv, mirrored_pe,
allocatable_pvs, alloc, NULL))) {
stack;
return 0;
}
extents, allocatable_pvs, alloc, NULL)))
return_0;
if (mirrors < 2) {
if (!lv_add_segment(ah, 0, ah->area_count, lv, segtype, stripe_size,
@@ -1656,14 +1637,14 @@ char *generate_lv_name(struct volume_group *vg, const char *format,
/*
* Create a new empty LV.
*/
struct logical_volume *lv_create_empty(struct format_instance *fi,
const char *name,
struct logical_volume *lv_create_empty(const char *name,
union lvid *lvid,
uint32_t status,
alloc_policy_t alloc,
int import,
struct volume_group *vg)
{
struct format_instance *fi = vg->fid;
struct cmd_context *cmd = vg->cmd;
struct lv_list *ll = NULL;
struct logical_volume *lv;
@@ -1705,7 +1686,7 @@ struct logical_volume *lv_create_empty(struct format_instance *fi,
lv->status = status;
lv->alloc = alloc;
lv->read_ahead = 0;
lv->read_ahead = vg->cmd->default_settings.read_ahead;
lv->major = -1;
lv->minor = -1;
lv->size = UINT64_C(0);
@@ -1803,7 +1784,7 @@ struct list *build_parallel_areas_from_lv(struct cmd_context *cmd,
}
int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv,
force_t force)
const force_t force)
{
struct volume_group *vg;
struct lvinfo info;
@@ -1839,37 +1820,41 @@ int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv,
/* FIXME Ensure not referred to by another existing LVs */
if (lv_info(cmd, lv, &info, 1)) {
if (lv_info(cmd, lv, &info, 1, 0)) {
if (info.open_count) {
log_error("Can't remove open logical volume \"%s\"",
lv->name);
return 0;
}
if (info.exists && (force == PROMPT)) {
if (yes_no_prompt("Do you really want to remove active "
"logical volume \"%s\"? [y/n]: ",
/*
* Check for confirmation prompts in the following cases:
* 1) Clustered VG, and some remote nodes have the LV active
* 2) Non-clustered VG, but LV active locally
*/
if ((vg_status(vg) & CLUSTERED) && !activate_lv_excl(cmd, lv) &&
(force == PROMPT)) {
if (yes_no_prompt("Logical volume \"%s\" is active on other "
"cluster nodes. Really remove? [y/n]: ",
lv->name) == 'n') {
log_print("Logical volume \"%s\" not removed",
lv->name);
return 0;
}
} else if (info.exists && (force == PROMPT)) {
if (yes_no_prompt("Do you really want to remove active "
"logical volume \"%s\"? [y/n]: ",
lv->name) == 'n') {
log_print("Logical volume \"%s\" not removed",
lv->name);
return 0;
}
}
}
if (!archive(vg))
return 0;
/* If the VG is clustered then make sure no-one else is using the LV
we are about to remove */
if (vg_status(vg) & CLUSTERED) {
if (!activate_lv_excl(cmd, lv)) {
log_error("Can't get exclusive access to volume \"%s\"",
lv->name);
return 0;
}
}
/* FIXME Snapshot commit out of sequence if it fails after here? */
if (!deactivate_lv(cmd, lv)) {
log_error("Unable to deactivate logical volume \"%s\"",

View File

@@ -119,6 +119,15 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
}
}
if (seg_is_snapshot(seg)) {
if (seg->cow && seg->cow == seg->origin) {
log_error("LV %s: segment %u has same LV %s for "
"both origin and snapshot",
lv->name, seg_count, seg->cow->name);
r = 0;
}
}
for (s = 0; s < seg->area_count; s++) {
if (seg_type(seg, s) == AREA_UNASSIGNED) {
log_error("LV %s: segment %u has unassigned "

View File

@@ -82,6 +82,7 @@ struct pv_segment;
//#define FMT_PRECOMMIT 0x00000040U /* Supports pre-commit? */
#define FMT_RESIZE_PV 0x00000080U /* Supports pvresize? */
#define FMT_UNLIMITED_STRIPESIZE 0x00000100U /* Unlimited stripe size? */
#define FMT_RESTRICTED_READAHEAD 0x00000200U /* Readahead restricted to 2-120? */
/* LVM2 external library flags */
#define CORRECT_INCONSISTENT 0x00000001U /* Correct inconsistent metadata */
@@ -304,8 +305,10 @@ struct list *get_vgids(struct cmd_context *cmd, int full_scan);
int pv_write(struct cmd_context *cmd, struct physical_volume *pv,
struct list *mdas, int64_t label_sector);
int is_orphan_vg(const char *vg_name);
int is_orphan(pv_t *pv);
vg_t *vg_lock_and_read(struct cmd_context *cmd, const char *vg_name,
const char *vgid,
uint32_t lock_flags, uint32_t status_flags,
uint32_t misc_flags);
@@ -325,6 +328,9 @@ int pv_resize(struct physical_volume *pv, struct volume_group *vg,
int pv_analyze(struct cmd_context *cmd, const char *pv_name,
uint64_t label_sector);
/* FIXME: move internal to library */
uint32_t pv_list_extents_free(const struct list *pvh);
struct volume_group *vg_create(struct cmd_context *cmd, const char *name,
uint32_t extent_size, uint32_t max_pv,
uint32_t max_lv, alloc_policy_t alloc,
@@ -342,8 +348,7 @@ int vg_split_mdas(struct cmd_context *cmd, struct volume_group *vg_from,
struct volume_group *vg_to);
/* Manipulate LVs */
struct logical_volume *lv_create_empty(struct format_instance *fi,
const char *name,
struct logical_volume *lv_create_empty(const char *name,
union lvid *lvid,
uint32_t status,
alloc_policy_t alloc,
@@ -405,7 +410,7 @@ struct lv_segment *find_cow(const struct logical_volume *lv);
/* Given a cow LV, return its origin */
struct logical_volume *origin_from_cow(const struct logical_volume *lv);
int vg_add_snapshot(struct format_instance *fid, const char *name,
int vg_add_snapshot(const char *name,
struct logical_volume *origin, struct logical_volume *cow,
union lvid *lvid, uint32_t extent_count,
uint32_t chunk_size);
@@ -462,15 +467,16 @@ char *generate_lv_name(struct volume_group *vg, const char *format,
/*
* Begin skeleton for external LVM library
*/
struct device *pv_dev(pv_t *pv);
const char *pv_vg_name(pv_t *pv);
uint64_t pv_size(pv_t *pv);
uint32_t pv_status(pv_t *pv);
uint32_t pv_pe_size(pv_t *pv);
uint64_t pv_pe_start(pv_t *pv);
uint32_t pv_pe_count(pv_t *pv);
uint32_t pv_pe_alloc_count(pv_t *pv);
struct device *pv_dev(const pv_t *pv);
const char *pv_vg_name(const pv_t *pv);
const char *pv_dev_name(const pv_t *pv);
uint64_t pv_size(const pv_t *pv);
uint32_t pv_status(const pv_t *pv);
uint32_t pv_pe_size(const pv_t *pv);
uint64_t pv_pe_start(const pv_t *pv);
uint32_t pv_pe_count(const pv_t *pv);
uint32_t pv_pe_alloc_count(const pv_t *pv);
uint32_t vg_status(vg_t *vg);
uint32_t vg_status(const vg_t *vg);
#endif

View File

@@ -33,7 +33,7 @@
* FIXME: Check for valid handle before dereferencing field or log error?
*/
#define pv_field(handle, field) \
(((struct physical_volume *)(handle))->field)
(((const struct physical_volume *)(handle))->field)
static struct physical_volume *_pv_read(struct cmd_context *cmd,
const char *pv_name,
@@ -93,7 +93,7 @@ int add_pv_to_vg(struct volume_group *vg, const char *pv_name,
return 0;
}
if (*pv->vg_name) {
if (!is_orphan_vg(pv->vg_name)) {
log_error("Physical volume '%s' is already in volume group "
"'%s'", pv_name, pv->vg_name);
return 0;
@@ -241,7 +241,7 @@ int vg_rename(struct cmd_context *cmd, struct volume_group *vg,
list_iterate_items(pvl, &vg->pvs) {
if (!(pvl->pv->vg_name = dm_pool_strdup(mem, new_name))) {
log_error("pv->vg_name allocation failed for '%s'",
dev_name(pvl->pv->dev));
pv_dev_name(pvl->pv));
return 0;
}
}
@@ -249,6 +249,20 @@ int vg_rename(struct cmd_context *cmd, struct volume_group *vg,
return 1;
}
static int remove_lvs_in_vg(struct cmd_context *cmd,
struct volume_group *vg,
force_t force)
{
struct lv_list *lvl;
list_iterate_items(lvl, &vg->lvs)
if (!lv_remove_single(cmd, lvl->lv, force))
return 0;
return 1;
}
/* FIXME: remove redundant vg_name */
int vg_remove_single(struct cmd_context *cmd, const char *vg_name,
struct volume_group *vg, int consistent,
force_t force __attribute((unused)))
@@ -268,6 +282,19 @@ int vg_remove_single(struct cmd_context *cmd, const char *vg_name,
if (!vg_check_status(vg, EXPORTED_VG))
return 0;
if (vg->lv_count) {
if ((force == PROMPT) &&
(yes_no_prompt("Do you really want to remove volume "
"group \"%s\" containing %d "
"logical volumes? [y/n]: ",
vg_name, vg->lv_count) == 'n')) {
log_print("Volume group \"%s\" not removed", vg_name);
return 0;
}
if (!remove_lvs_in_vg(cmd, vg, force))
return 0;
}
if (vg->lv_count) {
log_error("Volume group \"%s\" still contains %d "
"logical volume(s)", vg_name, vg->lv_count);
@@ -286,12 +313,12 @@ int vg_remove_single(struct cmd_context *cmd, const char *vg_name,
list_iterate_items(pvl, &vg->pvs) {
pv = pvl->pv;
log_verbose("Removing physical volume \"%s\" from "
"volume group \"%s\"", dev_name(pv_dev(pv)), vg_name);
"volume group \"%s\"", pv_dev_name(pv), vg_name);
pv->vg_name = ORPHAN;
pv->status = ALLOCATABLE_PV;
if (!dev_get_size(pv_dev(pv), &pv->size)) {
log_error("%s: Couldn't get size.", dev_name(pv_dev(pv)));
log_error("%s: Couldn't get size.", pv_dev_name(pv));
ret = 0;
continue;
}
@@ -300,7 +327,7 @@ int vg_remove_single(struct cmd_context *cmd, const char *vg_name,
if (!pv_write(cmd, pv, NULL, INT64_C(-1))) {
log_error("Failed to remove physical volume \"%s\""
" from volume group \"%s\"",
dev_name(pv_dev(pv)), vg_name);
pv_dev_name(pv), vg_name);
ret = 0;
}
}
@@ -503,13 +530,13 @@ int vg_change_pesize(struct cmd_context *cmd __attribute((unused)),
pv = pvl->pv;
pv->pe_size = new_size;
if (!_recalc_extents(&pv->pe_count, dev_name(pv->dev), "",
if (!_recalc_extents(&pv->pe_count, pv_dev_name(pv), "",
old_size, new_size)) {
stack;
return 0;
}
if (!_recalc_extents(&pv->pe_alloc_count, dev_name(pv->dev),
if (!_recalc_extents(&pv->pe_alloc_count, pv_dev_name(pv),
" allocated space", old_size, new_size)) {
stack;
return 0;
@@ -520,13 +547,13 @@ int vg_change_pesize(struct cmd_context *cmd __attribute((unused)),
if (pvseg->lvseg)
continue;
if (!_recalc_extents(&pvseg->pe, dev_name(pv->dev),
if (!_recalc_extents(&pvseg->pe, pv_dev_name(pv),
" PV segment start", old_size,
new_size)) {
stack;
return 0;
}
if (!_recalc_extents(&pvseg->len, dev_name(pv->dev),
if (!_recalc_extents(&pvseg->len, pv_dev_name(pv),
" PV segment length", old_size,
new_size)) {
stack;
@@ -681,6 +708,39 @@ pv_t *pv_create(const struct format_type *fmt,
pvmetadatasize, mdas);
}
static void _free_pv(struct dm_pool *mem, struct physical_volume *pv)
{
dm_pool_free(mem, pv);
}
static struct physical_volume *_alloc_pv(struct dm_pool *mem)
{
struct physical_volume *pv = dm_pool_zalloc(mem, sizeof(*pv));
if (!pv) {
stack;
return NULL;
}
if (!(pv->vg_name = dm_pool_zalloc(mem, NAME_LEN))) {
dm_pool_free(mem, pv);
return NULL;
}
pv->pe_size = 0;
pv->pe_start = 0;
pv->pe_count = 0;
pv->pe_alloc_count = 0;
pv->fmt = NULL;
pv->status = ALLOCATABLE_PV;
list_init(&pv->tags);
list_init(&pv->segments);
return pv;
}
/* Sizes in sectors */
static struct physical_volume *_pv_create(const struct format_type *fmt,
struct device *dev,
@@ -692,69 +752,55 @@ static struct physical_volume *_pv_create(const struct format_type *fmt,
uint64_t pvmetadatasize, struct list *mdas)
{
struct dm_pool *mem = fmt->cmd->mem;
struct physical_volume *pv = dm_pool_zalloc(mem, sizeof(*pv));
struct physical_volume *pv = _alloc_pv(mem);
if (!pv) {
stack;
if (!pv)
return NULL;
}
if (id)
memcpy(&pv->id, id, sizeof(*id));
else if (!id_create(&pv->id)) {
log_error("Failed to create random uuid for %s.",
dev_name(dev));
return NULL;
goto bad;
}
pv->dev = dev;
if (!(pv->vg_name = dm_pool_zalloc(mem, NAME_LEN)))
goto_bad;
pv->status = ALLOCATABLE_PV;
if (!dev_get_size(pv->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));
goto bad;
}
if (size) {
if (size > pv->size)
log_warn("WARNING: %s: Overriding real size. "
"You could lose data.", dev_name(pv->dev));
"You could lose data.", pv_dev_name(pv));
log_verbose("%s: Pretending size is %" PRIu64 " sectors.",
dev_name(pv->dev), size);
pv_dev_name(pv), size);
pv->size = size;
}
if (pv->size < PV_MIN_SIZE) {
log_error("%s: Size must exceed minimum of %ld sectors.",
dev_name(pv->dev), PV_MIN_SIZE);
pv_dev_name(pv), PV_MIN_SIZE);
goto bad;
}
pv->pe_size = 0;
pv->pe_start = 0;
pv->pe_count = 0;
pv->pe_alloc_count = 0;
pv->fmt = fmt;
list_init(&pv->tags);
list_init(&pv->segments);
if (!fmt->ops->pv_setup(fmt, pe_start, existing_extent_count,
existing_extent_size,
pvmetadatacopies, pvmetadatasize, mdas,
pv, NULL)) {
log_error("%s: Format-specific setup of physical volume "
"failed.", dev_name(pv->dev));
"failed.", pv_dev_name(pv));
goto bad;
}
return pv;
bad:
dm_pool_free(mem, pv);
_free_pv(mem, pv);
return NULL;
}
@@ -881,7 +927,8 @@ static struct physical_volume *_find_pv_by_name(struct cmd_context *cmd,
return NULL;
}
if (!pv->vg_name[0]) {
/* FIXME Can fail when no PV mda */
if (is_orphan_vg(pv->vg_name)) {
log_error("Physical volume %s not in a volume group", pv_name);
return NULL;
}
@@ -960,7 +1007,7 @@ int vg_validate(struct volume_group *vg)
stack;
log_error("Internal error: Duplicate PV id "
"%s detected for %s in %s.",
uuid, dev_name(pvl->pv->dev),
uuid, pv_dev_name(pvl->pv),
vg->name);
r = 0;
}
@@ -968,7 +1015,7 @@ int vg_validate(struct volume_group *vg)
if (strcmp(pvl->pv->vg_name, vg->name)) {
log_error("Internal error: VG name for PV %s is corrupted",
dev_name(pvl->pv->dev));
pv_dev_name(pvl->pv));
r = 0;
}
}
@@ -1187,7 +1234,7 @@ static int _update_pv_list(struct list *all_pvs, struct volume_group *vg)
/* PV is not on list so add it. Note that we don't copy it. */
if (!(pvl2 = dm_pool_zalloc(vg->cmd->mem, sizeof(*pvl2)))) {
log_error("pv_list allocation for '%s' failed",
dev_name(pvl->pv->dev));
pv_dev_name(pvl->pv));
return 0;
}
pvl2->pv = pvl->pv;
@@ -1225,7 +1272,7 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
struct list all_pvs;
char uuid[64] __attribute((aligned(8)));
if (!*vgname) {
if (is_orphan_vg(vgname)) {
if (use_precommitted) {
log_error("Internal error: vg_read requires vgname "
"with pre-commit.");
@@ -1426,7 +1473,7 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
if (!id_write_format(&pvl->pv->id, uuid, sizeof(uuid)))
return_NULL;
log_error("Removing PV %s (%s) that no longer belongs to VG %s",
dev_name(pvl->pv->dev), uuid, correct_vg->name);
pv_dev_name(pvl->pv), uuid, correct_vg->name);
if (!pv_write_orphan(cmd, pvl->pv))
return_NULL;
next_pv:
@@ -1489,7 +1536,7 @@ static struct volume_group *_vg_read_by_vgid(struct cmd_context *cmd,
/* Is corresponding vgname already cached? */
if ((vginfo = vginfo_from_vgid(vgid)) &&
vginfo->vgname && *vginfo->vgname) {
vginfo->vgname && !is_orphan_vg(vginfo->vgname)) {
if ((vg = _vg_read(cmd, vginfo->vgname, vgid,
&consistent, precommitted)) &&
!strncmp((char *)vg->id.uuid, vgid, ID_LEN)) {
@@ -1519,7 +1566,7 @@ static struct volume_group *_vg_read_by_vgid(struct cmd_context *cmd,
list_iterate_items(strl, vgnames) {
vgname = strl->str;
if (!vgname || !*vgname)
if (!vgname || is_orphan_vg(vgname))
continue; // FIXME Unnecessary?
consistent = 0;
if ((vg = _vg_read(cmd, vgname, vgid, &consistent,
@@ -1731,7 +1778,7 @@ static int _pv_write(struct cmd_context *cmd __attribute((unused)),
return 0;
}
if (*pv->vg_name || pv->pe_alloc_count) {
if (!is_orphan_vg(pv->vg_name) || pv->pe_alloc_count) {
log_error("Assertion failed: can't _pv_write non-orphan PV "
"(in VG %s)", pv->vg_name);
return 0;
@@ -1753,30 +1800,38 @@ int pv_write_orphan(struct cmd_context *cmd, struct physical_volume *pv)
pv->status = ALLOCATABLE_PV;
if (!dev_get_size(pv->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;
}
if (!_pv_write(cmd, pv, NULL, INT64_C(-1))) {
log_error("Failed to clear metadata from physical "
"volume \"%s\" after removal from \"%s\"",
dev_name(pv->dev), old_vg_name);
pv_dev_name(pv), old_vg_name);
return 0;
}
return 1;
}
/**
* is_orphan_vg - Determine whether a vg_name is an orphan
* @vg_name: pointer to the vg_name
*/
int is_orphan_vg(const char *vg_name)
{
return (!strcmp(vg_name, ORPHAN) ? 1 : 0);
}
/**
* is_orphan - Determine whether a pv is an orphan based on its vg_name
* @pv: handle to the physical volume
*/
int is_orphan(pv_t *pv)
{
return (pv_field(pv, vg_name)[0] ? 0 : 1);
return is_orphan_vg(pv_field(pv, vg_name));
}
/*
* Returns:
* 0 - fail
@@ -1867,6 +1922,7 @@ int vg_check_status(const struct volume_group *vg, uint32_t status)
* non-NULL - success; volume group handle
*/
vg_t *vg_lock_and_read(struct cmd_context *cmd, const char *vg_name,
const char *vgid,
uint32_t lock_flags, uint32_t status_flags,
uint32_t misc_flags)
{
@@ -1876,12 +1932,18 @@ vg_t *vg_lock_and_read(struct cmd_context *cmd, const char *vg_name,
if (!(misc_flags & CORRECT_INCONSISTENT))
consistent = 0;
if (!validate_name(vg_name)) {
log_error("Volume group name %s has invalid characters",
vg_name);
return NULL;
}
if (!lock_vol(cmd, vg_name, lock_flags)) {
log_error("Can't get lock for %s", vg_name);
return NULL;
}
if (!(vg = vg_read(cmd, vg_name, NULL, &consistent)) ||
if (!(vg = vg_read(cmd, vg_name, vgid, &consistent)) ||
((misc_flags & FAIL_INCONSISTENT) && !consistent)) {
log_error("Volume group \"%s\" not found", vg_name);
unlock_vg(cmd, vg_name);
@@ -1892,69 +1954,74 @@ vg_t *vg_lock_and_read(struct cmd_context *cmd, const char *vg_name,
unlock_vg(cmd, vg_name);
return NULL;
}
return vg;
}
/*
* Gets/Sets for external LVM library
*/
struct id pv_id(pv_t *pv)
struct id pv_id(const pv_t *pv)
{
return pv_field(pv, id);
}
const struct format_type *pv_format_type(pv_t *pv)
const struct format_type *pv_format_type(const pv_t *pv)
{
return pv_field(pv, fmt);
}
struct id pv_vgid(pv_t *pv)
struct id pv_vgid(const pv_t *pv)
{
return pv_field(pv, vgid);
}
struct device *pv_dev(pv_t *pv)
struct device *pv_dev(const pv_t *pv)
{
return pv_field(pv, dev);
}
const char *pv_vg_name(pv_t *pv)
const char *pv_vg_name(const pv_t *pv)
{
return pv_field(pv, vg_name);
}
uint64_t pv_size(pv_t *pv)
const char *pv_dev_name(const pv_t *pv)
{
return dev_name(pv_dev(pv));
}
uint64_t pv_size(const pv_t *pv)
{
return pv_field(pv, size);
}
uint32_t pv_status(pv_t *pv)
uint32_t pv_status(const pv_t *pv)
{
return pv_field(pv, status);
}
uint32_t pv_pe_size(pv_t *pv)
uint32_t pv_pe_size(const pv_t *pv)
{
return pv_field(pv, pe_size);
}
uint64_t pv_pe_start(pv_t *pv)
uint64_t pv_pe_start(const pv_t *pv)
{
return pv_field(pv, pe_start);
}
uint32_t pv_pe_count(pv_t *pv)
uint32_t pv_pe_count(const pv_t *pv)
{
return pv_field(pv, pe_count);
}
uint32_t pv_pe_alloc_count(pv_t *pv)
uint32_t pv_pe_alloc_count(const pv_t *pv)
{
return pv_field(pv, pe_alloc_count);
}
uint32_t vg_status(vg_t *vg)
uint32_t vg_status(const vg_t *vg)
{
return vg->status;
}

View File

@@ -113,6 +113,12 @@ struct metadata_area_ops {
struct volume_group * vg, struct metadata_area * mda);
int (*vg_remove) (struct format_instance * fi, struct volume_group * vg,
struct metadata_area * mda);
/*
* Returns number of free sectors in given metadata area.
*/
uint64_t (*mda_free_sectors) (struct metadata_area *mda);
/*
* Check if metadata area belongs to vg
*/
@@ -180,7 +186,7 @@ struct format_handler {
/*
* Write a PV structure to disk. Fails if the PV is in a VG ie
* pv->vg_name must be null.
* pv->vg_name must be a valid orphan VG name
*/
int (*pv_write) (const struct format_type * fmt,
struct physical_volume * pv, struct list * mdas,
@@ -304,9 +310,9 @@ int fixup_imported_mirrors(struct volume_group *vg);
/*
* Begin skeleton for external LVM library
*/
struct id pv_id(pv_t *pv);
const struct format_type *pv_format_type(pv_t *pv);
struct id pv_vgid(pv_t *pv);
struct id pv_id(const pv_t *pv);
const struct format_type *pv_format_type(const pv_t *pv);
struct id pv_vgid(const pv_t *pv);
pv_t *pv_by_path(struct cmd_context *cmd, const char *pv_name);
int add_pv_to_vg(struct volume_group *vg, const char *pv_name,

View File

@@ -198,6 +198,7 @@ int remove_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors,
extents = lv1->le_count;
_move_lv_segments(mirrored_seg->lv, lv1);
mirrored_seg->lv->status &= ~MIRRORED;
mirrored_seg->lv->status &= ~MIRROR_NOTSYNCED;
remove_log = 1;
/* Replace mirror with error segment */
segtype = get_segtype_from_string(mirrored_seg->lv->vg->cmd, "error");
@@ -438,7 +439,7 @@ static int _create_layers_for_mirror(struct alloc_handle *ah,
}
for (m = 0; m < num_mirrors; m++) {
if (!(img_lvs[m] = lv_create_empty(lv->vg->fid, img_name,
if (!(img_lvs[m] = lv_create_empty(img_name,
NULL, LVM_READ | LVM_WRITE,
ALLOC_INHERIT, 0, lv->vg))) {
log_error("Aborting. Failed to create mirror image LV. "
@@ -531,6 +532,37 @@ int add_mirror_layers(struct alloc_handle *ah,
return lv_add_more_mirrored_areas(lv, img_lvs, num_mirrors, 0);
}
static int _alloc_and_insert_pvmove_seg(struct logical_volume *lv_mirr,
struct lv_segment *seg, uint32_t s,
struct list *allocatable_pvs,
alloc_policy_t alloc,
const struct segment_type *segtype)
{
struct physical_volume *pv = seg_pv(seg, s);
uint32_t start_le = lv_mirr->le_count;
uint32_t pe = seg_pe(seg, s);
log_very_verbose("Moving %s:%u-%u of %s/%s", pv_dev_name(pv),
pe, pe + seg->area_len - 1,
seg->lv->vg->name, seg->lv->name);
release_lv_segment_area(seg, s, seg->area_len);
if (!lv_extend(lv_mirr, segtype, 1,
seg->area_len, 0u, seg->area_len,
pv, pe,
PVMOVE, allocatable_pvs,
alloc)) {
log_error("Unable to allocate "
"temporary LV for pvmove.");
return 0;
}
set_lv_segment_area_lv(seg, s, lv_mirr, start_le, 0);
return 1;
}
/*
* Replace any LV segments on given PV with temporary mirror.
* Returns list of LVs changed.
@@ -546,10 +578,8 @@ int insert_pvmove_mirrors(struct cmd_context *cmd,
struct lv_segment *seg;
struct lv_list *lvl;
struct pv_list *pvl;
struct physical_volume *pv;
uint32_t pe;
int lv_used = 0;
uint32_t s, start_le, extent_count = 0u;
uint32_t s, extent_count = 0u;
const struct segment_type *segtype;
struct pe_range *per;
uint32_t pe_start, pe_end, per_end, stripe_multiplier;
@@ -647,27 +677,11 @@ int insert_pvmove_mirrors(struct cmd_context *cmd,
lv_used = 1;
}
pv = seg_pv(seg, s);
pe = seg_pe(seg, s);
log_very_verbose("Moving %s:%u-%u of %s/%s",
dev_name(pvl->pv->dev),
pe, pe + seg->area_len - 1,
lv->vg->name, lv->name);
if (!_alloc_and_insert_pvmove_seg(lv_mirr, seg, s,
allocatable_pvs,
alloc, segtype))
return_0;
start_le = lv_mirr->le_count;
/* FIXME Clean this up */
release_lv_segment_area(seg, s, seg->area_len);
if (!lv_extend(lv_mirr, segtype, 1,
seg->area_len, 0u, seg->area_len,
pv, pe,
PVMOVE, allocatable_pvs,
alloc)) {
log_error("Unable to allocate "
"temporary LV for pvmove.");
return 0;
}
set_lv_segment_area_lv(seg, s, lv_mirr, start_le, 0);
extent_count += seg->area_len;
lv->status |= LOCKED;

View File

@@ -17,6 +17,9 @@
#include "metadata.h"
#include "pv_alloc.h"
#include "toolcontext.h"
#include "archiver.h"
#include "locking.h"
#include "lvmcache.h"
static struct pv_segment *_alloc_pv_segment(struct dm_pool *mem,
struct physical_volume *pv,
@@ -119,7 +122,7 @@ int pv_split_segment(struct physical_volume *pv, uint32_t pe)
if (!(peg = find_peg_by_pe(pv, pe))) {
log_error("Segment with extent %" PRIu32 " in PV %s not found",
pe, dev_name(pv->dev));
pe, pv_dev_name(pv));
return 0;
}
@@ -159,7 +162,7 @@ struct pv_segment *assign_peg_to_lvseg(struct physical_volume *pv,
if (!(peg = find_peg_by_pe(pv, pe))) {
log_error("Missing PV segment on %s at %u.",
dev_name(pv->dev), pe);
pv_dev_name(pv), pe);
return NULL;
}
@@ -176,7 +179,7 @@ int release_pv_segment(struct pv_segment *peg, uint32_t area_reduction)
{
if (!peg->lvseg) {
log_error("release_pv_segment with unallocated segment: "
"%s PE %" PRIu32, dev_name(peg->pv->dev), peg->pe);
"%s PE %" PRIu32, pv_dev_name(peg->pv), peg->pe);
return 0;
}
@@ -211,6 +214,46 @@ void merge_pv_segments(struct pv_segment *peg1, struct pv_segment *peg2)
list_del(&peg2->list);
}
/*
* Calculate the overlap, in extents, between a struct pv_segment and
* a struct pe_range.
*/
static uint32_t _overlap_pe(const struct pv_segment *pvseg,
const struct pe_range *per)
{
uint32_t start;
uint32_t end;
start = max(pvseg->pe, per->start);
end = min(pvseg->pe + pvseg->len, per->start + per->count);
if (end < start)
return 0;
else
return end - start;
}
/*
* Returns: number of free PEs in a struct pv_list
*/
uint32_t pv_list_extents_free(const struct list *pvh)
{
struct pv_list *pvl;
struct pe_range *per;
uint32_t extents = 0;
struct pv_segment *pvseg;
list_iterate_items(pvl, pvh) {
list_iterate_items(per, pvl->pe_ranges) {
list_iterate_items(pvseg, &pvl->pv->segments) {
if (!pvseg->lvseg) /* free space */
extents += _overlap_pe(pvseg, per);
}
}
}
return extents;
}
/*
* Check all pv_segments in VG for consistency
*/
@@ -236,7 +279,7 @@ int check_pv_segments(struct volume_group *vg)
/* FIXME Remove this next line eventually */
log_debug("%s %u: %6u %6u: %s(%u:%u)",
dev_name(pv->dev), segno++, peg->pe, peg->len,
pv_dev_name(pv), segno++, peg->pe, peg->len,
peg->lvseg ? peg->lvseg->lv->name : "NULL",
peg->lvseg ? peg->lvseg->le : 0, s);
/* FIXME Add details here on failure instead */
@@ -310,7 +353,7 @@ static int _reduce_pv(struct physical_volume *pv, struct volume_group *vg, uint3
if (new_pe_count < pv->pe_alloc_count) {
log_error("%s: cannot resize to %" PRIu32 " extents "
"as %" PRIu32 " are allocated.",
dev_name(pv->dev), new_pe_count,
pv_dev_name(pv), new_pe_count,
pv->pe_alloc_count);
return 0;
}
@@ -323,7 +366,7 @@ static int _reduce_pv(struct physical_volume *pv, struct volume_group *vg, uint3
if (peg->lvseg) {
log_error("%s: cannot resize to %" PRIu32 " extents as "
"later ones are allocated.",
dev_name(pv->dev), new_pe_count);
pv_dev_name(pv), new_pe_count);
return 0;
}
}
@@ -354,7 +397,7 @@ static int _extend_pv(struct physical_volume *pv, struct volume_group *vg,
if ((uint64_t) new_pe_count * pv->pe_size > pv->size ) {
log_error("%s: cannot resize to %" PRIu32 " extents as there "
"is only room for %" PRIu64 ".", dev_name(pv->dev),
"is only room for %" PRIu64 ".", pv_dev_name(pv),
new_pe_count, pv->size / pv->pe_size);
return 0;
}
@@ -383,13 +426,13 @@ int pv_resize(struct physical_volume *pv,
{
if ((new_pe_count == pv->pe_count)) {
log_verbose("No change to size of physical volume %s.",
dev_name(pv->dev));
pv_dev_name(pv));
return 1;
}
log_verbose("Resizing physical volume %s from %" PRIu32
" to %" PRIu32 " extents.",
dev_name(pv->dev), pv->pe_count, new_pe_count);
pv_dev_name(pv), pv->pe_count, new_pe_count);
if (new_pe_count > pv->pe_count)
return _extend_pv(pv, vg, new_pe_count);

View File

@@ -46,7 +46,7 @@ static int _create_single_area(struct dm_pool *mem, struct pv_map *pvm,
}
log_debug("Allowing allocation on %s start PE %" PRIu32 " length %"
PRIu32, dev_name(pvm->pv->dev), start, length);
PRIu32, pv_dev_name(pvm->pv), start, length);
pva->map = pvm;
pva->start = start;
pva->count = length;

View File

@@ -48,8 +48,7 @@ struct logical_volume *origin_from_cow(const struct logical_volume *lv)
return lv->snapshot->origin;
}
int vg_add_snapshot(struct format_instance *fid, const char *name,
struct logical_volume *origin,
int vg_add_snapshot(const char *name, struct logical_volume *origin,
struct logical_volume *cow, union lvid *lvid,
uint32_t extent_count, uint32_t chunk_size)
{
@@ -64,7 +63,12 @@ int vg_add_snapshot(struct format_instance *fid, const char *name,
return 0;
}
if (!(snap = lv_create_empty(fid, name ? name : "snapshot%d",
if (cow == origin) {
log_error("Snapshot and origin LVs must differ.");
return 0;
}
if (!(snap = lv_create_empty(name ? name : "snapshot%d",
lvid, LVM_READ | LVM_WRITE | VISIBLE_LV,
ALLOC_INHERIT, 1, origin->vg))) {
stack;

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

@@ -0,0 +1,27 @@
/*
* Copyright (C) 2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License v.2.1.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Return the address of the last file name component of NAME.
* If NAME ends in a slash, return the empty string.
*/
#include <string.h>
static inline char *last_path_component(char const *name)
{
char const *slash = strrchr (name, '/');
char const *res = slash ? slash + 1 : name;
return (char *) res;
}

View File

@@ -19,9 +19,4 @@
#include "lib.h"
char *last_path_component(char const *name)
{
char const *slash = strrchr (name, '/');
char const *res = slash ? slash + 1 : name;
return (char *) res;
}
/* empty for now. */

View File

@@ -15,6 +15,14 @@
#ifndef _LVM_UTIL_H
#define _LVM_UTIL_H
char *last_path_component(char const *name);
#define min(a, b) ({ typeof(a) _a = (a); \
typeof(b) _b = (b); \
(void) (&_a == &_b); \
_a < _b ? _a : _b; })
#define max(a, b) ({ typeof(a) _a = (a); \
typeof(b) _b = (b); \
(void) (&_a == &_b); \
_a > _b ? _a : _b; })
#endif

View File

@@ -23,8 +23,10 @@ FIELD(LVS, lv, STR, "LV", lvid, 4, lvname, "lv_name", "Name. LVs created for in
FIELD(LVS, lv, STR, "Attr", lvid, 4, lvstatus, "lv_attr", "Various attributes - see man page.")
FIELD(LVS, lv, NUM, "Maj", major, 3, int32, "lv_major", "Persistent major number or -1 if not persistent.")
FIELD(LVS, lv, NUM, "Min", minor, 3, int32, "lv_minor", "Persistent minor number or -1 if not persistent.")
FIELD(LVS, lv, NUM, "Rahead", lvid, 6, lvreadahead, "lv_read_ahead", "Read ahead setting in current units.")
FIELD(LVS, lv, STR, "KMaj", lvid, 4, lvkmaj, "lv_kernel_major", "Currently assigned major number or -1 if LV is not active.")
FIELD(LVS, lv, STR, "KMin", lvid, 4, lvkmin, "lv_kernel_minor", "Currently assigned minor number or -1 if LV is not active.")
FIELD(LVS, lv, NUM, "KRahead", lvid, 7, lvkreadahead, "lv_kernel_read_ahead", "Currently-in-use read ahead setting in current units.")
FIELD(LVS, lv, NUM, "LSize", size, 5, size64, "lv_size", "Size of LV in current units.")
FIELD(LVS, lv, NUM, "#Seg", lvid, 4, lvsegcount, "seg_count", "Number of segments in LV.")
FIELD(LVS, lv, STR, "Origin", lvid, 6, origin, "origin", "For snapshots, the origin device of this LV")
@@ -48,6 +50,7 @@ FIELD(PVS, pv, NUM, "PE", pe_count, 3, uint32, "pv_pe_count", "Total number of P
FIELD(PVS, pv, NUM, "Alloc", pe_alloc_count, 5, uint32, "pv_pe_alloc_count", "Total number of allocated Physical Extents.")
FIELD(PVS, pv, STR, "PV Tags", tags, 7, tags, "pv_tags", "Tags, if any.")
FIELD(PVS, pv, NUM, "#PMda", id, 5, pvmdas, "pv_mda_count", "Number of metadata areas on this device.")
FIELD(PVS, pv, NUM, "#PMdaFree", id, 9, pvmdafree, "pv_mda_free", "Free metadata area space on this device in current units.")
FIELD(VGS, vg, STR, "Fmt", cmd, 3, vgfmt, "vg_fmt", "Type of metadata.")
FIELD(VGS, vg, STR, "VG UUID", id, 38, uuid, "vg_uuid", "Unique identifier.")
@@ -67,6 +70,7 @@ FIELD(VGS, vg, NUM, "#SN", snapshot_count, 3, uint32, "snap_count", "Number of s
FIELD(VGS, vg, NUM, "Seq", seqno, 3, uint32, "vg_seqno", "Revision number of internal metadata. Incremented whenever it changes.")
FIELD(VGS, vg, STR, "VG Tags", tags, 7, tags, "vg_tags", "Tags, if any.")
FIELD(VGS, vg, NUM, "#VMda", cmd, 5, vgmdas, "vg_mda_count", "Number of metadata areas in use by this VG.")
FIELD(VGS, vg, NUM, "#VMdaFree", cmd, 9, vgmdafree, "vg_mda_free", "Free metadata area space for this VG in current units.")
FIELD(SEGS, seg, STR, "Type", list, 4, segtype, "segtype", "Type of LV segment")
FIELD(SEGS, seg, NUM, "#Str", area_count, 4, uint32, "stripes", "Number of stripes or mirror legs.")

View File

@@ -59,6 +59,8 @@ static char _alloc_policy_char(alloc_policy_t alloc)
}
}
static const uint64_t _minusone = UINT64_C(-1);
/*
* Data-munging functions to prepare each data type for display and sorting
*/
@@ -224,12 +226,11 @@ static int _lvkmaj_disp(struct dm_report *rh, struct dm_pool *mem __attribute((u
{
const struct logical_volume *lv = (const struct logical_volume *) data;
struct lvinfo info;
uint64_t minusone = UINT64_C(-1);
if (lv_info(lv->vg->cmd, lv, &info, 0) && info.exists)
if (lv_info(lv->vg->cmd, lv, &info, 0, 0) && info.exists)
return dm_report_field_int(rh, field, &info.major);
return dm_report_field_uint64(rh, field, &minusone);
return dm_report_field_uint64(rh, field, &_minusone);
}
static int _lvkmin_disp(struct dm_report *rh, struct dm_pool *mem __attribute((unused)),
@@ -238,12 +239,11 @@ static int _lvkmin_disp(struct dm_report *rh, struct dm_pool *mem __attribute((u
{
const struct logical_volume *lv = (const struct logical_volume *) data;
struct lvinfo info;
uint64_t minusone = UINT64_C(-1);
if (lv_info(lv->vg->cmd, lv, &info, 0) && info.exists)
if (lv_info(lv->vg->cmd, lv, &info, 0, 0) && info.exists)
return dm_report_field_int(rh, field, &info.minor);
return dm_report_field_uint64(rh, field, &minusone);
return dm_report_field_uint64(rh, field, &_minusone);
}
static int _lvstatus_disp(struct dm_report *rh __attribute((unused)), struct dm_pool *mem,
@@ -297,7 +297,7 @@ static int _lvstatus_disp(struct dm_report *rh __attribute((unused)), struct dm_
else
repstr[3] = '-';
if (lv_info(lv->vg->cmd, lv, &info, 1) && info.exists) {
if (lv_info(lv->vg->cmd, lv, &info, 1, 0) && info.exists) {
if (info.suspended)
repstr[4] = 's'; /* Suspended */
else if (info.live_table)
@@ -561,6 +561,34 @@ static int _size64_disp(struct dm_report *rh __attribute((unused)),
return 1;
}
static int _lvreadahead_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private __attribute((unused)))
{
const struct logical_volume *lv = (const struct logical_volume *) data;
if (lv->read_ahead == DM_READ_AHEAD_AUTO) {
dm_report_field_set_value(field, "auto", &_minusone);
return 1;
}
return _size32_disp(rh, mem, field, &lv->read_ahead, private);
}
static int _lvkreadahead_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data,
void *private)
{
const struct logical_volume *lv = (const struct logical_volume *) data;
struct lvinfo info;
if (!lv_info(lv->vg->cmd, lv, &info, 0, 1) || !info.exists)
return dm_report_field_uint64(rh, field, &_minusone);
return _size32_disp(rh, mem, field, &info.read_ahead, private);
}
static int _vgsize_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
@@ -745,6 +773,53 @@ static int _vgmdas_disp(struct dm_report *rh, struct dm_pool *mem,
return _uint32_disp(rh, mem, field, &count, private);
}
static int _pvmdafree_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
{
struct lvmcache_info *info;
uint64_t freespace = UINT64_MAX, mda_free;
const char *pvid = (const char *)(&((struct id *) data)->uuid);
struct metadata_area *mda;
info = info_from_pvid(pvid);
list_iterate_items(mda, &info->mdas) {
if (!mda->ops->mda_free_sectors)
continue;
mda_free = mda->ops->mda_free_sectors(mda);
if (mda_free < freespace)
freespace = mda_free;
}
if (freespace == UINT64_MAX)
freespace = UINT64_C(0);
return _size64_disp(rh, mem, field, &freespace, private);
}
static int _vgmdafree_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
{
const struct volume_group *vg = (const struct volume_group *) data;
uint64_t freespace = UINT64_MAX, mda_free;
struct metadata_area *mda;
list_iterate_items(mda, &vg->fid->metadata_areas) {
if (!mda->ops->mda_free_sectors)
continue;
mda_free = mda->ops->mda_free_sectors(mda);
if (mda_free < freespace)
freespace = mda_free;
}
if (freespace == UINT64_MAX)
freespace = UINT64_C(0);
return _size64_disp(rh, mem, field, &freespace, private);
}
static int _lvsegcount_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
@@ -779,7 +854,7 @@ static int _snpercent_disp(struct dm_report *rh __attribute((unused)), struct dm
}
if (!lv_is_cow(lv) ||
(lv_info(lv->vg->cmd, lv, &info, 0) && !info.exists)) {
(lv_info(lv->vg->cmd, lv, &info, 0, 0) && !info.exists)) {
*sortval = UINT64_C(0);
dm_report_field_set_value(field, "", sortval);
return 1;

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

@@ -69,7 +69,7 @@ static int _snap_text_import(struct lv_segment *seg, const struct config_node *s
return 0;
}
if (!vg_add_snapshot(seg->lv->vg->fid, seg->lv->name, org, cow,
if (!vg_add_snapshot(seg->lv->name, org, cow,
&seg->lv->lvid, seg->len, chunk_size)) {
stack;
return 0;

View File

@@ -18,6 +18,7 @@ dm_task_get_name
dm_task_get_names
dm_task_get_versions
dm_task_get_uuid
dm_task_get_read_ahead
dm_task_set_ro
dm_task_set_newname
dm_task_set_event_nr
@@ -28,6 +29,7 @@ dm_task_set_message
dm_task_set_uid
dm_task_set_gid
dm_task_set_mode
dm_task_set_read_ahead
dm_task_suppress_identical_reload
dm_task_add_target
dm_task_no_flush
@@ -67,6 +69,7 @@ dm_tree_node_add_striped_target
dm_tree_node_add_mirror_target
dm_tree_node_add_mirror_target_log
dm_tree_node_add_target_area
dm_tree_node_set_read_ahead
dm_tree_skip_lockfs
dm_tree_use_no_flush_suspend
dm_is_dm_major

View File

@@ -41,6 +41,7 @@ ifeq ("@LIB_SUFFIX@","dylib")
else
LIB_SHARED = $(interface)/libdevmapper.so
endif
VERSIONED_SHLIB = libdevmapper.$(LIB_SUFFIX).$(LIB_VERSION)
DEFS += -DDEVICE_UID=@DEVICE_UID@ -DDEVICE_GID=@DEVICE_GID@ \
-DDEVICE_MODE=@DEVICE_MODE@
@@ -86,10 +87,13 @@ install_ioctl_static: ioctl/libdevmapper.a
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \
$(libdir)/libdevmapper.a.$(LIB_VERSION)
$(VERSIONED_SHLIB): %.$(LIB_SUFFIX).$(LIB_VERSION): $(interface)/%.$(LIB_SUFFIX)
rm -f $@
$(LN_S) $< $@
.PHONY: distclean_lib distclean
distclean_lib:
distclean_lib:
$(RM) libdevmapper.pc
distclean: distclean_lib

View File

@@ -920,6 +920,33 @@ int dm_task_get_info(struct dm_task *dmt, struct dm_info *info)
return 1;
}
uint32_t dm_task_get_read_ahead(const struct dm_task *dmt, uint32_t *read_ahead)
{
const char *dev_name;
*read_ahead = 0;
#ifdef DM_COMPAT
/* Not supporting this */
if (_dm_version == 1)
return 1;
#endif
if (!dmt->dmi.v4 || !(dmt->dmi.v4->flags & DM_EXISTS_FLAG))
return 0;
if (*dmt->dmi.v4->name)
dev_name = dmt->dmi.v4->name;
else if (dmt->dev_name)
dev_name = dmt->dev_name;
else {
log_error("Get read ahead request failed: device name unrecorded.");
return 0;
}
return get_dev_node_read_ahead(dev_name, read_ahead);
}
const char *dm_task_get_name(const struct dm_task *dmt)
{
#ifdef DM_COMPAT
@@ -974,6 +1001,15 @@ int dm_task_set_ro(struct dm_task *dmt)
return 1;
}
int dm_task_set_read_ahead(struct dm_task *dmt, uint32_t read_ahead,
uint32_t read_ahead_flags)
{
dmt->read_ahead = read_ahead;
dmt->read_ahead_flags = read_ahead_flags;
return 1;
}
int dm_task_suppress_identical_reload(struct dm_task *dmt)
{
dmt->suppress_identical_reload = 1;
@@ -1267,7 +1303,9 @@ static struct dm_ioctl *_flatten(struct dm_task *dmt, unsigned repeat_count)
dmt->major, dmt->minor, dmi->name);
}
if (dmt->dev_name)
/* FIXME Until resume ioctl supplies name, use dev_name for readahead */
if (dmt->dev_name && (dmt->type != DM_DEVICE_RESUME || dmt->minor < 0 ||
dmt->major < 0))
strncpy(dmi->name, dmt->dev_name, sizeof(dmi->name));
if (dmt->uuid)
@@ -1668,6 +1706,12 @@ repeat_ioctl:
rename_dev_node(dmt->dev_name, dmt->newname);
break;
case DM_DEVICE_RESUME:
/* FIXME Kernel needs to fill in dmi->name */
set_dev_node_read_ahead(dmt->dev_name, dmt->read_ahead,
dmt->read_ahead_flags);
break;
case DM_DEVICE_MKNODES:
if (dmi->flags & DM_EXISTS_FLAG)
add_dev_node(dmi->name, MAJOR(dmi->dev),

View File

@@ -44,6 +44,8 @@ struct dm_task {
uid_t uid;
gid_t gid;
mode_t mode;
uint32_t read_ahead;
uint32_t read_ahead_flags;
union {
struct dm_ioctl *v4;
struct dm_ioctl_v1 *v1;

View File

@@ -157,6 +157,22 @@ int dm_task_no_open_count(struct dm_task *dmt);
int dm_task_skip_lockfs(struct dm_task *dmt);
int dm_task_suppress_identical_reload(struct dm_task *dmt);
/*
* Control read_ahead.
*/
#define DM_READ_AHEAD_AUTO UINT32_MAX /* Use kernel default readahead */
#define DM_READ_AHEAD_NONE 0 /* Disable readahead */
#define DM_READ_AHEAD_MINIMUM_FLAG 0x1 /* Value supplied is minimum */
/*
* Read ahead is set with DM_DEVICE_CREATE with a table or DM_DEVICE_RESUME.
*/
int dm_task_set_read_ahead(struct dm_task *dmt, uint32_t read_ahead,
uint32_t read_ahead_flags);
uint32_t dm_task_get_read_ahead(const struct dm_task *dmt,
uint32_t *read_ahead);
/*
* Use these to prepare for a create or reload.
*/
@@ -376,6 +392,13 @@ int dm_tree_node_add_target_area(struct dm_tree_node *node,
const char *dlid,
uint64_t offset);
/*
* Set readahead (in sectors) after loading the node.
*/
void dm_tree_node_set_read_ahead(struct dm_tree_node *dnode,
uint32_t read_ahead,
uint32_t read_ahead_flags);
/*****************************************************************************
* Library functions
*****************************************************************************/

View File

@@ -21,9 +21,15 @@
#include <stdarg.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <linux/dm-ioctl.h>
#ifdef linux
# include <linux/fs.h>
#endif
#ifdef HAVE_SELINUX
# include <selinux/selinux.h>
#endif
@@ -118,6 +124,8 @@ struct dm_task *dm_task_create(int type)
dmt->gid = DEVICE_GID;
dmt->mode = DEVICE_MODE;
dmt->no_open_count = 0;
dmt->read_ahead = DM_READ_AHEAD_AUTO;
dmt->read_ahead_flags = 0;
return dmt;
}
@@ -354,15 +362,119 @@ static int _rm_dev_node(const char *dev_name)
return 1;
}
#ifdef linux
static int _open_dev_node(const char *dev_name)
{
int fd = -1;
char path[PATH_MAX];
_build_dev_path(path, sizeof(path), dev_name);
if ((fd = open(path, O_RDONLY, 0)) < 0)
log_sys_error("open", path);
return fd;
}
int get_dev_node_read_ahead(const char *dev_name, uint32_t *read_ahead)
{
int r = 1;
int fd;
long read_ahead_long;
if ((fd = _open_dev_node(dev_name)) < 0)
return_0;
if (ioctl(fd, BLKRAGET, &read_ahead_long)) {
log_sys_error("BLKRAGET", dev_name);
*read_ahead = 0;
r = 0;
} else {
*read_ahead = (uint32_t) read_ahead_long;
log_debug("%s: read ahead is %" PRIu32, dev_name, *read_ahead);
}
if (close(fd))
stack;
return r;
}
static int _set_read_ahead(const char *dev_name, uint32_t read_ahead)
{
int r = 1;
int fd;
long read_ahead_long = (long) read_ahead;
if ((fd = _open_dev_node(dev_name)) < 0)
return_0;
log_debug("%s: Setting read ahead to %" PRIu32, dev_name, read_ahead);
if (ioctl(fd, BLKRASET, read_ahead_long)) {
log_sys_error("BLKRASET", dev_name);
r = 0;
}
if (close(fd))
stack;
return r;
}
static int _set_dev_node_read_ahead(const char *dev_name, uint32_t read_ahead,
uint32_t read_ahead_flags)
{
uint32_t current_read_ahead;
if (read_ahead == DM_READ_AHEAD_AUTO)
return 1;
if (read_ahead == DM_READ_AHEAD_NONE)
read_ahead = 0;
if (read_ahead_flags & DM_READ_AHEAD_MINIMUM_FLAG) {
if (!get_dev_node_read_ahead(dev_name, &current_read_ahead))
return_0;
if (current_read_ahead > read_ahead) {
log_debug("%s: read ahead %" PRIu32
" below minimum of %" PRIu32,
dev_name, current_read_ahead, read_ahead);
return 1;
}
}
return _set_read_ahead(dev_name, read_ahead);
}
#else
int get_dev_node_read_ahead(const char *dev_name, uint32_t *read_ahead)
{
*read_ahead = 0;
return 1;
}
static int _set_dev_node_read_ahead(const char *dev_name, uint32_t read_ahead,
uint32_t read_ahead_flags)
{
return 1;
}
#endif
typedef enum {
NODE_ADD,
NODE_DEL,
NODE_RENAME
NODE_RENAME,
NODE_READ_AHEAD
} node_op_t;
static int _do_node_op(node_op_t type, const char *dev_name, uint32_t major,
uint32_t minor, uid_t uid, gid_t gid, mode_t mode,
const char *old_name)
const char *old_name, uint32_t read_ahead,
uint32_t read_ahead_flags)
{
switch (type) {
case NODE_ADD:
@@ -371,6 +483,9 @@ static int _do_node_op(node_op_t type, const char *dev_name, uint32_t major,
return _rm_dev_node(dev_name);
case NODE_RENAME:
return _rename_dev_node(old_name, dev_name);
case NODE_READ_AHEAD:
return _set_dev_node_read_ahead(dev_name, read_ahead,
read_ahead_flags);
}
return 1;
@@ -387,6 +502,8 @@ struct node_op_parms {
uid_t uid;
gid_t gid;
mode_t mode;
uint32_t read_ahead;
uint32_t read_ahead_flags;
char *old_name;
char names[0];
};
@@ -400,7 +517,8 @@ static void _store_str(char **pos, char **ptr, const char *str)
static int _stack_node_op(node_op_t type, const char *dev_name, uint32_t major,
uint32_t minor, uid_t uid, gid_t gid, mode_t mode,
const char *old_name)
const char *old_name, uint32_t read_ahead,
uint32_t read_ahead_flags)
{
struct node_op_parms *nop;
size_t len = strlen(dev_name) + strlen(old_name) + 2;
@@ -418,6 +536,8 @@ static int _stack_node_op(node_op_t type, const char *dev_name, uint32_t major,
nop->uid = uid;
nop->gid = gid;
nop->mode = mode;
nop->read_ahead = read_ahead;
nop->read_ahead_flags = read_ahead_flags;
_store_str(&pos, &nop->dev_name, dev_name);
_store_str(&pos, &nop->old_name, old_name);
@@ -435,7 +555,8 @@ static void _pop_node_ops(void)
list_iterate_safe(noph, nopht, &_node_ops) {
nop = list_item(noph, struct node_op_parms);
_do_node_op(nop->type, nop->dev_name, nop->major, nop->minor,
nop->uid, nop->gid, nop->mode, nop->old_name);
nop->uid, nop->gid, nop->mode, nop->old_name,
nop->read_ahead, nop->read_ahead_flags);
list_del(&nop->list);
dm_free(nop);
}
@@ -445,17 +566,28 @@ int add_dev_node(const char *dev_name, uint32_t major, uint32_t minor,
uid_t uid, gid_t gid, mode_t mode)
{
return _stack_node_op(NODE_ADD, dev_name, major, minor, uid, gid, mode,
"");
"", 0, 0);
}
int rename_dev_node(const char *old_name, const char *new_name)
{
return _stack_node_op(NODE_RENAME, new_name, 0, 0, 0, 0, 0, old_name);
return _stack_node_op(NODE_RENAME, new_name, 0, 0, 0, 0, 0, old_name,
0, 0);
}
int rm_dev_node(const char *dev_name)
{
return _stack_node_op(NODE_DEL, dev_name, 0, 0, 0, 0, 0, "");
return _stack_node_op(NODE_DEL, dev_name, 0, 0, 0, 0, 0, "", 0, 0);
}
int set_dev_node_read_ahead(const char *dev_name, uint32_t read_ahead,
uint32_t read_ahead_flags)
{
if (read_ahead == DM_READ_AHEAD_AUTO)
return 1;
return _stack_node_op(NODE_READ_AHEAD, dev_name, 0, 0, 0, 0, 0, "",
read_ahead, read_ahead_flags);
}
void update_devs(void)
@@ -463,9 +595,25 @@ void update_devs(void)
_pop_node_ops();
}
int dm_set_dev_dir(const char *dir)
int dm_set_dev_dir(const char *dev_dir)
{
snprintf(_dm_dir, sizeof(_dm_dir), "%s%s", dir, DM_DIR);
size_t len;
const char *slash;
if (*dev_dir != '/') {
log_debug("Invalid dev_dir value, %s: "
"not an absolute name.", dev_dir);
return 0;
}
len = strlen(dev_dir);
slash = dev_dir[len-1] == '/' ? "" : "/";
if (snprintf(_dm_dir, sizeof _dm_dir, "%s%s%s", dev_dir, slash, DM_DIR)
>= sizeof _dm_dir) {
log_debug("Invalid dev_dir value, %s: name too long.", dev_dir);
return 0;
}
return 1;
}

View File

@@ -26,6 +26,9 @@ int add_dev_node(const char *dev_name, uint32_t minor, uint32_t major,
uid_t uid, gid_t gid, mode_t mode);
int rm_dev_node(const char *dev_name);
int rename_dev_node(const char *old_name, const char *new_name);
int get_dev_node_read_ahead(const char *dev_name, uint32_t *read_ahead);
int set_dev_node_read_ahead(const char *dev_name, uint32_t read_ahead,
uint32_t read_ahead_flags);
void update_devs(void);
#endif

View File

@@ -95,6 +95,9 @@ struct load_properties {
uint32_t major;
uint32_t minor;
uint32_t read_ahead;
uint32_t read_ahead_flags;
unsigned segment_count;
struct list segs;
@@ -609,6 +612,8 @@ struct dm_tree_node *dm_tree_add_new_dev(struct dm_tree *dtree,
}
dnode->props.read_only = read_only ? 1 : 0;
dnode->props.read_ahead = DM_READ_AHEAD_AUTO;
dnode->props.read_ahead_flags = 0;
if (clear_inactive && !_node_clear_table(dnode))
return_NULL;
@@ -618,6 +623,14 @@ struct dm_tree_node *dm_tree_add_new_dev(struct dm_tree *dtree,
return dnode;
}
void dm_tree_node_set_read_ahead(struct dm_tree_node *dnode,
uint32_t read_ahead,
uint32_t read_ahead_flags)
{
dnode->props.read_ahead = read_ahead;
dnode->props.read_ahead_flags = read_ahead_flags;
}
int dm_tree_add_dev(struct dm_tree *dtree, uint32_t major, uint32_t minor)
{
return _add_dev(dtree, &dtree->root, major, minor) ? 1 : 0;
@@ -875,6 +888,7 @@ out:
/* FIXME Merge with _suspend_node? */
static int _resume_node(const char *name, uint32_t major, uint32_t minor,
uint32_t read_ahead, uint32_t read_ahead_flags,
struct dm_info *newinfo)
{
struct dm_task *dmt;
@@ -887,6 +901,13 @@ static int _resume_node(const char *name, uint32_t major, uint32_t minor,
return 0;
}
/* FIXME Kernel should fill in name on return instead */
if (!dm_task_set_name(dmt, name)) {
log_error("Failed to set readahead device name for %s", name);
dm_task_destroy(dmt);
return 0;
}
if (!dm_task_set_major(dmt, major) || !dm_task_set_minor(dmt, minor)) {
log_error("Failed to set device number for %s resumption.", name);
dm_task_destroy(dmt);
@@ -896,6 +917,9 @@ static int _resume_node(const char *name, uint32_t major, uint32_t minor,
if (!dm_task_no_open_count(dmt))
log_error("Failed to disable open_count");
if (!dm_task_set_read_ahead(dmt, read_ahead, read_ahead_flags))
log_error("Failed to set read ahead");
if ((r = dm_task_run(dmt)))
r = dm_task_get_info(dmt, newinfo);
@@ -1136,7 +1160,9 @@ int dm_tree_activate_children(struct dm_tree_node *dnode,
if (!child->info.inactive_table && !child->info.suspended)
continue;
if (!_resume_node(name, child->info.major, child->info.minor, &newinfo)) {
if (!_resume_node(name, child->info.major, child->info.minor,
child->props.read_ahead,
child->props.read_ahead_flags, &newinfo)) {
log_error("Unable to resume %s (%" PRIu32
":%" PRIu32 ")", name, child->info.major,
child->info.minor);
@@ -1527,7 +1553,9 @@ int dm_tree_preload_children(struct dm_tree_node *dnode,
if (!child->info.inactive_table && !child->info.suspended)
continue;
if (!_resume_node(name, child->info.major, child->info.minor, &newinfo)) {
if (!_resume_node(name, child->info.major, child->info.minor,
child->props.read_ahead,
child->props.read_ahead_flags, &newinfo)) {
log_error("Unable to resume %s (%" PRIu32
":%" PRIu32 ")", name, child->info.major,
child->info.minor);

View File

@@ -3,7 +3,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

@@ -114,6 +114,14 @@ Specify which fields to display.
.IP \fB-r|--readonly
.br
Set the table being loaded read-only.
.IP \fB--readahead\ [+]<sectors>|auto|none
.br
Specify read ahead size in units of sectors.
The default value is "auto" which allows the kernel to choose
a suitable value automatically. The + prefix lets you
specify a minimum value which will not be used if it is
smaller than the value chosen by the kernel.
"None" is equivalent to specifying zero.
.IP \fB--table\ <table>
.br
Specify a one-line table directly on the command line.
@@ -341,6 +349,12 @@ for creating devices with holes in them.
.br
2056320 2875602 linear /dev/hdb 1028160
.SH ENVIRONMENT VARIABLES
.TP
\fBDM_DEV_DIR\fP
The device directory name.
Defaults to "/dev" and must be an absolute path.
.SH AUTHORS
Original version: Joe Thornber (thornber@sistina.com)

View File

@@ -14,7 +14,7 @@ lvchange \- change attributes of a logical volume
[\-\-monitor {y|n}]
[\-M/\-\-persistent y/n] [\-\-minor minor]
[\-P/\-\-partial]
[\-p/\-\-permission r/w] [\-r/\-\-readahead ReadAheadSectors]
[\-p/\-\-permission r/w] [\-r/\-\-readahead ReadAheadSectors|auto|none]
[\-\-refresh]
[\-t/\-\-test]
[\-v/\-\-verbose] LogicalVolumePath [LogicalVolumePath...]
@@ -72,9 +72,14 @@ Set to y to make the minor number specified persistent.
.I \-p, \-\-permission r/w
Change access permission to read-only or read/write.
.TP
.I \-r, \-\-readahead ReadAheadSectors
Change read ahead sector count per logical between 2 and 120.
For compatability with LVM1 only. Ignored by LVM2.
.I \-r, \-\-readahead ReadAheadSectors|auto|none
Set read ahead sector count of this logical volume.
For volume groups with metadata in lvm1 format, this must
be a value between 2 and 120.
The default value is "auto" which allows the kernel to choose
a suitable value automatically.
"None" is equivalent to specifying zero.
N.B. This setting is currently disregarded and "auto" is always used.
.TP
.I \-\-refresh
If the logical volume is active, reload its metadata.

View File

@@ -47,7 +47,7 @@ regenerated by copying the data from the first device again every
time the device is activated - perhaps, for example, after every reboot.
.TP
.I \-\-corelog
The optional argument "--corelog" is the same as specifying "--log core".
The optional argument "--corelog" is the same as specifying "--mirrorlog core".
.TP
.I \-R, \-\-regionsize MirrorLogRegionSize
A mirror is divided into regions of this size (in MB), and the mirror log
@@ -71,12 +71,12 @@ If the volume is read-only the snapshot will not be zeroed.
converts the linear logical volume "vg00/lvol1" to
a two-way mirror logical volume.
"lvconvert --log core vg00/lvol1"
"lvconvert --mirrorlog core vg00/lvol1"
.br
converts a mirror with a disk log to a
mirror with an in-memory log.
"lvconvert --log disk vg00/lvol1"
"lvconvert --mirrorlog disk vg00/lvol1"
.br
converts a mirror with an in-memory log
to a mirror with a disk log.

View File

@@ -8,13 +8,13 @@ lvcreate \- create a logical volume in an existing volume group
[\-A/\-\-autobackup y/n] [\-C/\-\-contiguous y/n] [\-d/\-\-debug]
[\-h/\-?/\-\-help]
[\-i/\-\-stripes Stripes [\-I/\-\-stripesize StripeSize]]
{\-l/\-\-extents LogicalExtentsNumber[%{VG|FREE}] |
{\-l/\-\-extents LogicalExtentsNumber[%{VG|PVS|FREE}] |
\-L/\-\-size LogicalVolumeSize[kKmMgGtT]}
[\-M/\-\-persistent y/n] [\-\-minor minor]
[\-m/\-\-mirrors Mirrors [\-\-nosync] [\-\-mirrorlog {disk|log}] [\-\-corelog]
[\-R/\-\-regionsize MirrorLogRegionSize]]
[\-n/\-\-name LogicalVolumeName]
[\-p/\-\-permission r/rw] [\-r/\-\-readahead ReadAheadSectors]
[\-p/\-\-permission r/rw] [\-r/\-\-readahead ReadAheadSectors|auto|none]
[\-t/\-\-test]
[\-v/\-\-verbose] [\-Z/\-\-zero y/n]
VolumeGroupName [PhysicalVolumePath...]
@@ -63,12 +63,14 @@ StripeSize must be 2^n (n = 2 to 9) for metadata in LVM1 format.
For metadata in LVM2 format, the stripe size may be a larger
power of 2 but must not exceed the physical extent size.
.TP
.I \-l, \-\-extents LogicalExtentsNumber[%{VG|FREE}]
.I \-l, \-\-extents LogicalExtentsNumber[%{VG|PVS|FREE}]
Gives the number of logical extents to allocate for the new
logical volume.
This can also be expressed as a percentage of the total space
in the Volume Group with the suffix %VG or of the remaining free space
with the suffix %FREE.
in the Volume Group with the suffix %VG, of the remaining
free space in the Volume Group with the suffix %FREE, or
of the remaining free space for the specified PhysicalVolume(s)
with the suffix %PVS,
.TP
.I \-L, \-\-size LogicalVolumeSize[kKmMgGtTpPeE]
Gives the size to allocate for the new logical volume.
@@ -102,7 +104,7 @@ data being mirrored. Using core means the mirror is regenerated
by copying the data from the first device again each time the
device is activated, for example, after every reboot.
The optional argument --corelog is equivalent to --log core.
The optional argument --corelog is equivalent to --mirrorlog core.
.TP
.I \-n, \-\-name LogicalVolumeName
@@ -116,9 +118,14 @@ Set access permissions to read only or read and write.
.br
Default is read and write.
.TP
.I \-r, \-\-readahead ReadAheadSectors
Set read ahead sector count of this logical volume to a value between 2 and 120.
Ignored by device-mapper.
.I \-r, \-\-readahead ReadAheadSectors|auto|none
Set read ahead sector count of this logical volume.
For volume groups with metadata in lvm1 format, this must
be a value between 2 and 120.
The default value is "auto" which allows the kernel to choose
a suitable value automatically.
"None" is equivalent to specifying zero.
N.B. This setting is currently disregarded and "auto" is always used.
.TP
.I \-R, \-\-regionsize MirrorLogRegionSize
A mirror is divided into regions of this size (in MB), and the mirror log
@@ -161,7 +168,7 @@ with 2 sides with a useable size of 500 MiB. This operation would
require 3 devices - two for the mirror devices and one for the disk
log.
"lvcreate -m1 --log core -L 500M vg00" tries to create a mirror logical volume
"lvcreate -m1 --mirrorlog core -L 500M vg00" tries to create a mirror logical volume
with 2 sides with a useable size of 500 MiB. This operation would
require 2 devices - the log is "in-memory".

View File

@@ -6,7 +6,7 @@ lvextend \- extend the size of a logical volume
[\-\-alloc AllocationPolicy]
[\-A/\-\-autobackup y/n] [\-d/\-\-debug] [\-h/\-?/\-\-help]
[\-i/\-\-stripes Stripes [\-I/\-\-stripesize StripeSize]]
{\-l/\-\-extents [+]LogicalExtentsNumber[%{VG|LV|FREE}] |
{\-l/\-\-extents [+]LogicalExtentsNumber[%{VG|LV|PVS|FREE}] |
\-L/\-\-size [+]LogicalVolumeSize[kKmMgGtT]}
[\-t/\-\-test]
[\-v/\-\-verbose] LogicalVolumePath [PhysicalVolumePath...]
@@ -21,14 +21,16 @@ volume use
.SH OPTIONS
See \fBlvm\fP for common options.
.TP
.I \-l, \-\-extents [+]LogicalExtentsNumber[%{VG|LV|FREE}]
.I \-l, \-\-extents [+]LogicalExtentsNumber[%{VG|LV|PVS|FREE}]
Extend or set the logical volume size in units of logical extents.
With the + sign the value is added to the actual size
of the logical volume and without it, the value is taken as an absolute one.
The number can also be expressed as a percentage of the total space
in the Volume Group with the suffix %VG or relative to the existing
size of the Logical Volume with the suffix %LV or as a percentage of the remaining
free space in the Volume Group with the suffix %FREE.
in the Volume Group with the suffix %VG, relative to the existing
size of the Logical Volume with the suffix %LV, of the remaining
free space for the specified PhysicalVolume(s) with the suffix %PVS,
or as a percentage of the remaining free space in the Volume Group
with the suffix %FREE.
.TP
.I \-L, \-\-size [+]LogicalVolumeSize[kKmMgGtTpPeE]
Extend or set the logical volume size in units of megabytes.
@@ -54,6 +56,10 @@ StripeSize must be 2^n (n = 2 to 9)
that logical volume by 54MB on physical volume /dev/sdk3.
This is only possible if /dev/sdk3 is a member of volume group vg01 and
there are enough free physical extents in it.
"lvextend /dev/vg01/lvol01 /dev/sdk3" tries to extend the size of that
logical volume by the amount of free space on physical volume /dev/sdk3.
This is equivalent to specifying "-l +100%PVS" on the command line.
.SH SEE ALSO
.BR lvm (8),
.BR lvcreate (8),

View File

@@ -306,6 +306,11 @@ such devices.
\fBmirror_region_size\fP \(em Unit size in KB for copy operations
when mirroring.
.IP
\fBreadahead\fP \(em Used when there is no readahead value stored
in the volume group metadata. Set to \fBnone\fP to disable
readahead in these circumstances or \fBauto\fP to use the default
value chosen by the kernel.
.IP
\fBreserved_memory\fP, \fBreserved_stack\fP \(em How many KB to reserve
for LVM2 to use while logical volumes are suspended. If insufficient
memory is reserved before suspension, there is a risk of machine deadlock.

View File

@@ -6,7 +6,7 @@ lvresize \- resize a logical volume
[\-\-alloc AllocationPolicy]
[\-A/\-\-autobackup y/n] [\-d/\-\-debug] [\-h/\-?/\-\-help]
[\-i/\-\-stripes Stripes [\-I/\-\-stripesize StripeSize]]
{\-l/\-\-extents [+]LogicalExtentsNumber[%{VG|LV|FREE}] |
{\-l/\-\-extents [+]LogicalExtentsNumber[%{VG|LV|PVS|FREE}] |
\-L/\-\-size [+]LogicalVolumeSize[kKmMgGtT]}
[\-t/\-\-test]
[\-v/\-\-verbose] LogicalVolumePath [PhysicalVolumePath...]
@@ -25,14 +25,16 @@ volume use
.SH OPTIONS
See \fBlvm\fP for common options.
.TP
.I \-l, \-\-extents [+/-]LogicalExtentsNumber[%{VG|LV|FREE}]
.I \-l, \-\-extents [+/-]LogicalExtentsNumber[%{VG|LV|PVS|FREE}]
Change or set the logical volume size in units of logical extents.
With the + or - sign the value is added to or subtracted from the actual size
of the logical volume and without it, the value is taken as an absolute one.
The number can also be expressed as a percentage of the total space
in the Volume Group with the suffix %VG or relative to the existing
size of the Logical Volume with the suffix %LV or as a percentage of the remaining
free space in the Volume Group with the suffix %FREE.
in the Volume Group with the suffix %VG, relative to the existing
size of the Logical Volume with the suffix %LV, as a percentage of
the remaining free space of the PhysicalVolumes on the command line with the
suffix %PVS, or as a percentage of the remaining free space in the
Volume Group with the suffix %FREE.
.TP
.I \-L, \-\-size [+/-]LogicalVolumeSize[kKmMgGtTpPeE]
Change or set the logical volume size in units of megabytes.

View File

@@ -3,17 +3,24 @@
vgremove \- remove a volume group
.SH SYNOPSIS
.B vgremove
[\-d/\-\-debug] [\-h/\-?/\-\-help] [\-t/\-\-test] [\-v/\-\-verbose]
[\-d/\-\-debug] [\-f/\-\-force] [\-h/\-?/\-\-help]
[\-t/\-\-test] [\-v/\-\-verbose]
VolumeGroupName [VolumeGroupName...]
.SH DESCRIPTION
vgremove allows you to remove one or more volume groups.
The volume group(s) must not have any logical volumes allocated:
Remove them first with \fBlvremove\fP. If one or more physical
volumes in the volume group are lost, consider
\fBvgreduce --removemissing\fP to make the volume group
If one or more physical volumes in the volume group are lost,
consider \fBvgreduce --removemissing\fP to make the volume group
metadata consistent again.
.sp
If there are logical volumes that exist in the volume group,
a prompt will be given to confirm removal. You can override
the prompt with \fB-f\fP.
.SH OPTIONS
See \fBlvm\fP for common options.
.TP
.BR \-f ", " \-\-force
Force the removal of any logical volumes on the volume group
without confirmation.
.SH SEE ALSO
.BR lvm (8),
.BR lvremove (8),

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

@@ -1,7 +1,7 @@
#
# Copyright (C) 2006 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

@@ -17,7 +17,7 @@
# the debugging of lvm issues.
# following external commands are used throughout the script
# which, echo and test are internal in bash at least
# echo and test are internal in bash at least
MKDIR=mkdir # need -p
TAR=tar # need czf
RM=rm # need -rf
@@ -43,12 +43,8 @@ die() {
exit $code
}
# which should error out if the binary is not executable, although i
# am not sure we can rely on this
which $LVM >& /dev/null || die 2 "Fatal: could not find lvm binary '$LVM'"
test -x `which $LVM` || die 2 "Fatal: lvm binary '$LVM' not executable"
which $DMSETUP >& /dev/null || die 2 "Fatal: could not find dmsetup binary '$DMSETUP'"
test -x `which $DMSETUP` || die 2 "Fatal: dmsetup binary '$DMSETUP' not executable"
"$LVM" version >& /dev/null || die 2 "Could not run lvm binary '$LVM'"
"$DMSETUP" version >& /dev/null || DMSETUP=:
function usage {
echo "$0 [options]"
@@ -95,15 +91,24 @@ log="$dir/lvmdump.log"
myecho() {
echo "$@"
echo "$@" >> $log
echo "$@" >> "$log"
}
log() {
echo "$@" >> $log
echo "$@" >> "$log"
eval "$@"
}
echo " "
warnings() {
if test "$UID" != "0" && test "$EUID" != "0"; then
myecho "WARNING! Running as non-privileged user, dump is likely incomplete!"
elif test "$DMSETUP" = ":"; then
myecho "WARNING! Could not run dmsetup, dump is likely incomplete."
fi
}
warnings
myecho "Creating dump directory: $dir"
echo " "
@@ -111,19 +116,19 @@ if (( $advanced )); then
myecho "Gathering LVM volume info..."
myecho " vgscan..."
log "$LVM vgscan -vvvv > $dir/vgscan 2>&1"
log "\"$LVM\" vgscan -vvvv > \"$dir/vgscan\" 2>&1"
myecho " pvscan..."
log "$LVM pvscan -v >> $dir/pvscan 2>> $log"
log "\"$LVM\" pvscan -v >> \"$dir/pvscan\" 2>> \"$log\""
myecho " lvs..."
log "$LVM lvs -a -o +devices >> $dir/lvs 2>> $log"
log "\"$LVM\" lvs -a -o +devices >> \"$dir/lvs\" 2>> \"$log\""
myecho " pvs..."
log "$LVM pvs -a -v > $dir/pvs 2>> $log"
log "\"$LVM\" pvs -a -v > \"$dir/pvs\" 2>> \"$log\""
echo " vgs..."
log "$LVM vgs -v > $dir/vgs 2>> $log"
myecho " vgs..."
log "\"$LVM\" vgs -v > \"$dir/vgs\" 2>> \"$log\""
fi
if (( $clustered )); then
@@ -133,7 +138,7 @@ if (( $clustered )); then
for i in nodes status services; do
cap_i=$(echo $i|tr a-z A-Z)
printf "$cap_i:\n----------------------------------\n"
log "cman_tool $i 2>> $log"
log "cman_tool $i 2>> \"$log\""
echo
done
@@ -165,65 +170,64 @@ if (( $clustered )); then
fi
myecho "Gathering LVM & device-mapper version info..."
echo "LVM VERSION:" > $dir/versions
$LVM lvs --version >> $dir/versions 2>> $log
echo "DEVICE MAPPER VERSION:" >> $dir/versions
$DMSETUP --version >> $dir/versions 2>> $log
echo "KERNEL VERSION:" >> $dir/versions
$UNAME -a >> $dir/versions 2>> $log
echo "DM TARGETS VERSIONS:" >> $dir/versions
$DMSETUP targets >> $dir/versions 2>> $log
echo "LVM VERSION:" > "$dir/versions"
"$LVM" lvs --version >> "$dir/versions" 2>> "$log"
echo "DEVICE MAPPER VERSION:" >> "$dir/versions"
"$DMSETUP" --version >> "$dir/versions" 2>> "$log"
echo "KERNEL VERSION:" >> "$dir/versions"
"$UNAME" -a >> "$dir/versions" 2>> "$log"
echo "DM TARGETS VERSIONS:" >> "$dir/versions"
"$DMSETUP" targets >> "$dir/versions" 2>> "$log"
myecho "Gathering dmsetup info..."
log "$DMSETUP info -c > $dir/dmsetup_info 2>> $log"
log "$DMSETUP table > $dir/dmsetup_table 2>> $log"
log "$DMSETUP status > $dir/dmsetup_status 2>> $log"
log "\"$DMSETUP\" info -c > \"$dir/dmsetup_info\" 2>> \"$log\""
log "\"$DMSETUP\" table > \"$dir/dmsetup_table\" 2>> \"$log\""
log "\"$DMSETUP\" status > \"$dir/dmsetup_status\" 2>> \"$log\""
myecho "Gathering process info..."
log "$PS alx > $dir/ps_info 2>> $log"
log "$PS alx > \"$dir/ps_info\" 2>> \"$log\""
myecho "Gathering console messages..."
log "$TAIL -n 75 /var/log/messages > $dir/messages 2>> $log"
log "$TAIL -n 75 /var/log/messages > \"$dir/messages\" 2>> \"$log\""
myecho "Gathering /etc/lvm info..."
log "$CP -a /etc/lvm $dir/lvm 2>> $log"
log "$CP -a /etc/lvm \"$dir/lvm\" 2>> \"$log\""
myecho "Gathering /dev listing..."
log "$LS -laR /dev > $dir/dev_listing 2>> $log"
log "$LS -laR /dev > \"$dir/dev_listing\" 2>> \"$log\""
myecho "Gathering /sys/block listing..."
log "$LS -laR /sys/block > $dir/sysblock_listing"
log "$LS -laR /sys/block > \"$dir/sysblock_listing\""
if (( $metadata )); then
myecho "Gathering LVM metadata from Physical Volumes..."
log "$MKDIR -p $dir/metadata"
log "$MKDIR -p \"$dir/metadata\""
pvs="$($LVM pvs --separator , --noheadings --units s --nosuffix -o \
name,pe_start 2>> $log | $SED -e 's/^ *//')"
pvs="$("$LVM" pvs --separator , --noheadings --units s --nosuffix -o \
name,pe_start 2>> "$log" | $SED -e 's/^ *//')"
for line in "$pvs"
do
test -z "$line" && continue
pv="$(echo $line | $CUT -d, -f1)"
pe_start="$(echo $line | $CUT -d, -f2)"
name="$($BASENAME $pv)"
name="$($BASENAME "$pv")"
myecho " $pv"
log "$DD if=$pv of=$dir/metadata/$name bs=512 count=$pe_start 2>> $log"
log "$DD if=$pv \"of=$dir/metadata/$name\" bs=512 count=$pe_start 2>> \"$log\""
done
fi
if test -z "$userdir"; then
lvm_dump="$dirbase.tgz"
myecho "Creating report tarball in $HOME/$lvm_dump..."
cd $HOME
$TAR czf $lvm_dump $dirbase 2>/dev/null
$RM -rf $dir
fi
if test "$UID" != "0" && test "$EUID" != "0"; then
myecho
myecho "WARNING! Running as non-privileged user, dump is likely incomplete!"
myecho
warnings
if test -z "$userdir"; then
cd "$HOME"
"$TAR" czf "$lvm_dump" "$dirbase" 2>/dev/null
"$RM" -rf "$dir"
fi
exit 0

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