mirror of
git://sourceware.org/git/lvm2.git
synced 2025-12-24 16:23:50 +03:00
Compare commits
148 Commits
dm_v1_02_2
...
dm_v1_02_2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
897fc59f72 | ||
|
|
947e44ae67 | ||
|
|
e44843beba | ||
|
|
147482ea69 | ||
|
|
09091c5cf8 | ||
|
|
50827a5f69 | ||
|
|
2d6444c924 | ||
|
|
1d2675d9aa | ||
|
|
ad98990a8e | ||
|
|
8e58c143f2 | ||
|
|
556a4a2395 | ||
|
|
5be987b40f | ||
|
|
066bc35e69 | ||
|
|
403779437c | ||
|
|
fb806f61d4 | ||
|
|
6ce306661c | ||
|
|
3c08ff94d4 | ||
|
|
a6afae2356 | ||
|
|
0eea7070a7 | ||
|
|
105c2b1eea | ||
|
|
82bb0e8dda | ||
|
|
8c01179075 | ||
|
|
c9d9a96630 | ||
|
|
8f21c9a920 | ||
|
|
0ba7d05ea7 | ||
|
|
5a4c5b4155 | ||
|
|
55323fb497 | ||
|
|
7c082d2471 | ||
|
|
f3cafcf983 | ||
|
|
75073e4aa6 | ||
|
|
a3c23f650c | ||
|
|
0545cd5879 | ||
|
|
c96506f22c | ||
|
|
49b2006824 | ||
|
|
8c6f96faab | ||
|
|
a0e648abfd | ||
|
|
6350cd12fc | ||
|
|
f2fab0677b | ||
|
|
edffc52927 | ||
|
|
d6e5e3d103 | ||
|
|
5be7a0ebf7 | ||
|
|
7f722fe7d3 | ||
|
|
a01732ee9b | ||
|
|
85ac11b69b | ||
|
|
590cfb77a5 | ||
|
|
f01dd16a27 | ||
|
|
df49287e5f | ||
|
|
c8ec8391ee | ||
|
|
3499e48064 | ||
|
|
2e379cb8a5 | ||
|
|
f8ee3c2369 | ||
|
|
c74fa11518 | ||
|
|
ceec4455df | ||
|
|
17c9975c0b | ||
|
|
6c1cdff912 | ||
|
|
79f53f569d | ||
|
|
ccb85cc719 | ||
|
|
c0eff8a07f | ||
|
|
954626f157 | ||
|
|
17e7dfa4bd | ||
|
|
971f233fb7 | ||
|
|
b12bc692af | ||
|
|
730301b34d | ||
|
|
c443bcf43c | ||
|
|
b77e7eeddc | ||
|
|
031b7b57a1 | ||
|
|
5123fab525 | ||
|
|
705b96c6f9 | ||
|
|
9ec582002b | ||
|
|
ee79277774 | ||
|
|
db02dc218e | ||
|
|
b66ce1089e | ||
|
|
ec0e70b599 | ||
|
|
a273482f9d | ||
|
|
76cf8c4cf7 | ||
|
|
9691ecc839 | ||
|
|
59b2a86359 | ||
|
|
fe7cd72cff | ||
|
|
f0761fc570 | ||
|
|
90990aa19d | ||
|
|
a3d3ce82e4 | ||
|
|
b8e48113a3 | ||
|
|
d4b1003a97 | ||
|
|
efd83567c9 | ||
|
|
5563f373f7 | ||
|
|
15a36619fe | ||
|
|
38e54b626e | ||
|
|
8aa30fb56a | ||
|
|
b764becd1b | ||
|
|
219370932e | ||
|
|
90afae186c | ||
|
|
84e49a809d | ||
|
|
1cfb9ff46a | ||
|
|
f35026c74f | ||
|
|
5f2d3da8c5 | ||
|
|
4e61f32a28 | ||
|
|
d7814c7011 | ||
|
|
aa40668e84 | ||
|
|
3767e6e96f | ||
|
|
44976cef6c | ||
|
|
eba4417947 | ||
|
|
c99204d370 | ||
|
|
1bfc4335bb | ||
|
|
6b9c7485f1 | ||
|
|
737f3d78f2 | ||
|
|
b1d5e1b5e3 | ||
|
|
8d92a5cc14 | ||
|
|
fc455df92c | ||
|
|
c0076ebfa1 | ||
|
|
5d607aa3cd | ||
|
|
fa1b9a4098 | ||
|
|
c8c4dbb409 | ||
|
|
16628e6cea | ||
|
|
7067c12991 | ||
|
|
7b47e241e0 | ||
|
|
d1e46207a5 | ||
|
|
2a04b97cbd | ||
|
|
e6c8ef59e0 | ||
|
|
d3380f41de | ||
|
|
4ef1633969 | ||
|
|
57e593aab2 | ||
|
|
6461caacbb | ||
|
|
e5531e2a93 | ||
|
|
329402a614 | ||
|
|
4656ed462e | ||
|
|
96ddad91a9 | ||
|
|
5eb40588d2 | ||
|
|
58def149aa | ||
|
|
0ee5743d75 | ||
|
|
7c266f3e81 | ||
|
|
d7ce981cd1 | ||
|
|
eadadf6299 | ||
|
|
8ac9fabd07 | ||
|
|
44c2b4b281 | ||
|
|
4cd97611e5 | ||
|
|
da27380ab5 | ||
|
|
756e539661 | ||
|
|
cde44e3172 | ||
|
|
e79a4b34b0 | ||
|
|
e9f0bdd72c | ||
|
|
d080291150 | ||
|
|
06c69c56ba | ||
|
|
d79710ba9d | ||
|
|
c9bc7dd0b6 | ||
|
|
ebc26c7421 | ||
|
|
3769425f6b | ||
|
|
a50957443e | ||
|
|
63fa007af0 |
@@ -2,7 +2,7 @@
|
||||
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
# Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
|
||||
#
|
||||
# This file is part of the LVM2.
|
||||
# This file is part of LVM2.
|
||||
#
|
||||
# This copyrighted material is made available to anyone wishing to use,
|
||||
# modify, copy, or redistribute it subject to the terms and conditions
|
||||
@@ -68,3 +68,6 @@ cscope.out: tools
|
||||
@CSCOPE_CMD@ -b -R
|
||||
all: cscope.out
|
||||
endif
|
||||
|
||||
check: all
|
||||
$(MAKE) -C test all
|
||||
|
||||
109
WHATS_NEW
109
WHATS_NEW
@@ -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.
|
||||
|
||||
|
||||
19
WHATS_NEW_DM
19
WHATS_NEW_DM
@@ -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
364
configure
vendored
@@ -719,6 +719,7 @@ CLVMD
|
||||
CLUSTER
|
||||
FSADM
|
||||
DMEVENTD
|
||||
LIB_PTHREAD
|
||||
LTLIBOBJS'
|
||||
ac_subst_files=''
|
||||
ac_precious_vars='build_alias
|
||||
@@ -8066,8 +8067,8 @@ fi
|
||||
echo "${ECHO_T}$CMDLIB" >&6; }
|
||||
|
||||
################################################################################
|
||||
{ echo "$as_me:$LINENO: checking whether to build fsadm" >&5
|
||||
echo $ECHO_N "checking whether to build fsadm... $ECHO_C" >&6; }
|
||||
{ echo "$as_me:$LINENO: checking whether to install fsadm" >&5
|
||||
echo $ECHO_N "checking whether to install fsadm... $ECHO_C" >&6; }
|
||||
# Check whether --enable-fsadm was given.
|
||||
if test "${enable_fsadm+set}" = set; then
|
||||
enableval=$enable_fsadm; FSADM=$enableval
|
||||
@@ -8852,6 +8853,99 @@ _ACEOF
|
||||
{ echo "$as_me:$LINENO: WARNING: Disabling selinux" >&5
|
||||
echo "$as_me: WARNING: Disabling selinux" >&2;}
|
||||
fi
|
||||
|
||||
# With --enable-static_link and selinux enabled, linking lvm.static
|
||||
# fails on at least Debian unstable due to unsatisfied references
|
||||
# to pthread_mutex_lock and _unlock. See if we need -lpthread.
|
||||
if test "$STATIC_LINK-$HAVE_SELINUX" = yes-yes; then
|
||||
lvm_saved_libs=$LIBS
|
||||
LIBS="$LIBS -static"
|
||||
{ echo "$as_me:$LINENO: checking for library containing pthread_mutex_lock" >&5
|
||||
echo $ECHO_N "checking for library containing pthread_mutex_lock... $ECHO_C" >&6; }
|
||||
if test "${ac_cv_search_pthread_mutex_lock+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
ac_func_search_save_LIBS=$LIBS
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char pthread_mutex_lock ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return pthread_mutex_lock ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
for ac_lib in '' pthread; do
|
||||
if test -z "$ac_lib"; then
|
||||
ac_res="none required"
|
||||
else
|
||||
ac_res=-l$ac_lib
|
||||
LIBS="-l$ac_lib $ac_func_search_save_LIBS"
|
||||
fi
|
||||
rm -f conftest.$ac_objext conftest$ac_exeext
|
||||
if { (ac_try="$ac_link"
|
||||
case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
|
||||
(eval "$ac_link") 2>conftest.er1
|
||||
ac_status=$?
|
||||
grep -v '^ *+' conftest.er1 >conftest.err
|
||||
rm -f conftest.er1
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } && {
|
||||
test -z "$ac_c_werror_flag" ||
|
||||
test ! -s conftest.err
|
||||
} && test -s conftest$ac_exeext &&
|
||||
$as_test_x conftest$ac_exeext; then
|
||||
ac_cv_search_pthread_mutex_lock=$ac_res
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
|
||||
fi
|
||||
|
||||
rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
|
||||
conftest$ac_exeext
|
||||
if test "${ac_cv_search_pthread_mutex_lock+set}" = set; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test "${ac_cv_search_pthread_mutex_lock+set}" = set; then
|
||||
:
|
||||
else
|
||||
ac_cv_search_pthread_mutex_lock=no
|
||||
fi
|
||||
rm conftest.$ac_ext
|
||||
LIBS=$ac_func_search_save_LIBS
|
||||
fi
|
||||
{ echo "$as_me:$LINENO: result: $ac_cv_search_pthread_mutex_lock" >&5
|
||||
echo "${ECHO_T}$ac_cv_search_pthread_mutex_lock" >&6; }
|
||||
ac_res=$ac_cv_search_pthread_mutex_lock
|
||||
if test "$ac_res" != no; then
|
||||
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
|
||||
test "$ac_cv_search_pthread_mutex_lock" = "none required" ||
|
||||
LIB_PTHREAD=-lpthread
|
||||
fi
|
||||
|
||||
LIBS=$lvm_saved_libs
|
||||
fi
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
@@ -9365,6 +9459,12 @@ else
|
||||
fi
|
||||
|
||||
|
||||
# Convert a relative dir name to absolute.
|
||||
case $DMDIR in
|
||||
/*) ;;
|
||||
*) DMDIR="`pwd`/$DMDIR" ;;
|
||||
esac
|
||||
|
||||
################################################################################
|
||||
if test x$READLINE = xyes; then
|
||||
|
||||
@@ -10095,253 +10195,6 @@ rm -f conftest*
|
||||
|
||||
fi
|
||||
|
||||
if test x$FSADM = xyes; then
|
||||
|
||||
|
||||
|
||||
for ac_header in fstab.h sys/mount.h sys/vfs.h
|
||||
do
|
||||
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
|
||||
if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
|
||||
{ echo "$as_me:$LINENO: checking for $ac_header" >&5
|
||||
echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
|
||||
if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
fi
|
||||
ac_res=`eval echo '${'$as_ac_Header'}'`
|
||||
{ echo "$as_me:$LINENO: result: $ac_res" >&5
|
||||
echo "${ECHO_T}$ac_res" >&6; }
|
||||
else
|
||||
# Is the header compilable?
|
||||
{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
|
||||
echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
$ac_includes_default
|
||||
#include <$ac_header>
|
||||
_ACEOF
|
||||
rm -f conftest.$ac_objext
|
||||
if { (ac_try="$ac_compile"
|
||||
case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
|
||||
(eval "$ac_compile") 2>conftest.er1
|
||||
ac_status=$?
|
||||
grep -v '^ *+' conftest.er1 >conftest.err
|
||||
rm -f conftest.er1
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } && {
|
||||
test -z "$ac_c_werror_flag" ||
|
||||
test ! -s conftest.err
|
||||
} && test -s conftest.$ac_objext; then
|
||||
ac_header_compiler=yes
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
ac_header_compiler=no
|
||||
fi
|
||||
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
|
||||
echo "${ECHO_T}$ac_header_compiler" >&6; }
|
||||
|
||||
# Is the header present?
|
||||
{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
|
||||
echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
#include <$ac_header>
|
||||
_ACEOF
|
||||
if { (ac_try="$ac_cpp conftest.$ac_ext"
|
||||
case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
|
||||
(eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
|
||||
ac_status=$?
|
||||
grep -v '^ *+' conftest.er1 >conftest.err
|
||||
rm -f conftest.er1
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } >/dev/null && {
|
||||
test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
|
||||
test ! -s conftest.err
|
||||
}; then
|
||||
ac_header_preproc=yes
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
ac_header_preproc=no
|
||||
fi
|
||||
|
||||
rm -f conftest.err conftest.$ac_ext
|
||||
{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
|
||||
echo "${ECHO_T}$ac_header_preproc" >&6; }
|
||||
|
||||
# So? What about this header?
|
||||
case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
|
||||
yes:no: )
|
||||
{ echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
|
||||
echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
|
||||
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
|
||||
echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
|
||||
ac_header_preproc=yes
|
||||
;;
|
||||
no:yes:* )
|
||||
{ echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
|
||||
echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
|
||||
{ echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
|
||||
echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
|
||||
{ echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
|
||||
echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
|
||||
{ echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
|
||||
echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
|
||||
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
|
||||
echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
|
||||
{ echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
|
||||
echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
|
||||
|
||||
;;
|
||||
esac
|
||||
{ echo "$as_me:$LINENO: checking for $ac_header" >&5
|
||||
echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
|
||||
if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
eval "$as_ac_Header=\$ac_header_preproc"
|
||||
fi
|
||||
ac_res=`eval echo '${'$as_ac_Header'}'`
|
||||
{ echo "$as_me:$LINENO: result: $ac_res" >&5
|
||||
echo "${ECHO_T}$ac_res" >&6; }
|
||||
|
||||
fi
|
||||
if test `eval echo '${'$as_ac_Header'}'` = yes; then
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
|
||||
_ACEOF
|
||||
|
||||
else
|
||||
{ { echo "$as_me:$LINENO: error: bailing out" >&5
|
||||
echo "$as_me: error: bailing out" >&2;}
|
||||
{ (exit 1); exit 1; }; }
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
|
||||
for ac_func in memmove
|
||||
do
|
||||
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||
{ echo "$as_me:$LINENO: checking for $ac_func" >&5
|
||||
echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
|
||||
if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
|
||||
For example, HP-UX 11i <limits.h> declares gettimeofday. */
|
||||
#define $ac_func innocuous_$ac_func
|
||||
|
||||
/* System header to define __stub macros and hopefully few prototypes,
|
||||
which can conflict with char $ac_func (); below.
|
||||
Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
|
||||
<limits.h> exists even on freestanding compilers. */
|
||||
|
||||
#ifdef __STDC__
|
||||
# include <limits.h>
|
||||
#else
|
||||
# include <assert.h>
|
||||
#endif
|
||||
|
||||
#undef $ac_func
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char $ac_func ();
|
||||
/* The GNU C library defines this for functions which it implements
|
||||
to always fail with ENOSYS. Some functions are actually named
|
||||
something starting with __ and the normal name is an alias. */
|
||||
#if defined __stub_$ac_func || defined __stub___$ac_func
|
||||
choke me
|
||||
#endif
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return $ac_func ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
rm -f conftest.$ac_objext conftest$ac_exeext
|
||||
if { (ac_try="$ac_link"
|
||||
case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
|
||||
(eval "$ac_link") 2>conftest.er1
|
||||
ac_status=$?
|
||||
grep -v '^ *+' conftest.er1 >conftest.err
|
||||
rm -f conftest.er1
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } && {
|
||||
test -z "$ac_c_werror_flag" ||
|
||||
test ! -s conftest.err
|
||||
} && test -s conftest$ac_exeext &&
|
||||
$as_test_x conftest$ac_exeext; then
|
||||
eval "$as_ac_var=yes"
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
eval "$as_ac_var=no"
|
||||
fi
|
||||
|
||||
rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
fi
|
||||
ac_res=`eval echo '${'$as_ac_var'}'`
|
||||
{ echo "$as_me:$LINENO: result: $ac_res" >&5
|
||||
echo "${ECHO_T}$ac_res" >&6; }
|
||||
if test `eval echo '${'$as_ac_var'}'` = yes; then
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
|
||||
_ACEOF
|
||||
|
||||
else
|
||||
{ { echo "$as_me:$LINENO: error: bailing out" >&5
|
||||
echo "$as_me: error: bailing out" >&2;}
|
||||
{ (exit 1); exit 1; }; }
|
||||
fi
|
||||
done
|
||||
|
||||
fi
|
||||
|
||||
if test x$CLUSTER != xnone; then
|
||||
|
||||
|
||||
@@ -11269,10 +11122,11 @@ fi
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
################################################################################
|
||||
ac_config_files="$ac_config_files Makefile make.tmpl daemons/Makefile daemons/clvmd/Makefile dmeventd/Makefile dmeventd/mirror/Makefile doc/Makefile include/Makefile lib/Makefile lib/format1/Makefile lib/format_pool/Makefile lib/locking/Makefile lib/mirror/Makefile lib/snapshot/Makefile man/Makefile po/Makefile scripts/Makefile tools/Makefile tools/version.h tools/fsadm/Makefile test/mm/Makefile test/device/Makefile test/format1/Makefile test/regex/Makefile test/filters/Makefile"
|
||||
ac_config_files="$ac_config_files Makefile make.tmpl daemons/Makefile daemons/clvmd/Makefile dmeventd/Makefile dmeventd/mirror/Makefile 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
|
||||
|
||||
81
configure.in
81
configure.in
@@ -1,8 +1,8 @@
|
||||
##
|
||||
## Copyright (C) 2000-2004 Sistina Software, Inc. All rights reserved.
|
||||
## Copyright (C) 2004 Red Hat, Inc. All rights reserved.
|
||||
## Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
|
||||
##
|
||||
## This file is part of the LVM2.
|
||||
## This file is part of LVM2.
|
||||
##
|
||||
## This copyrighted material is made available to anyone wishing to use,
|
||||
## modify, copy, or redistribute it subject to the terms and conditions
|
||||
@@ -24,7 +24,7 @@ AC_CONFIG_HEADERS(lib/misc/configure.h)
|
||||
|
||||
################################################################################
|
||||
dnl -- Setup the directory where autoconf has auxilary files
|
||||
AC_CONFIG_AUX_DIR(autoconf)
|
||||
AC_CONFIG_AUX_DIR(autoconf)
|
||||
|
||||
################################################################################
|
||||
dnl -- Get system type
|
||||
@@ -363,7 +363,7 @@ AC_MSG_RESULT($CMDLIB)
|
||||
|
||||
################################################################################
|
||||
dnl -- Enable fsadm
|
||||
AC_MSG_CHECKING(whether to build fsadm)
|
||||
AC_MSG_CHECKING(whether to install fsadm)
|
||||
AC_ARG_ENABLE(fsadm, [ --enable-fsadm Enable fsadm],
|
||||
FSADM=$enableval)
|
||||
AC_MSG_RESULT($FSADM)
|
||||
@@ -453,6 +453,18 @@ if test x$SELINUX = xyes; then
|
||||
else
|
||||
AC_MSG_WARN(Disabling selinux)
|
||||
fi
|
||||
|
||||
# With --enable-static_link and selinux enabled, linking lvm.static
|
||||
# fails on at least Debian unstable due to unsatisfied references
|
||||
# to pthread_mutex_lock and _unlock. See if we need -lpthread.
|
||||
if test "$STATIC_LINK-$HAVE_SELINUX" = yes-yes; then
|
||||
lvm_saved_libs=$LIBS
|
||||
LIBS="$LIBS -static"
|
||||
AC_SEARCH_LIBS([pthread_mutex_lock], [pthread],
|
||||
[test "$ac_cv_search_pthread_mutex_lock" = "none required" ||
|
||||
LIB_PTHREAD=-lpthread])
|
||||
LIBS=$lvm_saved_libs
|
||||
fi
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
@@ -526,6 +538,12 @@ AC_ARG_WITH(dmdir,
|
||||
[ DMDIR="$withval" CPPFLAGS="$CPPFLAGS -I$DMDIR/include"],
|
||||
[ DMDIR= ])
|
||||
|
||||
# Convert a relative dir name to absolute.
|
||||
case $DMDIR in
|
||||
/*) ;;
|
||||
*) DMDIR="`pwd`/$DMDIR" ;;
|
||||
esac
|
||||
|
||||
################################################################################
|
||||
dnl -- Ensure additional headers required
|
||||
if test x$READLINE = xyes; then
|
||||
@@ -540,11 +558,6 @@ if test x$CLVMD != xnone; then
|
||||
AC_FUNC_SELECT_ARGTYPES
|
||||
fi
|
||||
|
||||
if test x$FSADM = xyes; then
|
||||
AC_CHECK_HEADERS(fstab.h sys/mount.h sys/vfs.h,,AC_MSG_ERROR(bailing out))
|
||||
AC_CHECK_FUNCS(memmove,,AC_MSG_ERROR(bailing out))
|
||||
fi
|
||||
|
||||
if test x$CLUSTER != xnone; then
|
||||
AC_CHECK_HEADERS(sys/socket.h sys/un.h,,AC_MSG_ERROR(bailing out))
|
||||
AC_CHECK_FUNCS(socket,,AC_MSG_ERROR(bailing out))
|
||||
@@ -617,36 +630,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
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# Copyright (C) 2004 Red Hat, Inc. All rights reserved.
|
||||
#
|
||||
# This file is part of the LVM2.
|
||||
# This file is part of LVM2.
|
||||
#
|
||||
# This copyrighted material is made available to anyone wishing to use,
|
||||
# modify, copy, or redistribute it subject to the terms and conditions
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# Copyright (C) 2004 Red Hat, Inc. All rights reserved.
|
||||
#
|
||||
# This file is part of the LVM2.
|
||||
# This file is part of LVM2.
|
||||
#
|
||||
# This copyrighted material is made available to anyone wishing to use,
|
||||
# modify, copy, or redistribute it subject to the terms and conditions
|
||||
|
||||
@@ -67,4 +67,5 @@ static const char CLVMD_SOCKNAME[] = "\0clvmd";
|
||||
#define CLVMD_CMD_REFRESH 40
|
||||
#define CLVMD_CMD_GET_CLUSTERNAME 41
|
||||
#define CLVMD_CMD_SET_DEBUG 42
|
||||
#define CLVMD_CMD_VG_BACKUP 43
|
||||
#endif
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -722,10 +722,15 @@ int dm_event_get_registered_device(struct dm_event_handler *dmevh, int next)
|
||||
dm_event_handler_set_dso(dmevh, reply_dso);
|
||||
dm_event_handler_set_event_mask(dmevh, reply_mask);
|
||||
|
||||
if (reply_dso)
|
||||
if (reply_dso) {
|
||||
dm_free(reply_dso);
|
||||
if (reply_uuid)
|
||||
reply_dso = NULL;
|
||||
}
|
||||
|
||||
if (reply_uuid) {
|
||||
dm_free(reply_uuid);
|
||||
reply_uuid = NULL;
|
||||
}
|
||||
|
||||
dmevh->dev_name = dm_strdup(dm_task_get_name(dmt));
|
||||
if (!dmevh->dev_name) {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
# Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
|
||||
#
|
||||
# This file is part of the LVM2.
|
||||
# This file is part of LVM2.
|
||||
#
|
||||
# This copyrighted material is made available to anyone wishing to use,
|
||||
# modify, copy, or redistribute it subject to the terms and conditions
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -22,8 +22,8 @@ LVM2 that is running the LV's on my development box.
|
||||
}
|
||||
|
||||
|
||||
The important this to note is the devices section which makes sure that
|
||||
only the loopback devices are considered for LVM2 operations.
|
||||
The important thing to note is the devices section which makes sure
|
||||
that only the loopback devices are considered for LVM2 operations.
|
||||
|
||||
4) When you want to use this test setup just set the environment
|
||||
variable LVM_SYSTEM_DIR to point to your config directory
|
||||
@@ -39,8 +39,3 @@ LVM2 that is running the LV's on my development box.
|
||||
7) Test away. Make sure that you are explicit about which lvm
|
||||
executable you want to execute (eg, ./lvm if you are in
|
||||
LVM2/tools).
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
../lib/misc/crc.h
|
||||
../lib/misc/intl.h
|
||||
../lib/misc/util.h
|
||||
../lib/misc/last-path-component.h
|
||||
../lib/misc/lib.h
|
||||
../lib/misc/lvm-exec.h
|
||||
../lib/misc/lvm-file.h
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
# Copyright (C) 2004 Red Hat, Inc. All rights reserved.
|
||||
#
|
||||
# This file is part of the LVM2.
|
||||
# This file is part of LVM2.
|
||||
#
|
||||
# This copyrighted material is made available to anyone wishing to use,
|
||||
# modify, copy, or redistribute it subject to the terms and conditions
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
# Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
|
||||
#
|
||||
# This file is part of the LVM2.
|
||||
# This file is part of LVM2.
|
||||
#
|
||||
# This copyrighted material is made available to anyone wishing to use,
|
||||
# modify, copy, or redistribute it subject to the terms and conditions
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
4
lib/cache/lvmcache.c
vendored
4
lib/cache/lvmcache.c
vendored
@@ -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] ? ")" : "");
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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")) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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))) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)));
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
};
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved.
|
||||
# Copyright (C) 2004 Red Hat, Inc. All rights reserved.
|
||||
#
|
||||
# This file is part of the LVM2.
|
||||
# This file is part of LVM2.
|
||||
#
|
||||
# This copyrighted material is made available to anyone wishing to use,
|
||||
# modify, copy, or redistribute it subject to the terms and conditions
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef CLUSTER_LOCKING_INTERNAL
|
||||
int lock_resource(struct cmd_context *cmd, const char *resource, int flags);
|
||||
int lock_resource(struct cmd_context *cmd, const char *resource, uint32_t flags);
|
||||
void locking_end(void);
|
||||
int locking_init(int type, struct config_tree *cf, uint32_t *flags);
|
||||
#endif
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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\"",
|
||||
|
||||
@@ -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 "
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
27
lib/misc/last-path-component.h
Normal file
27
lib/misc/last-path-component.h
Normal 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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.")
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")) {
|
||||
|
||||
@@ -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")) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
*****************************************************************************/
|
||||
|
||||
@@ -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, ¤t_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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user