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

Compare commits

...

148 Commits

Author SHA1 Message Date
Alasdair Kergon
897fc59f72 pre-release 2007-12-20 15:12:57 +00:00
Alasdair Kergon
947e44ae67 tweak usage text 2007-12-17 14:47:22 +00:00
Alasdair Kergon
e44843beba replace fsadm.c with fsadm.sh 2007-12-17 12:31:50 +00:00
Alasdair Kergon
147482ea69 Build changes to replace fsadm C program with shell script. 2007-12-17 12:23:24 +00:00
Alasdair Kergon
09091c5cf8 Append fields to report/pvsegs_cols_verbose.
Permit LV segment fields with PV segment reports.
  Add seg_start_pe and seg_pe_ranges to reports.
2007-12-14 21:53:02 +00:00
Alasdair Kergon
50827a5f69 more readahead node fixes/debug messages 2007-12-14 19:49:27 +00:00
Alasdair Kergon
2d6444c924 Fix deptree to pass new name to _resume_node after a rename. 2007-12-14 17:57:04 +00:00
Alasdair Kergon
1d2675d9aa Add node operation stack debug messages. 2007-12-14 17:26:09 +00:00
Alasdair Kergon
ad98990a8e Report error when empty device name passed to readahead functions. 2007-12-13 02:25:45 +00:00
Alasdair Kergon
8e58c143f2 post-release 2007-12-05 22:48:06 +00:00
Alasdair Kergon
556a4a2395 clarify 2007-12-05 22:45:56 +00:00
Alasdair Kergon
5be987b40f pre-release
N.B. This is a big release and some regressions are inevitable.
2007-12-05 22:19:24 +00:00
Alasdair Kergon
066bc35e69 export can_split parameter until rest of pvmove allocation restructuring gets done 2007-12-05 22:11:20 +00:00
Alasdair Kergon
403779437c round readahead to multiple of page size in tools 2007-12-05 19:24:32 +00:00
Alasdair Kergon
fb806f61d4 Fix minimum readahead debug message. 2007-12-05 18:57:34 +00:00
Alasdair Kergon
6ce306661c post-release 2007-12-05 17:14:30 +00:00
Alasdair Kergon
3c08ff94d4 pre-release 2007-12-05 17:05:04 +00:00
Alasdair Kergon
a6afae2356 clarify when read_ahead may be set 2007-12-05 16:28:19 +00:00
Alasdair Kergon
0eea7070a7 work out device name to use for read ahead request 2007-12-05 16:24:41 +00:00
Alasdair Kergon
105c2b1eea read_ahead in report with underscore to match lvm2 field 2007-12-05 14:42:10 +00:00
Alasdair Kergon
82bb0e8dda fix ioctls to use long not int
update dm-ioctl.h after compat tidy-up
2007-12-05 14:11:26 +00:00
Patrick Caulfield
8c01179075 Tidy the clvmd backup code.
Move the backups inside the protection of the VG lock,
Don't backup if we have a suspended LV
Correct the vg_read() call
2007-12-05 13:17:18 +00:00
Jim Meyering
c9d9a96630 Avoid spurious test failure when compiled with readline support.
* test/t-000-basic.sh: Invoke initial test of lvm with its "version"
argument, so that the behavior of the tool doesn't depend on whether
readline was enabled at configure time.


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


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


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

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

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

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


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


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


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


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


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


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

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


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


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


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


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


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

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


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


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

View File

@@ -2,7 +2,7 @@
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
# Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
#
# This file is part of the LVM2.
# This file is part of LVM2.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
@@ -68,3 +68,6 @@ cscope.out: tools
@CSCOPE_CMD@ -b -R
all: cscope.out
endif
check: all
$(MAKE) -C test all

View File

@@ -1 +1 @@
2.02.28-cvs (2007-07-17)
2.02.30-cvs (2007-12-05)

109
WHATS_NEW
View File

@@ -1,27 +1,104 @@
Version 2.02.28 -
================================
Version 2.02.30 -
===================================
Replace tools/fsadm with scripts/fsadm.sh.
Append fields to report/pvsegs_cols_verbose.
Permit LV segment fields with PV segment reports.
Add seg_start_pe and seg_pe_ranges to reports.
Version 2.02.29 - 5th December 2007
===================================
Make clvmd backup vg metadata on remote nodes.
Refactor pvmove allocation code.
Decode cluster locking state in log message.
Change file locking state messages from debug to very verbose.
Fix --addtag to drop @ prefix from name.
Stop clvmd going haywire if a pre_function fails.
Convert some vg_reads into vg_lock_and_reads.
Avoid nested vg_reads when processing PVs in VGs and fix associated locking.
Accept sizes with --readahead argument.
Store size arguments as sectors internally.
Attempt to remove incomplete LVs with lvcreate zeroing/activation problems.
Add read_ahead activation code.
Add activation/readahead configuration option and FMT_RESTRICTED_READAHEAD.
Extend readahead arg to accept "auto" and "none".
Add lv_read_ahead and lv_kernel_read_ahead fields to reports and lvdisplay.
Prevent lvconvert -s from using same LV as origin and snapshot.
Fix human-readable output of odd numbers of sectors.
Add pv_mda_free and vg_mda_free fields to reports for raw text format.
Add LVM2 version to 'Generated by' comment in metadata.
Show 'not usable' space when PV is too large for device in pvdisplay.
Ignore and fix up any excessive device size found in metadata.
Fix error message when fixing up PV size in lvm2 metadata (2.02.11).
Fix orphan-related locking in pvdisplay and pvs.
Fix missing VG unlocks in some pvchange error paths.
Add some missing validation of VG names.
Rename validate_vg_name() to validate_new_vg_name().
Change orphan lock to VG_ORPHANS.
Change format1 to use ORPHAN as orphan VG name.
Convert pvchange, pvdisplay, pvscan to use is_orphan()
Add is_orphan_vg() and change all hard-coded checks to use it.
Detect md superblocks version 1.0, 1.1 and 1.2.
Add _alloc_pv() and _free_pv() from _pv_create() code and fix error paths.
Add pv_dev_name() to access PV device name.
Add const attributes to pv accessor functions.
Refactor vg_add_snapshot() and lv_create_empty().
Handle new sysfs subsystem/block/devices directory structure.
Run test with LVM_SYSTEM_DIR pointing to private root and /dev dirs.
Fix a bug in lvm_dump.sh checks for lvm/dmsetup binaries.
Fix underquotations in lvm_dump.sh.
Refactor lvcreate stripe and mirror parameter validation.
Print --help output to stdout, not stderr.
After a cmdline processing error, don't print help text but suggest --help.
Add %PVS extents option to lvresize, lvextend, and lvcreate.
Add 'make check' to run tests in new subdirectory 'test'.
Moved the obsolete test subdirectory to old-tests.
Cope with relative paths in configure --with-dmdir.
Remove no-longer-correct restrictions on PV arg count with stripes/mirrors.
Fix strdup memory leak in str_list_dup().
Link with -lpthread when static SELinux libraries require that.
Detect command line PE values that exceed their 32-bit range.
Include strerror string in dev_open_flags' stat failure message.
Move guts of pvresize into library.
Avoid error when --corelog is provided without --mirrorlog. (2.02.28)
Correct --mirrorlog argument name in man pages (not --log).
Clear MIRROR_NOTSYNCED LV flag when converting from mirror to linear.
Modify lvremove to prompt for removal if LV active on other cluster nodes.
Add '-f' to vgremove to force removal of VG even if LVs exist.
Version 2.02.28 - 24th August 2007
==================================
Fix clvmd logging so you can get lvm-level debugging out of it.
Introduce VG_GLOBAL lock type for vgscan/pvscan to trigger clvmd -R.
Change locking_flags from int to uint32_t.
Fix clvmd -R, so it fully refreshes the caches.
Change lvconvert_mirrors to use mirror segtype not striped.
Fix lvconvert_mirrors detection of number of existing mirrors.
Clean up numerous compiler warnings that appeared in recent releases.
Remove several unused parameters from _allocate().
Only permit --force, --verbose and --debug arguments to be repeated.
Fix inconsistent licence notices: executables are GPLv2; libraries LGPLv2.1.
Move guts of lvremove into library.
Allow clvmd debug to be turned on in a running daemon using clvmd -d
Move guts of vgremove and lvremove into library, including yes_no_prompt.
Allow clvmd debug to be turned on in a running daemon using clvmd -d [-C].
Update to use autoconf 2.61, while still supporting 2.57.
Add more cluster info to lvmdump
Add const attributes where possible, first cut.
Add more cluster info to lvmdump.
Add further const attributes throughout.
Add support for renaming mirrored LVs.
Factor out core of lvrename() to lv_rename lvm library function.
Add --log argument to specify log type for mirrors.
Don't try to monitor devices which we failed to create.
Don't leak a file descriptor in fcntl_lock_file(), when fcntl fails.
Remove create_dir function; use now-equivalent dm_create_dir instead
Detect stream write failure reliably; new fn: lvm_fclose; use dm_fclose
Factor out core of lvrename() to library function.
Add --mirrorlog argument to specify log type for mirrors.
Don't attempt to monitor devices if their creation failed in _lv_activate.
Don't leak a file descriptor in fcntl_lock_file() when fcntl fails.
Replace create_dir with dm_create_dir.
Detect stream write failure reliably with lvm_fclose using dm_fclose.
Fix clvmd if compiled with gulm support. (2.02.26)
Trivial fix to lvdisplay man page.
Fix lvdisplay man page to say LV size is reported in sectors, not KB.
Add vg_lock_and_read() external library function.
Fix loading of persistent cache if cache_dir is used. (2.02.23)
Eliminate uses of strdup+basename. Use last_path_component instead.
Reduce _compare_paths lstat error message from log_error to log_very_verbose.
Create util.h with last_path_component replacing strdup + basename.
Use gcc's printf attribute wherever possible.
In _line_append, use "sizeof buf - 1" rather than equivalent "4095"
In _line_append, use "sizeof buf - 1" rather than equivalent "4095".
Introduce is_same_inode macro, now including a comparison of st_dev.
Don't leak a file descriptor in _lock_file(), when flock fails.
Don't leak a file descriptor in _lock_file() when flock fails.
Add SUN's LDOM virtual block device (vdisk) and ps3disk to filters.
Split metadata-external.h out from metadata.h for the tools to use.

View File

@@ -1,3 +1,22 @@
Version 1.02.24 - 20th December 2007
====================================
Fix deptree to pass new name to _resume_node after a rename.
Suppress other node operations if node is deleted.
Add node operation stack debug messages.
Report error when empty device name passed to readahead functions.
Fix minimum readahead debug message.
Version 1.02.23 - 5th December 2007
===================================
Update dm-ioctl.h after removal of compat code.
Add readahead support to libdevmapper and dmsetup.
Fix double free in a libdevmapper-event error path.
Fix configure --with-dmeventd-path substitution.
Allow a DM_DEV_DIR environment variable to override /dev in dmsetup.
Create a libdevmapper.so.$LIB_VERSION symlink within the build tree.
Avoid static link failure with some SELinux libraries that require libpthread.
Remove obsolete dmfs code from tree and update INSTALL.
Version 1.02.22 - 21st August 2007
==================================
Fix inconsistent licence notices: executables are GPLv2; libraries LGPLv2.1.

364
configure vendored
View File

@@ -719,6 +719,7 @@ CLVMD
CLUSTER
FSADM
DMEVENTD
LIB_PTHREAD
LTLIBOBJS'
ac_subst_files=''
ac_precious_vars='build_alias
@@ -8066,8 +8067,8 @@ fi
echo "${ECHO_T}$CMDLIB" >&6; }
################################################################################
{ echo "$as_me:$LINENO: checking whether to build fsadm" >&5
echo $ECHO_N "checking whether to build fsadm... $ECHO_C" >&6; }
{ echo "$as_me:$LINENO: checking whether to install fsadm" >&5
echo $ECHO_N "checking whether to install fsadm... $ECHO_C" >&6; }
# Check whether --enable-fsadm was given.
if test "${enable_fsadm+set}" = set; then
enableval=$enable_fsadm; FSADM=$enableval
@@ -8852,6 +8853,99 @@ _ACEOF
{ echo "$as_me:$LINENO: WARNING: Disabling selinux" >&5
echo "$as_me: WARNING: Disabling selinux" >&2;}
fi
# With --enable-static_link and selinux enabled, linking lvm.static
# fails on at least Debian unstable due to unsatisfied references
# to pthread_mutex_lock and _unlock. See if we need -lpthread.
if test "$STATIC_LINK-$HAVE_SELINUX" = yes-yes; then
lvm_saved_libs=$LIBS
LIBS="$LIBS -static"
{ echo "$as_me:$LINENO: checking for library containing pthread_mutex_lock" >&5
echo $ECHO_N "checking for library containing pthread_mutex_lock... $ECHO_C" >&6; }
if test "${ac_cv_search_pthread_mutex_lock+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_func_search_save_LIBS=$LIBS
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char pthread_mutex_lock ();
int
main ()
{
return pthread_mutex_lock ();
;
return 0;
}
_ACEOF
for ac_lib in '' pthread; do
if test -z "$ac_lib"; then
ac_res="none required"
else
ac_res=-l$ac_lib
LIBS="-l$ac_lib $ac_func_search_save_LIBS"
fi
rm -f conftest.$ac_objext conftest$ac_exeext
if { (ac_try="$ac_link"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_link") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest$ac_exeext &&
$as_test_x conftest$ac_exeext; then
ac_cv_search_pthread_mutex_lock=$ac_res
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
fi
rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
conftest$ac_exeext
if test "${ac_cv_search_pthread_mutex_lock+set}" = set; then
break
fi
done
if test "${ac_cv_search_pthread_mutex_lock+set}" = set; then
:
else
ac_cv_search_pthread_mutex_lock=no
fi
rm conftest.$ac_ext
LIBS=$ac_func_search_save_LIBS
fi
{ echo "$as_me:$LINENO: result: $ac_cv_search_pthread_mutex_lock" >&5
echo "${ECHO_T}$ac_cv_search_pthread_mutex_lock" >&6; }
ac_res=$ac_cv_search_pthread_mutex_lock
if test "$ac_res" != no; then
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
test "$ac_cv_search_pthread_mutex_lock" = "none required" ||
LIB_PTHREAD=-lpthread
fi
LIBS=$lvm_saved_libs
fi
fi
################################################################################
@@ -9365,6 +9459,12 @@ else
fi
# Convert a relative dir name to absolute.
case $DMDIR in
/*) ;;
*) DMDIR="`pwd`/$DMDIR" ;;
esac
################################################################################
if test x$READLINE = xyes; then
@@ -10095,253 +10195,6 @@ rm -f conftest*
fi
if test x$FSADM = xyes; then
for ac_header in fstab.h sys/mount.h sys/vfs.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
{ echo "$as_me:$LINENO: checking for $ac_header" >&5
echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
echo $ECHO_N "(cached) $ECHO_C" >&6
fi
ac_res=`eval echo '${'$as_ac_Header'}'`
{ echo "$as_me:$LINENO: result: $ac_res" >&5
echo "${ECHO_T}$ac_res" >&6; }
else
# Is the header compilable?
{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
$ac_includes_default
#include <$ac_header>
_ACEOF
rm -f conftest.$ac_objext
if { (ac_try="$ac_compile"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_compile") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest.$ac_objext; then
ac_header_compiler=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_header_compiler=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
echo "${ECHO_T}$ac_header_compiler" >&6; }
# Is the header present?
{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <$ac_header>
_ACEOF
if { (ac_try="$ac_cpp conftest.$ac_ext"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } >/dev/null && {
test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
test ! -s conftest.err
}; then
ac_header_preproc=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_header_preproc=no
fi
rm -f conftest.err conftest.$ac_ext
{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
echo "${ECHO_T}$ac_header_preproc" >&6; }
# So? What about this header?
case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
yes:no: )
{ echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
ac_header_preproc=yes
;;
no:yes:* )
{ echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
;;
esac
{ echo "$as_me:$LINENO: checking for $ac_header" >&5
echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
eval "$as_ac_Header=\$ac_header_preproc"
fi
ac_res=`eval echo '${'$as_ac_Header'}'`
{ echo "$as_me:$LINENO: result: $ac_res" >&5
echo "${ECHO_T}$ac_res" >&6; }
fi
if test `eval echo '${'$as_ac_Header'}'` = yes; then
cat >>confdefs.h <<_ACEOF
#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF
else
{ { echo "$as_me:$LINENO: error: bailing out" >&5
echo "$as_me: error: bailing out" >&2;}
{ (exit 1); exit 1; }; }
fi
done
for ac_func in memmove
do
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
{ echo "$as_me:$LINENO: checking for $ac_func" >&5
echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
For example, HP-UX 11i <limits.h> declares gettimeofday. */
#define $ac_func innocuous_$ac_func
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func (); below.
Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
<limits.h> exists even on freestanding compilers. */
#ifdef __STDC__
# include <limits.h>
#else
# include <assert.h>
#endif
#undef $ac_func
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char $ac_func ();
/* The GNU C library defines this for functions which it implements
to always fail with ENOSYS. Some functions are actually named
something starting with __ and the normal name is an alias. */
#if defined __stub_$ac_func || defined __stub___$ac_func
choke me
#endif
int
main ()
{
return $ac_func ();
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (ac_try="$ac_link"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_link") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest$ac_exeext &&
$as_test_x conftest$ac_exeext; then
eval "$as_ac_var=yes"
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
eval "$as_ac_var=no"
fi
rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
conftest$ac_exeext conftest.$ac_ext
fi
ac_res=`eval echo '${'$as_ac_var'}'`
{ echo "$as_me:$LINENO: result: $ac_res" >&5
echo "${ECHO_T}$ac_res" >&6; }
if test `eval echo '${'$as_ac_var'}'` = yes; then
cat >>confdefs.h <<_ACEOF
#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
else
{ { echo "$as_me:$LINENO: error: bailing out" >&5
echo "$as_me: error: bailing out" >&2;}
{ (exit 1); exit 1; }; }
fi
done
fi
if test x$CLUSTER != xnone; then
@@ -11269,10 +11122,11 @@ fi
################################################################################
ac_config_files="$ac_config_files Makefile make.tmpl daemons/Makefile daemons/clvmd/Makefile dmeventd/Makefile dmeventd/mirror/Makefile doc/Makefile include/Makefile lib/Makefile lib/format1/Makefile lib/format_pool/Makefile lib/locking/Makefile lib/mirror/Makefile lib/snapshot/Makefile man/Makefile po/Makefile scripts/Makefile tools/Makefile tools/version.h tools/fsadm/Makefile test/mm/Makefile test/device/Makefile test/format1/Makefile test/regex/Makefile test/filters/Makefile"
ac_config_files="$ac_config_files Makefile make.tmpl daemons/Makefile daemons/clvmd/Makefile dmeventd/Makefile dmeventd/mirror/Makefile doc/Makefile include/Makefile lib/Makefile lib/format1/Makefile lib/format_pool/Makefile lib/locking/Makefile lib/mirror/Makefile lib/snapshot/Makefile test/Makefile man/Makefile po/Makefile scripts/Makefile tools/Makefile tools/version.h"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
@@ -11842,17 +11696,12 @@ do
"lib/locking/Makefile") CONFIG_FILES="$CONFIG_FILES lib/locking/Makefile" ;;
"lib/mirror/Makefile") CONFIG_FILES="$CONFIG_FILES lib/mirror/Makefile" ;;
"lib/snapshot/Makefile") CONFIG_FILES="$CONFIG_FILES lib/snapshot/Makefile" ;;
"test/Makefile") CONFIG_FILES="$CONFIG_FILES test/Makefile" ;;
"man/Makefile") CONFIG_FILES="$CONFIG_FILES man/Makefile" ;;
"po/Makefile") CONFIG_FILES="$CONFIG_FILES po/Makefile" ;;
"scripts/Makefile") CONFIG_FILES="$CONFIG_FILES scripts/Makefile" ;;
"tools/Makefile") CONFIG_FILES="$CONFIG_FILES tools/Makefile" ;;
"tools/version.h") CONFIG_FILES="$CONFIG_FILES tools/version.h" ;;
"tools/fsadm/Makefile") CONFIG_FILES="$CONFIG_FILES tools/fsadm/Makefile" ;;
"test/mm/Makefile") CONFIG_FILES="$CONFIG_FILES test/mm/Makefile" ;;
"test/device/Makefile") CONFIG_FILES="$CONFIG_FILES test/device/Makefile" ;;
"test/format1/Makefile") CONFIG_FILES="$CONFIG_FILES test/format1/Makefile" ;;
"test/regex/Makefile") CONFIG_FILES="$CONFIG_FILES test/regex/Makefile" ;;
"test/filters/Makefile") CONFIG_FILES="$CONFIG_FILES test/filters/Makefile" ;;
*) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
@@ -12060,10 +11909,11 @@ CLVMD!$CLVMD$ac_delim
CLUSTER!$CLUSTER$ac_delim
FSADM!$FSADM$ac_delim
DMEVENTD!$DMEVENTD$ac_delim
LIB_PTHREAD!$LIB_PTHREAD$ac_delim
LTLIBOBJS!$LTLIBOBJS$ac_delim
_ACEOF
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 9; then
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 10; then
break
elif $ac_last_try; then
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5

View File

@@ -1,8 +1,8 @@
##
## Copyright (C) 2000-2004 Sistina Software, Inc. All rights reserved.
## Copyright (C) 2004 Red Hat, Inc. All rights reserved.
## Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
##
## This file is part of the LVM2.
## This file is part of LVM2.
##
## This copyrighted material is made available to anyone wishing to use,
## modify, copy, or redistribute it subject to the terms and conditions
@@ -24,7 +24,7 @@ AC_CONFIG_HEADERS(lib/misc/configure.h)
################################################################################
dnl -- Setup the directory where autoconf has auxilary files
AC_CONFIG_AUX_DIR(autoconf)
AC_CONFIG_AUX_DIR(autoconf)
################################################################################
dnl -- Get system type
@@ -363,7 +363,7 @@ AC_MSG_RESULT($CMDLIB)
################################################################################
dnl -- Enable fsadm
AC_MSG_CHECKING(whether to build fsadm)
AC_MSG_CHECKING(whether to install fsadm)
AC_ARG_ENABLE(fsadm, [ --enable-fsadm Enable fsadm],
FSADM=$enableval)
AC_MSG_RESULT($FSADM)
@@ -453,6 +453,18 @@ if test x$SELINUX = xyes; then
else
AC_MSG_WARN(Disabling selinux)
fi
# With --enable-static_link and selinux enabled, linking lvm.static
# fails on at least Debian unstable due to unsatisfied references
# to pthread_mutex_lock and _unlock. See if we need -lpthread.
if test "$STATIC_LINK-$HAVE_SELINUX" = yes-yes; then
lvm_saved_libs=$LIBS
LIBS="$LIBS -static"
AC_SEARCH_LIBS([pthread_mutex_lock], [pthread],
[test "$ac_cv_search_pthread_mutex_lock" = "none required" ||
LIB_PTHREAD=-lpthread])
LIBS=$lvm_saved_libs
fi
fi
################################################################################
@@ -526,6 +538,12 @@ AC_ARG_WITH(dmdir,
[ DMDIR="$withval" CPPFLAGS="$CPPFLAGS -I$DMDIR/include"],
[ DMDIR= ])
# Convert a relative dir name to absolute.
case $DMDIR in
/*) ;;
*) DMDIR="`pwd`/$DMDIR" ;;
esac
################################################################################
dnl -- Ensure additional headers required
if test x$READLINE = xyes; then
@@ -540,11 +558,6 @@ if test x$CLVMD != xnone; then
AC_FUNC_SELECT_ARGTYPES
fi
if test x$FSADM = xyes; then
AC_CHECK_HEADERS(fstab.h sys/mount.h sys/vfs.h,,AC_MSG_ERROR(bailing out))
AC_CHECK_FUNCS(memmove,,AC_MSG_ERROR(bailing out))
fi
if test x$CLUSTER != xnone; then
AC_CHECK_HEADERS(sys/socket.h sys/un.h,,AC_MSG_ERROR(bailing out))
AC_CHECK_FUNCS(socket,,AC_MSG_ERROR(bailing out))
@@ -617,36 +630,32 @@ 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
])
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

@@ -115,8 +115,13 @@ int do_command(struct local_client *client, struct clvm_header *msg, int msglen,
break;
case CLVMD_CMD_LOCK_VG:
lockname = &args[2];
/* Check to see if the VG is in use by LVM1 */
status = do_check_lvm1(&args[2]);
status = do_check_lvm1(lockname);
/* P_global causes a cache refresh */
if (strcmp(lockname, "P_global") == 0)
do_refresh_cache();
break;
case CLVMD_CMD_LOCK_LV:
@@ -148,6 +153,10 @@ int do_command(struct local_client *client, struct clvm_header *msg, int msglen,
*retlen = strlen(*buf)+1;
break;
case CLVMD_CMD_VG_BACKUP:
lvm_do_backup(&args[2]);
break;
default:
/* Won't get here because command is validated in pre_command */
break;
@@ -255,6 +264,7 @@ int do_pre_command(struct local_client *client)
case CLVMD_CMD_REFRESH:
case CLVMD_CMD_GET_CLUSTERNAME:
case CLVMD_CMD_SET_DEBUG:
case CLVMD_CMD_VG_BACKUP:
break;
default:
@@ -284,6 +294,7 @@ int do_post_command(struct local_client *client)
break;
case CLVMD_CMD_LOCK_VG:
case CLVMD_CMD_VG_BACKUP:
/* Nothing to do here */
break;

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.
*
@@ -42,9 +42,11 @@
/* LVM2 headers */
#include "toolcontext.h"
#include "lvmcache.h"
#include "log.h"
#include "activate.h"
#include "locking.h"
#include "archiver.h"
#include "defaults.h"
static struct cmd_context *cmd = NULL;
@@ -52,6 +54,7 @@ static struct dm_hash_table *lv_hash = NULL;
static pthread_mutex_t lv_hash_lock;
static pthread_mutex_t lvm_lock;
static char last_error[1024];
static int suspended = 0;
struct lv_info {
int lock_id;
@@ -222,7 +225,7 @@ static int do_activate_lv(char *resource, unsigned char lock_flags, int mode)
}
/* If it's suspended then resume it */
if (!lv_info_by_lvid(cmd, resource, &lvi, 0))
if (!lv_info_by_lvid(cmd, resource, &lvi, 0, 0))
return EIO;
if (lvi.suspended)
@@ -268,7 +271,7 @@ static int do_suspend_lv(char *resource)
}
/* Only suspend it if it exists */
if (!lv_info_by_lvid(cmd, resource, &lvi, 0))
if (!lv_info_by_lvid(cmd, resource, &lvi, 0, 0))
return EIO;
if (lvi.exists) {
@@ -338,11 +341,15 @@ int do_lock_lv(unsigned char command, unsigned char lock_flags, char *resource)
case LCK_LV_SUSPEND:
status = do_suspend_lv(resource);
if (!status)
suspended++;
break;
case LCK_UNLOCK:
case LCK_LV_RESUME: /* if active */
status = do_resume_lv(resource);
if (!status)
suspended--;
break;
case LCK_LV_ACTIVATE:
@@ -413,7 +420,7 @@ int post_lock_lv(unsigned char command, unsigned char lock_flags,
struct lvinfo lvi;
pthread_mutex_lock(&lvm_lock);
status = lv_info_by_lvid(cmd, resource, &lvi, 0);
status = lv_info_by_lvid(cmd, resource, &lvi, 0, 0);
pthread_mutex_unlock(&lvm_lock);
if (!status)
return EIO;
@@ -442,9 +449,15 @@ int do_check_lvm1(const char *vgname)
int do_refresh_cache()
{
int ret;
DEBUGLOG("Refreshing context\n");
log_notice("Refreshing context");
return refresh_toolcontext(cmd)==1?0:-1;
ret = refresh_toolcontext(cmd);
init_full_scan_done(0);
lvmcache_label_scan(cmd, 2);
return ret==1?0:-1;
}
@@ -541,6 +554,15 @@ static void *get_initial_state()
static void lvm2_log_fn(int level, const char *file, int line,
const char *message)
{
/* Send messages to the normal LVM2 logging system too,
so we get debug output when it's asked for.
We need to NULL the function ptr otherwise it will just call
back into here! */
init_log_fn(NULL);
print_log(level, file, line, "%s", message);
init_log_fn(lvm2_log_fn);
/*
* Ignore non-error messages, but store the latest one for returning
* to the user.
@@ -584,6 +606,24 @@ void init_lvhash()
pthread_mutex_init(&lvm_lock, NULL);
}
/* Backups up the LVM metadata if it's changed */
void lvm_do_backup(const char *vgname)
{
struct volume_group * vg;
int consistent = 0;
DEBUGLOG("Triggering backup of VG metadata for %s. suspended=%d\n", vgname, suspended);
vg = vg_read(cmd, vgname, NULL /*vgid*/, &consistent);
if (vg) {
if (consistent)
check_current_backup(vg);
}
else {
log_error("Error backing up metadata, can't find VG for group %s", vgname);
}
}
/* Called to initialise the LVM context of the daemon */
int init_lvm(int using_gulm)
{
@@ -594,7 +634,13 @@ int init_lvm(int using_gulm)
/* Use LOG_DAEMON for syslog messages instead of LOG_USER */
init_syslog(LOG_DAEMON);
init_debug(_LOG_ERR);
openlog("clvmd", LOG_PID, LOG_DAEMON);
init_debug(cmd->current_settings.debug);
init_verbose(cmd->current_settings.verbose + VERBOSE_BASE_LEVEL);
set_activation(cmd->current_settings.activation);
archive_enable(cmd, cmd->current_settings.archive);
backup_enable(cmd, cmd->current_settings.backup);
cmd->cmd_line = (char *)"clvmd";
/* Check lvm.conf is setup for cluster-LVM */
check_config();

View File

@@ -28,7 +28,7 @@ extern int do_check_lvm1(const char *vgname);
extern int do_refresh_cache(void);
extern int init_lvm(int using_gulm);
extern void init_lvhash(void);
extern void lvm_do_backup(const char *vgname);
extern int hold_unlock(char *resource);
extern int hold_lock(char *resource, int mode, int flags);
extern void unlock_all(void);

View File

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

@@ -156,7 +156,7 @@ static int _parse_config_file(struct parser *p, struct config_tree *cft)
return 1;
}
struct config_tree *create_config_tree_from_string(struct cmd_context *cmd,
struct config_tree *create_config_tree_from_string(struct cmd_context *cmd __attribute((unused)),
const char *config_settings)
{
struct cs *c;
@@ -371,7 +371,7 @@ static int _line_append(struct output_line *outline, const char *fmt, ...)
va_start(ap, fmt);
n = vsnprintf(&buf[0], sizeof buf - 1, fmt, ap);
if (n < 0 || n > sizeof buf - 1) {
if (n < 0 || n > (int) sizeof buf - 1) {
log_error("vsnprintf failed for config line");
return 0;
}
@@ -1248,13 +1248,13 @@ static char _token_type_to_char(int type)
* Returns:
* # of 'type' tokens in 'str'.
*/
static unsigned _count_tokens (const char *str, unsigned len, int type)
static unsigned _count_tokens(const char *str, unsigned len, int type)
{
char c;
c = _token_type_to_char(type);
return(count_chars_len(str, len, c));
return count_chars_len(str, len, c);
}
/*

View File

@@ -39,6 +39,7 @@
#define DEFAULT_FALLBACK_TO_LOCAL_LOCKING 1
#define DEFAULT_FALLBACK_TO_CLUSTERED_LOCKING 1
#define DEFAULT_MIRRORLOG "disk"
#define DEFAULT_MIRROR_LOG_FAULT_POLICY "allocate"
#define DEFAULT_MIRROR_DEV_FAULT_POLICY "remove"
#define DEFAULT_DMEVENTD_MIRROR_LIB "libdevmapper-event-lvm2mirror.so"
@@ -62,6 +63,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
@@ -111,7 +113,7 @@
#define DEFAULT_VGS_COLS_VERB "vg_name,vg_attr,vg_extent_size,pv_count,lv_count,snap_count,vg_size,vg_free,vg_uuid"
#define DEFAULT_PVS_COLS_VERB "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,dev_size,pv_uuid"
#define DEFAULT_SEGS_COLS_VERB "lv_name,vg_name,lv_attr,seg_start,seg_size,stripes,segtype,stripesize,chunksize"
#define DEFAULT_PVSEGS_COLS_VERB "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,pvseg_start,pvseg_size"
#define DEFAULT_PVSEGS_COLS_VERB "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,pvseg_start,pvseg_size,lv_name,seg_start_pe,segtype,seg_pe_ranges"
#define DEFAULT_LVS_SORT "vg_name,lv_name"
#define DEFAULT_VGS_SORT "vg_name"

View File

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

@@ -67,7 +67,7 @@ static int _errseg_target_present(const struct lv_segment *seg __attribute((unus
#endif
static int _errseg_modules_needed(struct dm_pool *mem,
const struct lv_segment *seg,
const struct lv_segment *seg __attribute((unused)),
struct list *modules)
{
if (!str_list_add(mem, modules, "error")) {

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;
}
@@ -299,7 +357,7 @@ struct dev_filter *sysfs_filter_create(const char *proc)
#else
struct dev_filter *sysfs_filter_create(const char *proc)
struct dev_filter *sysfs_filter_create(const char *proc __attribute((unused)))
{
return NULL;
}

View File

@@ -80,7 +80,7 @@ static const device_info_t device_info[] = {
{NULL, 0}
};
static int _passes_lvm_type_device_filter(struct dev_filter *f,
static int _passes_lvm_type_device_filter(struct dev_filter *f __attribute((unused)),
struct device *dev)
{
const char *name = dev_name(dev);

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;
@@ -653,7 +653,7 @@ static int _write_pvd(struct disk_list *data)
/*
* assumes the device has been opened.
*/
static int __write_all_pvd(const struct format_type *fmt,
static int __write_all_pvd(const struct format_type *fmt __attribute((unused)),
struct disk_list *data)
{
const char *pv_name = dev_name(data->dev);

View File

@@ -175,7 +175,7 @@ static struct volume_group *_build_vg(struct format_instance *fid,
static struct volume_group *_format1_vg_read(struct format_instance *fid,
const char *vg_name,
struct metadata_area *mda)
struct metadata_area *mda __attribute((unused)))
{
struct dm_pool *mem = dm_pool_create("lvm1 vg_read", 1024 * 10);
struct list pvs;
@@ -261,7 +261,7 @@ static int _flatten_vg(struct format_instance *fid, struct dm_pool *mem,
}
static int _format1_vg_write(struct format_instance *fid, struct volume_group *vg,
struct metadata_area *mda)
struct metadata_area *mda __attribute((unused)))
{
struct dm_pool *mem = dm_pool_create("lvm1 vg_write", 1024 * 10);
struct list pvds;
@@ -284,7 +284,7 @@ static int _format1_vg_write(struct format_instance *fid, struct volume_group *v
}
static int _format1_pv_read(const struct format_type *fmt, const char *pv_name,
struct physical_volume *pv, struct list *mdas)
struct physical_volume *pv, struct list *mdas __attribute((unused)))
{
struct dm_pool *mem = dm_pool_create("lvm1 pv_read", 1024);
struct disk_list *dl;
@@ -325,9 +325,9 @@ static int _format1_pv_read(const struct format_type *fmt, const char *pv_name,
static int _format1_pv_setup(const struct format_type *fmt,
uint64_t pe_start, uint32_t extent_count,
uint32_t extent_size,
int pvmetadatacopies,
uint64_t pvmetadatasize, struct list *mdas,
struct physical_volume *pv, struct volume_group *vg)
int pvmetadatacopies __attribute((unused)),
uint64_t pvmetadatasize __attribute((unused)), struct list *mdas __attribute((unused)),
struct physical_volume *pv, struct volume_group *vg __attribute((unused)))
{
if (pv->size > MAX_PV_SIZE)
pv->size--;
@@ -381,7 +381,7 @@ static int _format1_lv_setup(struct format_instance *fid, struct logical_volume
}
static int _format1_pv_write(const struct format_type *fmt, struct physical_volume *pv,
struct list *mdas, int64_t sector)
struct list *mdas __attribute((unused)), int64_t sector __attribute((unused)))
{
struct dm_pool *mem;
struct disk_list *dl;
@@ -470,7 +470,7 @@ static int _format1_vg_setup(struct format_instance *fid, struct volume_group *v
return 1;
}
static int _format1_segtype_supported(struct format_instance *fid,
static int _format1_segtype_supported(struct format_instance *fid __attribute((unused)),
const struct segment_type *segtype)
{
if (!(segtype->flags & SEG_FORMAT1_SUPPORT)) {
@@ -487,9 +487,9 @@ static struct metadata_area_ops _metadata_format1_ops = {
};
static struct format_instance *_format1_create_instance(const struct format_type *fmt,
const char *vgname,
const char *vgid,
void *private)
const char *vgname __attribute((unused)),
const char *vgid __attribute((unused)),
void *private __attribute((unused)))
{
struct format_instance *fid;
struct metadata_area *mda;
@@ -516,7 +516,7 @@ static struct format_instance *_format1_create_instance(const struct format_type
return fid;
}
static void _format1_destroy_instance(struct format_instance *fid)
static void _format1_destroy_instance(struct format_instance *fid __attribute((unused)))
{
return;
}
@@ -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));
}
}
@@ -134,7 +137,7 @@ static int _system_id(struct cmd_context *cmd, char *s, const char *prefix)
return 1;
}
int export_pv(struct cmd_context *cmd, struct dm_pool *mem,
int export_pv(struct cmd_context *cmd, struct dm_pool *mem __attribute((unused)),
struct volume_group *vg,
struct pv_disk *pvd, struct physical_volume *pv)
{
@@ -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 =
@@ -588,7 +600,7 @@ int export_lvs(struct disk_list *dl, struct volume_group *vg,
/*
* FIXME: More inefficient code.
*/
int import_snapshots(struct dm_pool *mem, struct volume_group *vg,
int import_snapshots(struct dm_pool *mem __attribute((unused)), struct volume_group *vg,
struct list *pvds)
{
struct logical_volume *lvs[MAX_LV];
@@ -644,7 +656,7 @@ int import_snapshots(struct dm_pool *mem, struct volume_group *vg,
continue;
/* insert the snapshot */
if (!vg_add_snapshot(vg->fid, NULL, org, cow, NULL,
if (!vg_add_snapshot(NULL, org, cow, NULL,
org->le_count,
lvd->lv_chunk_size)) {
log_err("Couldn't add snapshot.");
@@ -679,7 +691,7 @@ int export_uuids(struct disk_list *dl, struct volume_group *vg)
* This calculates the nasty pv_number field
* used by LVM1.
*/
void export_numbers(struct list *pvds, struct volume_group *vg)
void export_numbers(struct list *pvds, struct volume_group *vg __attribute((unused)))
{
struct disk_list *dl;
int pv_num = 1;

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

@@ -30,7 +30,7 @@ static void _not_supported(const char *op)
op);
}
static int _lvm1_can_handle(struct labeller *l, void *buf, uint64_t sector)
static int _lvm1_can_handle(struct labeller *l __attribute((unused)), void *buf, uint64_t sector)
{
struct pv_disk *pvd = (struct pv_disk *) buf;
uint32_t version;
@@ -48,7 +48,7 @@ static int _lvm1_can_handle(struct labeller *l, void *buf, uint64_t sector)
return 0;
}
static int _lvm1_write(struct label *label, void *buf)
static int _lvm1_write(struct label *label __attribute((unused)), void *buf __attribute((unused)))
{
_not_supported("write");
return 0;
@@ -85,14 +85,14 @@ static int _lvm1_read(struct labeller *l, struct device *dev, void *buf,
return 1;
}
static int _lvm1_initialise_label(struct labeller *l, struct label *label)
static int _lvm1_initialise_label(struct labeller *l __attribute((unused)), struct label *label)
{
strcpy(label->type, "LVM1");
return 1;
}
static void _lvm1_destroy_label(struct labeller *l, struct label *label)
static void _lvm1_destroy_label(struct labeller *l __attribute((unused)), struct label *label __attribute((unused)))
{
return;
}

View File

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

@@ -33,8 +33,8 @@
#define CPOUT_64(x, y) {(y) = xlate64_be((x));}
static int __read_pool_disk(const struct format_type *fmt, struct device *dev,
struct dm_pool *mem, struct pool_list *pl,
const char *vg_name)
struct dm_pool *mem __attribute((unused)), struct pool_list *pl,
const char *vg_name __attribute((unused)))
{
char buf[512] __attribute((aligned(8)));

View File

@@ -172,7 +172,7 @@ static struct volume_group *_build_vg_from_pds(struct format_instance
static struct volume_group *_pool_vg_read(struct format_instance *fid,
const char *vg_name,
struct metadata_area *mda)
struct metadata_area *mda __attribute((unused)))
{
struct dm_pool *mem = dm_pool_create("pool vg_read", 1024);
struct list pds;
@@ -207,18 +207,22 @@ static struct volume_group *_pool_vg_read(struct format_instance *fid,
return vg;
}
static int _pool_pv_setup(const struct format_type *fmt,
uint64_t pe_start, uint32_t extent_count,
uint32_t extent_size,
int pvmetadatacopies,
uint64_t pvmetadatasize, struct list *mdas,
struct physical_volume *pv, struct volume_group *vg)
static int _pool_pv_setup(const struct format_type *fmt __attribute((unused)),
uint64_t pe_start __attribute((unused)),
uint32_t extent_count __attribute((unused)),
uint32_t extent_size __attribute((unused)),
int pvmetadatacopies __attribute((unused)),
uint64_t pvmetadatasize __attribute((unused)),
struct list *mdas __attribute((unused)),
struct physical_volume *pv __attribute((unused)),
struct volume_group *vg __attribute((unused)))
{
return 1;
}
static int _pool_pv_read(const struct format_type *fmt, const char *pv_name,
struct physical_volume *pv, struct list *mdas)
struct physical_volume *pv,
struct list *mdas __attribute((unused)))
{
struct dm_pool *mem = dm_pool_create("pool pv_read", 1024);
struct pool_list *pl;
@@ -268,9 +272,9 @@ static struct metadata_area_ops _metadata_format_pool_ops = {
/* *INDENT-ON* */
static struct format_instance *_pool_create_instance(const struct format_type *fmt,
const char *vgname,
const char *vgid,
void *private)
const char *vgname __attribute((unused)),
const char *vgid __attribute((unused)),
void *private __attribute((unused)))
{
struct format_instance *fid;
struct metadata_area *mda;
@@ -299,7 +303,7 @@ static struct format_instance *_pool_create_instance(const struct format_type *f
return fid;
}
static void _pool_destroy_instance(struct format_instance *fid)
static void _pool_destroy_instance(struct format_instance *fid __attribute((unused)))
{
return;
}

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

@@ -29,7 +29,7 @@ static void _pool_not_supported(const char *op)
op);
}
static int _pool_can_handle(struct labeller *l, void *buf, uint64_t sector)
static int _pool_can_handle(struct labeller *l __attribute((unused)), void *buf, uint64_t sector)
{
struct pool_disk pd;
@@ -50,7 +50,7 @@ static int _pool_can_handle(struct labeller *l, void *buf, uint64_t sector)
return 0;
}
static int _pool_write(struct label *label, void *buf)
static int _pool_write(struct label *label __attribute((unused)), void *buf __attribute((unused)))
{
_pool_not_supported("write");
return 0;
@@ -64,14 +64,14 @@ static int _pool_read(struct labeller *l, struct device *dev, void *buf,
return read_pool_label(&pl, l, dev, buf, label);
}
static int _pool_initialise_label(struct labeller *l, struct label *label)
static int _pool_initialise_label(struct labeller *l __attribute((unused)), struct label *label)
{
strcpy(label->type, "POOL");
return 1;
}
static void _pool_destroy_label(struct labeller *l, struct label *label)
static void _pool_destroy_label(struct labeller *l __attribute((unused)), struct label *label __attribute((unused)))
{
return;
}

View File

@@ -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
*/
@@ -140,8 +147,8 @@ static int _pv_analyze_mda_raw (const struct format_type * fmt,
int i;
uint64_t offset;
uint64_t offset2;
uint64_t size;
uint64_t size2;
size_t size;
size_t size2;
char *buf=NULL;
struct device_area *area;
struct mda_context *mdac;
@@ -149,9 +156,8 @@ static int _pv_analyze_mda_raw (const struct format_type * fmt,
mdac = (struct mda_context *) mda->metadata_locn;
log_print("Found text metadata area, offset=%"PRIu64", size=%"PRIu64,
mdac->area.start,
mdac->area.size);
log_print("Found text metadata area: offset=%" PRIu64 ", size=%"
PRIu64, mdac->area.start, mdac->area.size);
area = &mdac->area;
if (!dev_open(area->dev))
@@ -201,12 +207,12 @@ static int _pv_analyze_mda_raw (const struct format_type * fmt,
/*
* FIXME: We could add more sophisticated metadata detection
*/
if (maybe_config_section(buf, size+size2)) {
if (maybe_config_section(buf, size + size2)) {
/* FIXME: Validate region, pull out timestamp?, etc */
/* FIXME: Do something with this region */
log_verbose ("Found LVM2 metadata record at "
"offset=%"PRIu64", size=%"PRIu64", "
"offset2=%"PRIu64" size2=%"PRIu64,
"offset=%"PRIu64", size=%"PRIsize_t", "
"offset2=%"PRIu64" size2=%"PRIsize_t,
offset, size, offset2, size2);
offset = prev_sector;
size = SECTOR_SIZE;
@@ -840,8 +846,8 @@ static struct volume_group *_vg_read_precommit_file(struct format_instance *fid,
return vg;
}
static int _vg_write_file(struct format_instance *fid, struct volume_group *vg,
struct metadata_area *mda)
static int _vg_write_file(struct format_instance *fid __attribute((unused)),
struct volume_group *vg, struct metadata_area *mda)
{
struct text_context *tc = (struct text_context *) mda->metadata_locn;
@@ -905,7 +911,7 @@ static int _vg_write_file(struct format_instance *fid, struct volume_group *vg,
return 1;
}
static int _vg_commit_file_backup(struct format_instance *fid,
static int _vg_commit_file_backup(struct format_instance *fid __attribute((unused)),
struct volume_group *vg,
struct metadata_area *mda)
{
@@ -972,7 +978,8 @@ static int _vg_commit_file(struct format_instance *fid, struct volume_group *vg,
return 1;
}
static int _vg_remove_file(struct format_instance *fid, struct volume_group *vg,
static int _vg_remove_file(struct format_instance *fid __attribute((unused)),
struct volume_group *vg __attribute((unused)),
struct metadata_area *mda)
{
struct text_context *tc = (struct text_context *) mda->metadata_locn;
@@ -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);
@@ -1164,7 +1188,8 @@ static int _mda_setup(const struct format_type *fmt,
uint64_t pe_start, uint64_t pe_end,
int pvmetadatacopies,
uint64_t pvmetadatasize, struct list *mdas,
struct physical_volume *pv, struct volume_group *vg)
struct physical_volume *pv,
struct volume_group *vg __attribute((unused)))
{
uint64_t mda_adjustment, disk_size, alignment;
uint64_t start1, mda_size1; /* First area - start of disk */
@@ -1182,7 +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;
}
@@ -1203,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;
@@ -1437,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;
@@ -1448,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)) {
@@ -1555,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,
};
@@ -1646,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

@@ -111,7 +111,8 @@ static int _read_id(struct id *id, struct config_node *cn, const char *path)
static int _read_pv(struct format_instance *fid, struct dm_pool *mem,
struct volume_group *vg, struct config_node *pvn,
struct config_node *vgn, struct dm_hash_table *pv_hash)
struct config_node *vgn __attribute((unused)),
struct dm_hash_table *pv_hash)
{
struct physical_volume *pv;
struct pv_list *pvl;
@@ -201,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;
}
@@ -214,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));
}
}
@@ -383,12 +384,12 @@ int text_import_areas(struct lv_segment *seg, const struct config_node *sn,
/* FIXME Cope if LV not yet read in */
if ((pv = dm_hash_lookup(pv_hash, cv->v.str))) {
if (!set_lv_segment_area_pv(seg, s, pv, cv->next->v.i)) {
if (!set_lv_segment_area_pv(seg, s, pv, (uint32_t) cv->next->v.i)) {
stack;
return 0;
}
} else if ((lv1 = find_lv(seg->lv->vg, cv->v.str))) {
set_lv_segment_area_lv(seg, s, lv1, cv->next->v.i,
set_lv_segment_area_lv(seg, s, lv1, (uint32_t) cv->next->v.i,
flags);
} else {
log_error("Couldn't find volume '%s' "
@@ -469,9 +470,11 @@ static int _read_segments(struct dm_pool *mem, struct volume_group *vg,
return 1;
}
static int _read_lvnames(struct format_instance *fid, struct dm_pool *mem,
static int _read_lvnames(struct format_instance *fid __attribute((unused)),
struct dm_pool *mem,
struct volume_group *vg, struct config_node *lvn,
struct config_node *vgn, struct dm_hash_table *pv_hash)
struct config_node *vgn __attribute((unused)),
struct dm_hash_table *pv_hash __attribute((unused)))
{
struct logical_volume *lv;
struct lv_list *lvl;
@@ -520,9 +523,21 @@ static int _read_lvnames(struct format_instance *fid, struct dm_pool *mem,
}
}
/* 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);
@@ -544,9 +559,11 @@ static int _read_lvnames(struct format_instance *fid, struct dm_pool *mem,
return 1;
}
static int _read_lvsegs(struct format_instance *fid, struct dm_pool *mem,
static int _read_lvsegs(struct format_instance *fid __attribute((unused)),
struct dm_pool *mem,
struct volume_group *vg, struct config_node *lvn,
struct config_node *vgn, struct dm_hash_table *pv_hash)
struct config_node *vgn __attribute((unused)),
struct dm_hash_table *pv_hash)
{
struct logical_volume *lv;
struct lv_list *lvl;

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

@@ -31,7 +31,7 @@
#include <unistd.h>
#ifndef CLUSTER_LOCKING_INTERNAL
int lock_resource(struct cmd_context *cmd, const char *resource, int flags);
int lock_resource(struct cmd_context *cmd, const char *resource, uint32_t flags);
void locking_end(void);
int locking_init(int type, struct config_tree *cf, uint32_t *flags);
#endif
@@ -295,7 +295,7 @@ static int _cluster_free_request(lvm_response_t * response, int num)
return 1;
}
static int _lock_for_cluster(unsigned char cmd, unsigned int flags, char *name)
static int _lock_for_cluster(unsigned char cmd, uint32_t flags, const char *name)
{
int status;
int i;
@@ -330,11 +330,14 @@ static int _lock_for_cluster(unsigned char cmd, unsigned int flags, char *name)
* locks are cluster-wide.
* Also, if the lock is exclusive it makes no sense to try to
* acquire it on all nodes, so just do that on the local node too.
* One exception, is that P_ locks /do/ get distributed across
* the cluster because they might have side-effects.
*/
if (cmd == CLVMD_CMD_LOCK_VG ||
(flags & LCK_TYPE_MASK) == LCK_EXCL ||
(flags & LCK_LOCAL) ||
!(flags & LCK_CLUSTER_VG))
if (strncmp(name, "P_", 2) &&
(cmd == CLVMD_CMD_LOCK_VG ||
(flags & LCK_TYPE_MASK) == LCK_EXCL ||
(flags & LCK_LOCAL) ||
!(flags & LCK_CLUSTER_VG)))
node = ".";
status = _cluster_request(cmd, node, args, len,
@@ -368,13 +371,15 @@ static int _lock_for_cluster(unsigned char cmd, unsigned int flags, char *name)
/* API entry point for LVM */
#ifdef CLUSTER_LOCKING_INTERNAL
static int _lock_resource(struct cmd_context *cmd, const char *resource,
int flags)
uint32_t flags)
#else
int lock_resource(struct cmd_context *cmd, const char *resource, int flags)
int lock_resource(struct cmd_context *cmd, const char *resource, uint32_t flags)
#endif
{
char lockname[PATH_MAX];
int cluster_cmd = 0;
const char *lock_scope;
const char *lock_type = "";
assert(strlen(resource) < sizeof(lockname));
assert(resource);
@@ -382,12 +387,15 @@ int lock_resource(struct cmd_context *cmd, const char *resource, int flags)
switch (flags & LCK_SCOPE_MASK) {
case LCK_VG:
/* If the VG name is empty then lock the unused PVs */
if (!*resource)
if (!*resource) /* FIXME Deprecated */
dm_snprintf(lockname, sizeof(lockname), "P_orphans");
else if (*resource == '#')
dm_snprintf(lockname, sizeof(lockname), "P_%s", resource + 1);
else
dm_snprintf(lockname, sizeof(lockname), "V_%s",
resource);
lock_scope = "VG";
cluster_cmd = CLVMD_CMD_LOCK_VG;
flags &= LCK_TYPE_MASK;
break;
@@ -395,6 +403,7 @@ int lock_resource(struct cmd_context *cmd, const char *resource, int flags)
case LCK_LV:
cluster_cmd = CLVMD_CMD_LOCK_LV;
strcpy(lockname, resource);
lock_scope = "LV";
flags &= 0xffdf; /* Mask off HOLD flag */
break;
@@ -404,9 +413,46 @@ int lock_resource(struct cmd_context *cmd, const char *resource, int flags)
return 0;
}
/* Send a message to the cluster manager */
log_very_verbose("Locking %s at 0x%x", lockname, flags);
switch(flags & LCK_TYPE_MASK) {
case LCK_UNLOCK:
lock_type = "UN";
break;
case LCK_NULL:
lock_type = "NL";
break;
case LCK_READ:
lock_type = "CR";
break;
case LCK_PREAD:
lock_type = "PR";
break;
case LCK_WRITE:
lock_type = "PW";
break;
case LCK_EXCL:
lock_type = "EX";
break;
default:
log_error("Unrecognised lock type: %u",
flags & LCK_TYPE_MASK);
return 0;
}
/* If we are unlocking a VG, then trigger remote metadata backups */
if (cluster_cmd == CLVMD_CMD_LOCK_VG && ((flags & LCK_TYPE_MASK) == LCK_UNLOCK)) {
log_very_verbose("Requesing backup of VG metadata for %s", resource);
_lock_for_cluster(CLVMD_CMD_VG_BACKUP, LCK_CLUSTER_VG, resource);
}
log_very_verbose("Locking %s %s %s %s%s%s%s (0x%x)", lock_scope, lockname,
lock_type,
flags & LCK_NONBLOCK ? "" : "B",
flags & LCK_HOLD ? "H" : "",
flags & LCK_LOCAL ? "L" : "",
flags & LCK_CLUSTER_VG ? "C" : "",
flags);
/* Send a message to the cluster manager */
return _lock_for_cluster(cluster_cmd, flags, lockname);
}

View File

@@ -23,12 +23,12 @@ static void *_locking_lib = NULL;
static void (*_reset_fn) (void) = NULL;
static void (*_end_fn) (void) = NULL;
static int (*_lock_fn) (struct cmd_context * cmd, const char *resource,
int flags) = NULL;
uint32_t flags) = NULL;
static int (*_init_fn) (int type, struct config_tree * cft,
uint32_t *flags) = NULL;
static int _lock_resource(struct cmd_context *cmd, const char *resource,
int flags)
uint32_t flags)
{
if (_lock_fn)
return _lock_fn(cmd, resource, flags);

View File

@@ -124,7 +124,7 @@ static void _install_ctrl_c_handler()
siginterrupt(SIGINT, 1);
}
static int _lock_file(const char *file, int flags)
static int _lock_file(const char *file, uint32_t flags)
{
int operation;
int r = 1;
@@ -204,17 +204,18 @@ static int _lock_file(const char *file, int flags)
}
static int _file_lock_resource(struct cmd_context *cmd, const char *resource,
int flags)
uint32_t flags)
{
char lockfile[PATH_MAX];
assert(resource);
switch (flags & LCK_SCOPE_MASK) {
case LCK_VG:
if (!*resource)
if (!*resource) /* FIXME Deprecated */
dm_snprintf(lockfile, sizeof(lockfile),
"%s/P_orphans", _lock_dir);
else if (*resource == '#')
dm_snprintf(lockfile, sizeof(lockfile),
"%s/P_%s", _lock_dir, resource + 1);
else
dm_snprintf(lockfile, sizeof(lockfile),
"%s/V_%s", _lock_dir, resource);
@@ -235,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

@@ -118,7 +118,7 @@ void sigint_restore(void)
sigaction(SIGINT, &_oldhandler, NULL);
}
static void _block_signals(int flags __attribute((unused)))
static void _block_signals(uint32_t flags __attribute((unused)))
{
sigset_t set;
@@ -156,7 +156,7 @@ static void _unblock_signals(void)
return;
}
static void _lock_memory(int flags)
static void _lock_memory(uint32_t flags)
{
if (!(_locking.flags & LCK_PRE_MEMLOCK))
return;
@@ -165,7 +165,7 @@ static void _lock_memory(int flags)
memlock_inc();
}
static void _unlock_memory(int flags)
static void _unlock_memory(uint32_t flags)
{
if (!(_locking.flags & LCK_PRE_MEMLOCK))
return;
@@ -187,7 +187,7 @@ void reset_locking(void)
_unblock_signals();
}
static void _update_vg_lock_count(int flags)
static void _update_vg_lock_count(uint32_t flags)
{
if ((flags & LCK_SCOPE_MASK) != LCK_VG)
return;
@@ -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,
@@ -313,11 +313,13 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname)
* VG locking is by VG name.
* FIXME This should become VG uuid.
*/
static int _lock_vol(struct cmd_context *cmd, const char *resource, int flags)
static int _lock_vol(struct cmd_context *cmd, const char *resource, uint32_t flags)
{
_block_signals(flags);
_lock_memory(flags);
assert(resource);
if (!(_locking.lock_resource(cmd, resource, flags))) {
_unlock_memory(flags);
_unblock_signals();
@@ -331,10 +333,15 @@ static int _lock_vol(struct cmd_context *cmd, const char *resource, int flags)
return 1;
}
int lock_vol(struct cmd_context *cmd, const char *vol, int flags)
int lock_vol(struct cmd_context *cmd, const char *vol, uint32_t flags)
{
char resource[258] __attribute((aligned(8)));
if (flags == LCK_NONE) {
log_debug("Internal error: %s: LCK_NONE lock requested", vol);
return 1;
}
switch (flags & LCK_SCOPE_MASK) {
case LCK_VG:
/* Lock VG to change on-disk metadata. */

View File

@@ -28,14 +28,14 @@ int locking_is_clustered(void);
/*
* LCK_VG:
* Lock/unlock on-disk volume group data
* Use "" to lock orphan PVs
* Use VG_ORPHANS to lock orphan PVs
* char *vol holds volume group name
*
* LCK_LV:
* Lock/unlock an individual logical volume
* char *vol holds lvid
*/
int lock_vol(struct cmd_context *cmd, const char *vol, int flags);
int lock_vol(struct cmd_context *cmd, const char *vol, uint32_t flags);
/*
* Does the LVM1 driver have this VG active?
@@ -45,42 +45,49 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
/*
* Lock type - these numbers are the same as VMS and the IBM DLM
*/
#define LCK_TYPE_MASK 0x00000007
#define LCK_TYPE_MASK 0x00000007U
#define LCK_NULL 0x00000000 /* LCK$_NLMODE */
#define LCK_READ 0x00000001 /* LCK$_CRMODE */
#define LCK_NULL 0x00000000U /* LCK$_NLMODE */
#define LCK_READ 0x00000001U /* LCK$_CRMODE */
/* LCK$_CWMODE */
#define LCK_PREAD 0x00000003 /* LCK$_PRMODE */
#define LCK_WRITE 0x00000004 /* LCK$_PWMODE */
#define LCK_EXCL 0x00000005 /* LCK$_EXMODE */
#define LCK_UNLOCK 0x00000006 /* This is ours */
#define LCK_PREAD 0x00000003U /* LCK$_PRMODE */
#define LCK_WRITE 0x00000004U /* LCK$_PWMODE */
#define LCK_EXCL 0x00000005U /* LCK$_EXMODE */
#define LCK_UNLOCK 0x00000006U /* This is ours */
/*
* Lock scope
*/
#define LCK_SCOPE_MASK 0x00000008
#define LCK_VG 0x00000000
#define LCK_LV 0x00000008
#define LCK_SCOPE_MASK 0x00000008U
#define LCK_VG 0x00000000U
#define LCK_LV 0x00000008U
/*
* Lock bits
*/
#define LCK_NONBLOCK 0x00000010 /* Don't block waiting for lock? */
#define LCK_HOLD 0x00000020 /* Hold lock when lock_vol returns? */
#define LCK_LOCAL 0x00000040 /* Don't propagate to other nodes */
#define LCK_CLUSTER_VG 0x00000080 /* VG is clustered */
#define LCK_NONBLOCK 0x00000010U /* Don't block waiting for lock? */
#define LCK_HOLD 0x00000020U /* Hold lock when lock_vol returns? */
#define LCK_LOCAL 0x00000040U /* Don't propagate to other nodes */
#define LCK_CLUSTER_VG 0x00000080U /* VG is clustered */
/*
* Additional lock bits for cluster communication
*/
#define LCK_PARTIAL_MODE 0x00000001 /* Running in partial mode */
#define LCK_MIRROR_NOSYNC_MODE 0x00000002 /* Mirrors don't require sync */
#define LCK_DMEVENTD_MONITOR_MODE 0x00000004 /* Register with dmeventd */
#define LCK_PARTIAL_MODE 0x00000001U /* Running in partial mode */
#define LCK_MIRROR_NOSYNC_MODE 0x00000002U /* Mirrors don't require sync */
#define LCK_DMEVENTD_MONITOR_MODE 0x00000004U /* Register with dmeventd */
/*
* Special cases of VG locks.
*/
#define VG_ORPHANS "#orphans"
#define VG_GLOBAL "#global"
/*
* Common combinations
*/
#define LCK_NONE (LCK_VG | LCK_NULL)
#define LCK_VG_READ (LCK_VG | LCK_READ | LCK_HOLD)
#define LCK_VG_WRITE (LCK_VG | LCK_WRITE | LCK_HOLD)
#define LCK_VG_UNLOCK (LCK_VG | LCK_UNLOCK)

View File

@@ -17,7 +17,7 @@
#include "config.h"
typedef int (*lock_resource_fn) (struct cmd_context * cmd, const char *resource,
int flags);
uint32_t flags);
typedef void (*fin_lock_fn) (void);
typedef void (*reset_lock_fn) (void);

View File

@@ -37,7 +37,7 @@ static void _no_reset_locking(void)
}
static int _no_lock_resource(struct cmd_context *cmd, const char *resource,
int flags)
uint32_t flags)
{
switch (flags & LCK_SCOPE_MASK) {
case LCK_VG:
@@ -76,7 +76,7 @@ static int _no_lock_resource(struct cmd_context *cmd, const char *resource,
return 1;
}
int init_no_locking(struct locking_type *locking, struct cmd_context *cmd)
int init_no_locking(struct locking_type *locking, struct cmd_context *cmd __attribute((unused)))
{
locking->lock_resource = _no_lock_resource;
locking->reset_locking = _no_reset_locking;

View File

@@ -48,11 +48,9 @@ struct alloc_handle *allocate_extents(struct volume_group *vg,
uint32_t stripes,
uint32_t mirrors, uint32_t log_count,
uint32_t extents,
struct physical_volume *mirrored_pv,
uint32_t mirrored_pe,
uint32_t status,
struct list *allocatable_pvs,
alloc_policy_t alloc,
unsigned can_split,
struct list *parallel_areas);
int lv_add_segment(struct alloc_handle *ah,

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;
@@ -735,13 +720,13 @@ static int _for_each_pv(struct cmd_context *cmd, struct logical_volume *lv,
(le - seg->le) / area_multiple,
area_len, max_seg_len,
only_single_area_segments ? 0 : 0,
only_single_area_segments ? 1 : 0,
top_level_area_index != -1 ? top_level_area_index : s,
only_single_area_segments ? 1U : 0U,
top_level_area_index != -1 ? top_level_area_index : (int) s,
only_single_area_segments, fn,
data)))
stack;
} else if (seg_type(seg, s) == AREA_PV)
if (!(r = fn(cmd, seg_pvseg(seg, s), top_level_area_index != -1 ? top_level_area_index : s, data)))
if (!(r = fn(cmd, seg_pvseg(seg, s), top_level_area_index != -1 ? (uint32_t) top_level_area_index : s, data)))
stack;
if (r != 1)
return r;
@@ -813,7 +798,7 @@ static int _is_contiguous(struct pv_segment *pvseg, struct pv_area *pva)
return 1;
}
static int _is_condition(struct cmd_context *cmd,
static int _is_condition(struct cmd_context *cmd __attribute((unused)),
struct pv_segment *pvseg, uint32_t s,
void *data)
{
@@ -1068,17 +1053,15 @@ static int _find_parallel_space(struct alloc_handle *ah, alloc_policy_t alloc,
*/
static int _allocate(struct alloc_handle *ah,
struct volume_group *vg,
struct logical_volume *lv, uint32_t status,
struct logical_volume *lv,
uint32_t new_extents,
struct list *allocatable_pvs,
uint32_t stripes, uint32_t mirrors,
const struct segment_type *segtype)
unsigned can_split,
struct list *allocatable_pvs)
{
struct pv_area **areas;
uint32_t allocated = lv ? lv->le_count : 0;
uint32_t old_allocated;
struct lv_segment *prev_lvseg = NULL;
unsigned can_split = 1; /* Are we allowed more than one segment? */
int r = 0;
struct list *pvms;
uint32_t areas_size;
@@ -1089,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))
@@ -1195,11 +1178,9 @@ struct alloc_handle *allocate_extents(struct volume_group *vg,
uint32_t stripes,
uint32_t mirrors, uint32_t log_count,
uint32_t extents,
struct physical_volume *mirrored_pv,
uint32_t mirrored_pe,
uint32_t status,
struct list *allocatable_pvs,
alloc_policy_t alloc,
unsigned can_split,
struct list *parallel_areas)
{
struct alloc_handle *ah;
@@ -1223,15 +1204,12 @@ 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, status, (lv ? lv->le_count : 0) + extents,
allocatable_pvs, stripes, mirrors, segtype)) {
!_allocate(ah, vg, lv, (lv ? lv->le_count : 0) + extents,
can_split, allocatable_pvs)) {
stack;
alloc_destroy(ah);
return NULL;
@@ -1334,8 +1312,8 @@ int lv_add_mirror_segment(struct alloc_handle *ah,
struct logical_volume *lv,
struct logical_volume **sub_lvs,
uint32_t mirrors,
const struct segment_type *segtype,
uint32_t status,
const struct segment_type *segtype __attribute((unused)),
uint32_t status __attribute((unused)),
uint32_t region_size,
struct logical_volume *log_lv)
{
@@ -1426,16 +1404,19 @@ int lv_extend(struct logical_volume *lv,
uint32_t m;
struct alloc_handle *ah;
struct lv_segment *seg;
unsigned can_split = 1;
if (segtype_is_virtual(segtype))
return lv_add_virtual_segment(lv, status, extents, segtype);
/* FIXME Temporary restriction during code reorganisation */
if (mirrored_pv)
can_split = 0;
if (!(ah = allocate_extents(lv->vg, lv, segtype, stripes, mirrors, 0,
extents, mirrored_pv, mirrored_pe, status,
allocatable_pvs, alloc, NULL))) {
stack;
return 0;
}
extents, allocatable_pvs, alloc, can_split,
NULL)))
return_0;
if (mirrors < 2) {
if (!lv_add_segment(ah, 0, ah->area_count, lv, segtype, stripe_size,
@@ -1556,7 +1537,7 @@ static int _for_each_sub_lv(struct cmd_context *cmd, struct logical_volume *lv,
void *data)
{
struct lv_segment *seg;
int s;
uint32_t s;
list_iterate_items(seg, &lv->segments) {
if (seg->log_lv && !func(cmd, seg->log_lv, data))
@@ -1574,7 +1555,6 @@ static int _for_each_sub_lv(struct cmd_context *cmd, struct logical_volume *lv,
/*
* Core of LV renaming routine.
* VG must be locked by caller.
* Returns 0 on failure, 1 on success.
*/
int lv_rename(struct cmd_context *cmd, struct logical_volume *lv,
const char *new_name)
@@ -1660,14 +1640,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;
@@ -1709,7 +1689,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);
@@ -1807,7 +1787,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;
@@ -1843,37 +1823,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 == DONT_FORCE)) {
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 */
@@ -107,9 +108,9 @@ typedef enum {
* Whether or not to force an operation.
*/
typedef enum {
DONT_FORCE = 0,
FORCE_NO_CONFIRM = 1, /* skip yes/no confirmation of operation */
FORCE_OVERRIDE = 2 /* skip confirmation and bypass a second condition */
PROMPT = 0, /* Issue yes/no prompt to confirm operation */
DONT_PROMPT = 1, /* Skip yes/no prompt */
DONT_PROMPT_OVERRIDE = 2 /* Skip prompt + override a second condition */
} force_t;
struct cmd_context;
@@ -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);
@@ -323,13 +326,19 @@ pv_t *pv_create(const struct format_type *fmt,
int pv_resize(struct physical_volume *pv, struct volume_group *vg,
uint32_t new_pe_count);
int pv_analyze(struct cmd_context *cmd, const char *pv_name,
int64_t label_sector);
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,
int pv_count, char **pv_names);
int vg_remove(struct volume_group *vg);
int vg_remove_single(struct cmd_context *cmd, const char *vg_name,
struct volume_group *vg, int consistent,
force_t force);
int vg_rename(struct cmd_context *cmd, struct volume_group *vg,
const char *new_name);
int vg_extend(struct volume_group *vg, int pv_count, char **pv_names);
@@ -339,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,
@@ -402,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);
@@ -427,9 +435,9 @@ int create_mirror_layers(struct alloc_handle *ah,
struct logical_volume *log_lv);
int remove_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors,
struct list *removable_pvs, int remove_log);
struct list *removable_pvs, unsigned remove_log);
int reconfigure_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors,
struct list *removable_pvs, int remove_log);
struct list *removable_pvs, unsigned remove_log);
int insert_pvmove_mirrors(struct cmd_context *cmd,
struct logical_volume *lv_mirr,
@@ -459,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

@@ -25,6 +25,7 @@
#include "activate.h"
#include "display.h"
#include "locking.h"
#include "archiver.h"
#include <sys/param.h>
@@ -32,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,
@@ -92,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;
@@ -240,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;
}
}
@@ -248,6 +249,99 @@ 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)))
{
struct physical_volume *pv;
struct pv_list *pvl;
int ret = 1;
if (!vg || !consistent || (vg_status(vg) & PARTIAL_VG)) {
log_error("Volume group \"%s\" not found or inconsistent.",
vg_name);
log_error("Consider vgreduce --removemissing if metadata "
"is inconsistent.");
return 0;
}
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);
return 0;
}
if (!archive(vg))
return 0;
if (!vg_remove(vg)) {
log_error("vg_remove %s failed", vg_name);
return 0;
}
/* init physical volumes */
list_iterate_items(pvl, &vg->pvs) {
pv = pvl->pv;
log_verbose("Removing physical volume \"%s\" from "
"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.", pv_dev_name(pv));
ret = 0;
continue;
}
/* FIXME Write to same sector label was read from */
if (!pv_write(cmd, pv, NULL, INT64_C(-1))) {
log_error("Failed to remove physical volume \"%s\""
" from volume group \"%s\"",
pv_dev_name(pv), vg_name);
ret = 0;
}
}
backup_remove(cmd, vg_name);
if (ret)
log_print("Volume group \"%s\" successfully removed", vg_name);
else
log_error("Volume group \"%s\" not properly removed", vg_name);
return ret;
}
int vg_extend(struct volume_group *vg, int pv_count, char **pv_names)
{
int i;
@@ -399,8 +493,8 @@ static int _recalc_extents(uint32_t *extents, const char *desc1,
return 1;
}
int vg_change_pesize(struct cmd_context *cmd, struct volume_group *vg,
uint32_t new_size)
int vg_change_pesize(struct cmd_context *cmd __attribute((unused)),
struct volume_group *vg, uint32_t new_size)
{
uint32_t old_size = vg->extent_size;
struct pv_list *pvl;
@@ -436,13 +530,13 @@ int vg_change_pesize(struct cmd_context *cmd, struct volume_group *vg,
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;
@@ -453,13 +547,13 @@ int vg_change_pesize(struct cmd_context *cmd, struct volume_group *vg,
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;
@@ -550,8 +644,8 @@ int vg_change_pesize(struct cmd_context *cmd, struct volume_group *vg,
return 1;
}
int vg_split_mdas(struct cmd_context *cmd, struct volume_group *vg_from,
struct volume_group *vg_to)
int vg_split_mdas(struct cmd_context *cmd __attribute((unused)),
struct volume_group *vg_from, struct volume_group *vg_to)
{
struct metadata_area *mda, *mda2;
struct list *mdas_from, *mdas_to;
@@ -614,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,
@@ -625,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;
}
@@ -814,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;
}
@@ -893,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;
}
@@ -901,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;
}
}
@@ -1120,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;
@@ -1158,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.");
@@ -1359,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:
@@ -1422,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)) {
@@ -1452,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,
@@ -1664,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;
@@ -1686,37 +1800,45 @@ 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
* 1 - success
*/
int pv_analyze(struct cmd_context *cmd, const char *pv_name,
int64_t label_sector)
uint64_t label_sector)
{
struct label *label;
struct device *dev;
@@ -1800,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)
{
@@ -1809,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);
@@ -1825,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

@@ -118,7 +118,7 @@ static int _delete_lv(struct lv_segment *mirrored_seg, struct logical_volume *lv
* Reduce mirrored_seg to num_mirrors images.
*/
int remove_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors,
struct list *removable_pvs, int remove_log)
struct list *removable_pvs, unsigned remove_log)
{
uint32_t m;
uint32_t extents;
@@ -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");
@@ -255,7 +256,8 @@ int remove_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors,
return 1;
}
static int get_mirror_fault_policy(struct cmd_context *cmd, int log_policy)
static int get_mirror_fault_policy(struct cmd_context *cmd __attribute((unused)),
int log_policy)
{
const char *policy;
@@ -347,7 +349,7 @@ static int replace_mirror_images(struct lv_segment *mirrored_seg,
}
int reconfigure_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors,
struct list *removable_pvs, int remove_log)
struct list *removable_pvs, unsigned remove_log)
{
int r;
int insync = 0;
@@ -416,7 +418,7 @@ static int _create_layers_for_mirror(struct alloc_handle *ah,
uint32_t first_area,
uint32_t num_mirrors,
struct logical_volume *lv,
const struct segment_type *segtype,
const struct segment_type *segtype __attribute((unused)),
struct logical_volume **img_lvs)
{
uint32_t m;
@@ -437,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. "
@@ -467,7 +469,7 @@ int create_mirror_layers(struct alloc_handle *ah,
uint32_t num_mirrors,
struct logical_volume *lv,
const struct segment_type *segtype,
uint32_t status,
uint32_t status __attribute((unused)),
uint32_t region_size,
struct logical_volume *log_lv)
{
@@ -508,7 +510,7 @@ int create_mirror_layers(struct alloc_handle *ah,
int add_mirror_layers(struct alloc_handle *ah,
uint32_t num_mirrors,
uint32_t existing_mirrors,
uint32_t existing_mirrors __attribute((unused)),
struct logical_volume *lv,
const struct segment_type *segtype)
{
@@ -530,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.
@@ -545,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;
@@ -646,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

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

View File

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

@@ -27,7 +27,7 @@ int emit_to_buffer(char **buffer, size_t *size, const char *fmt, ...)
n = vsnprintf(*buffer, *size, fmt, ap);
va_end(ap);
if (n < 0 || (n == *size))
if (n < 0 || ((size_t)n == *size))
return 0;
*buffer += n;
@@ -40,10 +40,10 @@ int emit_to_buffer(char **buffer, size_t *size, const char *fmt, ...)
*
* Returns:
* len - incremented for each char we encounter, whether 'c' or not.
* count - number of occurences of 'c'
* count - number of occurrences of 'c'
*/
void count_chars(const char *str, size_t *len, int *count,
const char c)
const int c)
{
const char *ptr;
@@ -56,18 +56,18 @@ void count_chars(const char *str, size_t *len, int *count,
* Count occurences of 'c' in 'str' of length 'size'.
*
* Returns:
* # of occurences of 'c'
* Number of occurrences of 'c'
*/
unsigned count_chars_len(const char *str, size_t size, const char c)
unsigned count_chars_len(const char *str, size_t len, const int c)
{
int i;
unsigned count=0;
size_t i;
unsigned count = 0;
for (i=0; i < size; i++)
for (i = 0; i < len; i++)
if (str[i] == c)
count++;
return count;
return count;
}
/*

View File

@@ -32,7 +32,7 @@ char *build_dm_name(struct dm_pool *mem, const char *vg,
int validate_name(const char *n);
void count_chars(const char *str, size_t *len, int *count,
char c);
unsigned count_chars_len(const char *str, size_t size, char c);
const int c);
unsigned count_chars_len(const char *str, size_t len, const int c);
#endif

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.")
@@ -77,8 +81,10 @@ FIELD(SEGS, seg, NUM, "Region", region_size, 6, size32, "region_size", "For mirr
FIELD(SEGS, seg, NUM, "Chunk", list, 5, chunksize, "chunksize", "For snapshots, the unit of data used when tracking changes.")
FIELD(SEGS, seg, NUM, "Chunk", list, 5, chunksize, "chunk_size", "For snapshots, the unit of data used when tracking changes.")
FIELD(SEGS, seg, NUM, "Start", list, 5, segstart, "seg_start", "Offset within the LV to the start of the segment in current units.")
FIELD(SEGS, seg, NUM, "Start", list, 5, segstartpe, "seg_start_pe", "Offset within the LV to the start of the segment in physical extents.")
FIELD(SEGS, seg, NUM, "SSize", list, 5, segsize, "seg_size", "Size of segment in current units.")
FIELD(SEGS, seg, STR, "Seg Tags", tags, 8, tags, "seg_tags", "Tags, if any.")
FIELD(SEGS, seg, STR, "PE Ranges", list, 9, peranges, "seg_pe_ranges", "Ranges of Physical Extents of underlying devices in command line format.")
FIELD(SEGS, seg, STR, "Devices", list, 5, devices, "devices", "Underlying devices used with starting extent numbers.")
FIELD(PVSEGS, pvseg, NUM, "Start", pe, 5, uint32, "pvseg_start", "Physical Extent number of start of segment.")

View File

@@ -59,28 +59,29 @@ 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
*/
static int _string_disp(struct dm_report *rh, struct dm_pool *mem,
static int _string_disp(struct dm_report *rh, struct dm_pool *mem __attribute((unused)),
struct dm_report_field *field,
const void *data, void *private)
const void *data, void *private __attribute((unused)))
{
return dm_report_field_string(rh, field, (const char **) data);
}
static int _dev_name_disp(struct dm_report *rh, struct dm_pool *mem,
static int _dev_name_disp(struct dm_report *rh, struct dm_pool *mem __attribute((unused)),
struct dm_report_field *field,
const void *data, void *private)
const void *data, void *private __attribute((unused)))
{
const char *name = dev_name(*(const struct device **) data);
return dm_report_field_string(rh, field, &name);
}
static int _devices_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
static int _format_pvsegs(struct dm_pool *mem, struct dm_report_field *field,
const void *data, int range_format)
{
const struct lv_segment *seg = (const struct lv_segment *) data;
unsigned int s;
@@ -113,19 +114,32 @@ static int _devices_disp(struct dm_report *rh, struct dm_pool *mem,
return 0;
}
if (dm_snprintf(extent_str, sizeof(extent_str), "(%" PRIu32
")", extent) < 0) {
if (dm_snprintf(extent_str, sizeof(extent_str),
"%s%" PRIu32 "%s",
range_format ? ":" : "(", extent,
range_format ? "-" : ")") < 0) {
log_error("Extent number dm_snprintf failed");
return 0;
}
if (!dm_pool_grow_object(mem, extent_str, strlen(extent_str))) {
log_error("dm_pool_grow_object failed");
return 0;
}
if (range_format) {
if (dm_snprintf(extent_str, sizeof(extent_str),
"%" PRIu32, extent + seg->area_len - 1) < 0) {
log_error("Extent number dm_snprintf failed");
return 0;
}
if (!dm_pool_grow_object(mem, extent_str, strlen(extent_str))) {
log_error("dm_pool_grow_object failed");
return 0;
}
}
if ((s != seg->area_count - 1) &&
!dm_pool_grow_object(mem, ",", 1)) {
!dm_pool_grow_object(mem, range_format ? " " : ",", 1)) {
log_error("dm_pool_grow_object failed");
return 0;
}
@@ -141,9 +155,23 @@ static int _devices_disp(struct dm_report *rh, struct dm_pool *mem,
return 1;
}
static int _tags_disp(struct dm_report *rh, struct dm_pool *mem,
static int _devices_disp(struct dm_report *rh __attribute((unused)), struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private __attribute((unused)))
{
return _format_pvsegs(mem, field, data, 0);
}
static int _peranges_disp(struct dm_report *rh __attribute((unused)), struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private __attribute((unused)))
{
return _format_pvsegs(mem, field, data, 1);
}
static int _tags_disp(struct dm_report *rh __attribute((unused)), struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
const void *data, void *private __attribute((unused)))
{
const struct list *tags = (const struct list *) data;
struct str_list *sl;
@@ -218,37 +246,35 @@ static int _pvfmt_disp(struct dm_report *rh, struct dm_pool *mem,
return _string_disp(rh, mem, field, &pv->fmt->name, private);
}
static int _lvkmaj_disp(struct dm_report *rh, struct dm_pool *mem,
static int _lvkmaj_disp(struct dm_report *rh, struct dm_pool *mem __attribute((unused)),
struct dm_report_field *field,
const void *data, void *private)
const void *data, void *private __attribute((unused)))
{
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,
static int _lvkmin_disp(struct dm_report *rh, struct dm_pool *mem __attribute((unused)),
struct dm_report_field *field,
const void *data, void *private)
const void *data, void *private __attribute((unused)))
{
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, struct dm_pool *mem,
static int _lvstatus_disp(struct dm_report *rh __attribute((unused)), struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
const void *data, void *private __attribute((unused)))
{
const struct logical_volume *lv = (const struct logical_volume *) data;
struct lvinfo info;
@@ -297,7 +323,7 @@ static int _lvstatus_disp(struct dm_report *rh, struct dm_pool *mem,
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)
@@ -331,9 +357,9 @@ static int _lvstatus_disp(struct dm_report *rh, struct dm_pool *mem,
return 1;
}
static int _pvstatus_disp(struct dm_report *rh, struct dm_pool *mem,
static int _pvstatus_disp(struct dm_report *rh __attribute((unused)), struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
const void *data, void *private __attribute((unused)))
{
const uint32_t status = *(const uint32_t *) data;
char *repstr;
@@ -357,9 +383,9 @@ static int _pvstatus_disp(struct dm_report *rh, struct dm_pool *mem,
return 1;
}
static int _vgstatus_disp(struct dm_report *rh, struct dm_pool *mem,
static int _vgstatus_disp(struct dm_report *rh __attribute((unused)), struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
const void *data, void *private __attribute((unused)))
{
const struct volume_group *vg = (const struct volume_group *) data;
char *repstr;
@@ -401,9 +427,9 @@ static int _vgstatus_disp(struct dm_report *rh, struct dm_pool *mem,
}
static int _segtype_disp(struct dm_report *rh __attribute((unused)),
struct dm_pool *mem,
struct dm_pool *mem __attribute((unused)),
struct dm_report_field *field,
const void *data, void *private)
const void *data, void *private __attribute((unused)))
{
const struct lv_segment *seg = (const struct lv_segment *) data;
@@ -416,9 +442,9 @@ static int _segtype_disp(struct dm_report *rh __attribute((unused)),
return 1;
}
static int _origin_disp(struct dm_report *rh, struct dm_pool *mem,
static int _origin_disp(struct dm_report *rh, struct dm_pool *mem __attribute((unused)),
struct dm_report_field *field,
const void *data, void *private)
const void *data, void *private __attribute((unused)))
{
const struct logical_volume *lv = (const struct logical_volume *) data;
@@ -430,9 +456,9 @@ static int _origin_disp(struct dm_report *rh, struct dm_pool *mem,
return 1;
}
static int _loglv_disp(struct dm_report *rh, struct dm_pool *mem,
static int _loglv_disp(struct dm_report *rh, struct dm_pool *mem __attribute((unused)),
struct dm_report_field *field,
const void *data, void *private)
const void *data, void *private __attribute((unused)))
{
const struct logical_volume *lv = (const struct logical_volume *) data;
struct lv_segment *seg;
@@ -450,7 +476,7 @@ static int _loglv_disp(struct dm_report *rh, struct dm_pool *mem,
static int _lvname_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
const void *data, void *private __attribute((unused)))
{
const struct logical_volume *lv = (const struct logical_volume *) data;
char *repstr, *lvname;
@@ -482,9 +508,9 @@ static int _lvname_disp(struct dm_report *rh, struct dm_pool *mem,
return 1;
}
static int _movepv_disp(struct dm_report *rh, struct dm_pool *mem,
static int _movepv_disp(struct dm_report *rh, struct dm_pool *mem __attribute((unused)),
struct dm_report_field *field,
const void *data, void *private)
const void *data, void *private __attribute((unused)))
{
const struct logical_volume *lv = (const struct logical_volume *) data;
const char *name;
@@ -501,7 +527,7 @@ static int _movepv_disp(struct dm_report *rh, struct dm_pool *mem,
return 1;
}
static int _size32_disp(struct dm_report *rh, struct dm_pool *mem,
static int _size32_disp(struct dm_report *rh __attribute((unused)), struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
{
@@ -531,7 +557,8 @@ static int _size32_disp(struct dm_report *rh, struct dm_pool *mem,
return 1;
}
static int _size64_disp(struct dm_report *rh, struct dm_pool *mem,
static int _size64_disp(struct dm_report *rh __attribute((unused)),
struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
{
@@ -560,6 +587,34 @@ static int _size64_disp(struct dm_report *rh, struct dm_pool *mem,
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)
@@ -584,6 +639,15 @@ static int _segstart_disp(struct dm_report *rh, struct dm_pool *mem,
return _size64_disp(rh, mem, field, &start, private);
}
static int _segstartpe_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
{
const struct lv_segment *seg = (const struct lv_segment *) data;
return dm_report_field_uint32(rh, field, &seg->le);
}
static int _segsize_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
@@ -684,9 +748,9 @@ static int _vgfree_disp(struct dm_report *rh, struct dm_pool *mem,
return _size64_disp(rh, mem, field, &freespace, private);
}
static int _uuid_disp(struct dm_report *rh, struct dm_pool *mem,
static int _uuid_disp(struct dm_report *rh __attribute((unused)), struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
const void *data, void *private __attribute((unused)))
{
char *repstr = NULL;
@@ -704,16 +768,16 @@ static int _uuid_disp(struct dm_report *rh, struct dm_pool *mem,
return 1;
}
static int _uint32_disp(struct dm_report *rh, struct dm_pool *mem,
static int _uint32_disp(struct dm_report *rh, struct dm_pool *mem __attribute((unused)),
struct dm_report_field *field,
const void *data, void *private)
const void *data, void *private __attribute((unused)))
{
return dm_report_field_uint32(rh, field, data);
}
static int _int32_disp(struct dm_report *rh, struct dm_pool *mem,
static int _int32_disp(struct dm_report *rh, struct dm_pool *mem __attribute((unused)),
struct dm_report_field *field,
const void *data, void *private)
const void *data, void *private __attribute((unused)))
{
return dm_report_field_int32(rh, field, data);
}
@@ -744,6 +808,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)
@@ -756,9 +867,9 @@ static int _lvsegcount_disp(struct dm_report *rh, struct dm_pool *mem,
return _uint32_disp(rh, mem, field, &count, private);
}
static int _snpercent_disp(struct dm_report *rh, struct dm_pool *mem,
static int _snpercent_disp(struct dm_report *rh __attribute((unused)), struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
const void *data, void *private __attribute((unused)))
{
const struct logical_volume *lv = (const struct logical_volume *) data;
struct lvinfo info;
@@ -778,7 +889,7 @@ static int _snpercent_disp(struct dm_report *rh, struct dm_pool *mem,
}
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;
@@ -806,9 +917,9 @@ static int _snpercent_disp(struct dm_report *rh, struct dm_pool *mem,
return 1;
}
static int _copypercent_disp(struct dm_report *rh, struct dm_pool *mem,
static int _copypercent_disp(struct dm_report *rh __attribute((unused)), struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
const void *data, void *private __attribute((unused)))
{
struct logical_volume *lv = (struct logical_volume *) data;
float percent;

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;
@@ -128,7 +128,7 @@ static int _snap_target_present(const struct lv_segment *seg __attribute((unused
#endif
static int _snap_modules_needed(struct dm_pool *mem,
const struct lv_segment *seg,
const struct lv_segment *seg __attribute((unused)),
struct list *modules)
{
if (!str_list_add(mem, modules, "snapshot")) {

View File

@@ -65,7 +65,7 @@ static int _zero_target_present(const struct lv_segment *seg __attribute((unused
#endif
static int _zero_modules_needed(struct dm_pool *mem,
const struct lv_segment *seg,
const struct lv_segment *seg __attribute((unused)),
struct list *modules)
{
if (!str_list_add(mem, modules, "zero")) {

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@
@@ -48,7 +49,7 @@ DEFS += -DDEVICE_UID=@DEVICE_UID@ -DDEVICE_GID=@DEVICE_GID@ \
include ../make.tmpl
.PHONY: install_dynamic install_static install_include \
install_fs install_ioctl install_ioctl_static \
install_ioctl install_ioctl_static \
install_pkgconfig
INSTALL_TYPE = install_dynamic
@@ -74,10 +75,6 @@ install_dynamic: install_@interface@
install_static: install_@interface@_static
$(LN_S) -f libdevmapper.a.$(LIB_VERSION) $(libdir)/libdevmapper.a
install_fs: fs/libdevmapper.$(LIB_SUFFIX)
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \
$(libdir)/libdevmapper.$(LIB_SUFFIX).$(LIB_VERSION)
install_ioctl: ioctl/libdevmapper.$(LIB_SUFFIX)
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \
$(libdir)/libdevmapper.$(LIB_SUFFIX).$(LIB_VERSION)
@@ -90,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;
}
@@ -292,6 +300,8 @@ static int _add_dev_node(const char *dev_name, uint32_t major, uint32_t minor,
return 0;
}
log_debug("Created %s", path);
#ifdef HAVE_SELINUX
if (!dm_set_selinux_context(path, S_IFBLK))
return 0;
@@ -333,6 +343,8 @@ static int _rename_dev_node(const char *old_name, const char *new_name)
return 0;
}
log_debug("Renamed %s to %s", oldpath, newpath);
return 1;
}
@@ -351,18 +363,134 @@ static int _rm_dev_node(const char *dev_name)
return 0;
}
log_debug("Removed %s", path);
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 (!*dev_name) {
log_error("Empty device name passed to BLKRAGET");
return 0;
}
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 (!*dev_name) {
log_error("Empty device name passed to BLKRAGET");
return 0;
}
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: retaining kernel read ahead of %" PRIu32
" (requested %" 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 +499,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 +518,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,12 +533,27 @@ 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;
struct list *noph, *nopht;
size_t len = strlen(dev_name) + strlen(old_name) + 2;
char *pos;
/*
* Ignore any outstanding operations on the node if deleting it
*/
if (type == NODE_DEL) {
list_iterate_safe(noph, nopht, &_node_ops) {
nop = list_item(noph, struct node_op_parms);
if (!strcmp(dev_name, nop->dev_name)) {
list_del(&nop->list);
dm_free(nop);
}
}
}
if (!(nop = dm_malloc(sizeof(*nop) + len))) {
log_error("Insufficient memory to stack mknod operation");
return 0;
@@ -418,6 +566,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 +585,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);
}
@@ -444,18 +595,39 @@ static void _pop_node_ops(void)
int add_dev_node(const char *dev_name, uint32_t major, uint32_t minor,
uid_t uid, gid_t gid, mode_t mode)
{
log_debug("%s: Stacking NODE_ADD (%" PRIu32 ",%" PRIu32 ") %u:%u 0%o",
dev_name, major, minor, uid, gid, 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);
log_debug("%s: Stacking NODE_RENAME to %s", old_name, new_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, "");
log_debug("%s: Stacking NODE_DEL (replaces other stacked ops)", dev_name);
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;
log_debug("%s: Stacking NODE_READ_AHEAD %" PRIu32 " (flags=%" PRIu32
")", dev_name, read_ahead, read_ahead_flags);
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 +635,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,9 +1160,11 @@ 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(child->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,
":%" PRIu32 ")", child->name, child->info.major,
child->info.minor);
continue;
}
@@ -1484,7 +1510,6 @@ int dm_tree_preload_children(struct dm_tree_node *dnode,
void *handle = NULL;
struct dm_tree_node *child;
struct dm_info newinfo;
const char *name;
/* Preload children first */
while ((child = dm_tree_next_child(&handle, dnode, 0))) {
@@ -1500,11 +1525,6 @@ int dm_tree_preload_children(struct dm_tree_node *dnode,
if (dm_tree_node_num_children(child, 0))
dm_tree_preload_children(child, uuid_prefix, uuid_prefix_len);
if (!(name = dm_tree_node_get_name(child))) {
stack;
continue;
}
/* FIXME Cope if name exists with no uuid? */
if (!child->info.exists) {
if (!_create_node(child)) {
@@ -1527,9 +1547,11 @@ 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(child->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,
":%" PRIu32 ")", child->name, child->info.major,
child->info.minor);
continue;
}

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,13 @@ 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 sectors.
The default value is "auto" which allows the kernel to choose
a suitable value automatically.
"None" is equivalent to specifying zero.
.TP
.I \-\-refresh
If the logical volume is active, reload its metadata.

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