1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-09-23 17:44:22 +03:00

Compare commits

..

1 Commits

Author SHA1 Message Date
David Teigland
83d62fbda6 generate man pages 2017-02-13 08:21:58 -06:00
285 changed files with 3051 additions and 34588 deletions

View File

@@ -59,8 +59,6 @@ liblvm: lib
daemons: lib libdaemon tools
tools: lib libdaemon device-mapper
po: tools daemons
man: tools
all_man: tools
scripts: liblvm libdm
lib.device-mapper: include.device-mapper
@@ -100,7 +98,7 @@ CLEAN_DIRS += autom4te.cache
check check_system check_cluster check_local check_lvmetad check_lvmpolld check_lvmlockd_test check_lvmlockd_dlm check_lvmlockd_sanlock unit: all
$(MAKE) -C test $(@)
conf.generate man.generate: tools
conf.generate: tools
# how to use parenthesis in makefiles
leftparen:=(
@@ -130,9 +128,8 @@ rpm: dist
$(top_srcdir)/spec/source.inc >$(rpmbuilddir)/SOURCES/source.inc
rpmbuild -v --define "_topdir $(rpmbuilddir)" -ba $(top_srcdir)/spec/lvm2.spec
generate: conf.generate man.generate
generate: conf.generate
$(MAKE) -C conf generate
$(MAKE) -C man generate
all_man:
$(MAKE) -C man all_man

5
README
View File

@@ -6,12 +6,11 @@ Installation instructions are in INSTALL.
There is no warranty - see COPYING and COPYING.LIB.
Tarballs are available from:
ftp://sourceware.org/pub/lvm2/
ftp://sources.redhat.com/pub/lvm2/
The source code is stored in git:
https://sourceware.org/git/?p=lvm2.git
git clone git://sourceware.org/git/lvm2.git
http://git.fedorahosted.org/git/lvm2.git
git clone git://git.fedorahosted.org/git/lvm2.git
Mailing list for general discussion related to LVM2:
linux-lvm@redhat.com

View File

@@ -1,31 +1,5 @@
Version 2.02.169 -
=====================================
Remove obsolete lvmchange binary - convert to built-in command.
Lvdisplay [-m] shows more informations for cached volumes.
Add option for lvcreate/lvconvert --cachemetadataformat auto|1|2.
Support cache segment with configurable metadata format.
Add allocation/cache_metadata_format profilable setttings.
Use function cache_set_params() for both lvcreate and lvconvert.
Skip rounding on cache chunk size boudary when create cache LV.
Improve cache_set_params support for chunk_size selection.
Fix metadata profile allocation/cache_[mode|policy] setting.
Fix missing support for using allocation/cache_pool_chunk_size setting.
Upstream git moved to https://sourceware.org/git/?p=lvm2
Support conversion of raid type, stripesize and number of disks
Reject writemostly/writebehind in lvchange during resynchronization.
Deactivate active origin first before removal for improved workflow.
Fix regression of accepting options --type and -m with lvresize (2.02.158).
Add lvconvert --swapmetadata, new specific way to swap pool metadata LVs.
Add lvconvert --startpoll, new specific way to start polling conversions.
Add lvconvert --mergethin, new specific way to merge thin snapshots.
Add lvconvert --mergemirrors, new specific way to merge split mirrors.
Add lvconvert --mergesnapshot, new specific way to combine cow LVs.
Split up lvconvert code based on command definitions.
Split up lvchange code based on command definitions.
Generate help output and man pages from command definitions.
Verify all command line items against command definition.
Match every command run to one command definition.
Specify every allowed command definition/syntax in command-lines.in.
Add extra memory page when limiting pthread stack size in clvmd.
Support striped/raid0* <-> raid10_near conversions
Support shrinking of RaidLvs

View File

@@ -1,9 +1,5 @@
Version 1.02.138 -
=====================================
Provide dm_tree_node_add_cache_target@base compatible symbol.
Support DM_CACHE_FEATURE_METADATA2, new cache metadata format 2.
Improve code to handle mode mask for cache nodes.
Cache status check for passthrough also require trailing space.
Add extra memory page when limiting pthread stack size in dmeventd.
Avoids immediate resume when preloaded device is smaller.
Do not suppress kernel key description in dmsetup table output.

View File

@@ -9,6 +9,6 @@ allocation {
cache_mode = "writethrough"
cache_policy = "smq"
cache_settings {
# currently no settings for "smq" policy
# currently no settins for "smq" policy
}
}

View File

@@ -403,20 +403,9 @@ allocation {
# This configuration option has an automatic default value.
# cache_mode = "writethrough"
# Configuration option allocation/cache_metadata_format.
# Sets default metadata format for new cache.
#
# Accepted values:
# 0 Automatically detected best available format
# 1 Original format
# 2 Improved 2nd. generation format
#
# This configuration option has an automatic default value.
# cache_metadata_format = 0
# Configuration option allocation/cache_policy.
# The default cache policy used for new cache volume.
# Since kernel 4.2 the default policy is smq (Stochastic multiqueue),
# Since kernel 4.2 the default policy is smq (Stochastic multique),
# otherwise the older mq (Multiqueue) policy is selected.
# This configuration option does not have a default value defined.
@@ -1024,7 +1013,7 @@ global {
# Configuration option global/cache_disabled_features.
# Features to not use in the cache driver.
# This can be helpful for testing, or to avoid using a feature that is
# causing problems. Features include: policy_mq, policy_smq, metadata2.
# causing problems. Features include: policy_mq, policy_smq.
#
# Example
# cache_disabled_features = [ "policy_smq" ]
@@ -1288,9 +1277,8 @@ activation {
# Configuration option activation/raid_region_size.
# Size in KiB of each raid or mirror synchronization region.
# The clean/dirty state of data is tracked for each region.
# The value is rounded down to a power of two if necessary, and
# is ignored if it is not a multiple of the machine memory page size.
# For raid or mirror segment types, this is the amount of data that is
# copied at once when initializing, or moved at once by pvmove.
raid_region_size = 512
# Configuration option activation/error_when_full.

250
configure vendored
View File

@@ -702,7 +702,6 @@ BLKDEACTIVATE
FSADM
ELDFLAGS
DM_LIB_PATCHLEVEL
DMFILEMAPD
DMEVENTD_PATH
DMEVENTD
DL_LIBS
@@ -738,7 +737,6 @@ CLDNOWHOLEARCHIVE
CLDFLAGS
CACHE
BUILD_NOTIFYDBUS
BUILD_DMFILEMAPD
BUILD_LOCKDDLM
BUILD_LOCKDSANLOCK
BUILD_LVMLOCKD
@@ -823,8 +821,6 @@ HAVE_PIE
POW_LIB
LIBOBJS
ALLOCA
SORT
WC
CHMOD
CSCOPE_CMD
CFLOW_CMD
@@ -962,7 +958,6 @@ enable_use_lvmetad
with_lvmetad_pidfile
enable_use_lvmpolld
with_lvmpolld_pidfile
enable_dmfilemapd
enable_notify_dbus
enable_blkid_wiping
enable_udev_systemd_background_jobs
@@ -1697,7 +1692,6 @@ Optional Features:
--disable-use-lvmlockd disable usage of LVM lock daemon
--disable-use-lvmetad disable usage of LVM Metadata Daemon
--disable-use-lvmpolld disable usage of LVM Poll Daemon
--enable-dmfilemapd enable the dmstats filemap daemon
--enable-notify-dbus enable LVM notification using dbus
--disable-blkid_wiping disable libblkid detection of signatures when wiping
and use native code instead
@@ -5240,202 +5234,6 @@ else
CHMOD="$ac_cv_path_CHMOD"
fi
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}wc", so it can be a program name with args.
set dummy ${ac_tool_prefix}wc; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_path_WC+:} false; then :
$as_echo_n "(cached) " >&6
else
case $WC in
[\\/]* | ?:[\\/]*)
ac_cv_path_WC="$WC" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_WC="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
;;
esac
fi
WC=$ac_cv_path_WC
if test -n "$WC"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $WC" >&5
$as_echo "$WC" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
fi
if test -z "$ac_cv_path_WC"; then
ac_pt_WC=$WC
# Extract the first word of "wc", so it can be a program name with args.
set dummy wc; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_path_ac_pt_WC+:} false; then :
$as_echo_n "(cached) " >&6
else
case $ac_pt_WC in
[\\/]* | ?:[\\/]*)
ac_cv_path_ac_pt_WC="$ac_pt_WC" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_ac_pt_WC="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
;;
esac
fi
ac_pt_WC=$ac_cv_path_ac_pt_WC
if test -n "$ac_pt_WC"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_WC" >&5
$as_echo "$ac_pt_WC" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
if test "x$ac_pt_WC" = x; then
WC=""
else
case $cross_compiling:$ac_tool_warned in
yes:)
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
WC=$ac_pt_WC
fi
else
WC="$ac_cv_path_WC"
fi
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}sort", so it can be a program name with args.
set dummy ${ac_tool_prefix}sort; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_path_SORT+:} false; then :
$as_echo_n "(cached) " >&6
else
case $SORT in
[\\/]* | ?:[\\/]*)
ac_cv_path_SORT="$SORT" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_SORT="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
;;
esac
fi
SORT=$ac_cv_path_SORT
if test -n "$SORT"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $SORT" >&5
$as_echo "$SORT" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
fi
if test -z "$ac_cv_path_SORT"; then
ac_pt_SORT=$SORT
# Extract the first word of "sort", so it can be a program name with args.
set dummy sort; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_path_ac_pt_SORT+:} false; then :
$as_echo_n "(cached) " >&6
else
case $ac_pt_SORT in
[\\/]* | ?:[\\/]*)
ac_cv_path_ac_pt_SORT="$ac_pt_SORT" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_ac_pt_SORT="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
;;
esac
fi
ac_pt_SORT=$ac_cv_path_ac_pt_SORT
if test -n "$ac_pt_SORT"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_SORT" >&5
$as_echo "$ac_pt_SORT" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
if test "x$ac_pt_SORT" = x; then
SORT=""
else
case $cross_compiling:$ac_tool_warned in
yes:)
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
SORT=$ac_pt_SORT
fi
else
SORT="$ac_cv_path_SORT"
fi
################################################################################
ac_header_dirent=no
@@ -12078,32 +11876,6 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
################################################################################
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build dmfilemapd" >&5
$as_echo_n "checking whether to build dmfilemapd... " >&6; }
# Check whether --enable-dmfilemapd was given.
if test "${enable_dmfilemapd+set}" = set; then :
enableval=$enable_dmfilemapd; DMFILEMAPD=$enableval
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $DMFILEMAPD" >&5
$as_echo "$DMFILEMAPD" >&6; }
BUILD_DMFILEMAPD=$DMFILEMAPD
$as_echo "#define DMFILEMAPD 1" >>confdefs.h
if test "$DMFILEMAPD" = yes; then
ac_fn_c_check_header_mongrel "$LINENO" "linux/fiemap.h" "ac_cv_header_linux_fiemap_h" "$ac_includes_default"
if test "x$ac_cv_header_linux_fiemap_h" = xyes; then :
else
as_fn_error $? "--enable-dmfilemapd requires fiemap.h" "$LINENO" 5
fi
fi
################################################################################
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build notifydbus" >&5
$as_echo_n "checking whether to build notifydbus... " >&6; }
@@ -15153,23 +14925,6 @@ done
fi
if test "$DMFILEMAPD" = yes; then
for ac_header in sys/inotify.h
do :
ac_fn_c_check_header_mongrel "$LINENO" "sys/inotify.h" "ac_cv_header_sys_inotify_h" "$ac_includes_default"
if test "x$ac_cv_header_sys_inotify_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_SYS_INOTIFY_H 1
_ACEOF
else
hard_bailout
fi
done
fi
################################################################################
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}modprobe", so it can be a program name with args.
@@ -15629,13 +15384,11 @@ LVM_LIBAPI=`echo "$VER" | $AWK -F '[()]' '{print $2}'`
################################################################################
ac_config_files="$ac_config_files Makefile make.tmpl daemons/Makefile daemons/clvmd/Makefile daemons/cmirrord/Makefile daemons/dmeventd/Makefile daemons/dmeventd/libdevmapper-event.pc daemons/dmeventd/plugins/Makefile daemons/dmeventd/plugins/lvm2/Makefile daemons/dmeventd/plugins/raid/Makefile daemons/dmeventd/plugins/mirror/Makefile daemons/dmeventd/plugins/snapshot/Makefile daemons/dmeventd/plugins/thin/Makefile daemons/dmfilemapd/Makefile daemons/lvmdbusd/Makefile daemons/lvmdbusd/path.py daemons/lvmetad/Makefile daemons/lvmpolld/Makefile daemons/lvmlockd/Makefile conf/Makefile conf/example.conf conf/lvmlocal.conf conf/command_profile_template.profile conf/metadata_profile_template.profile include/.symlinks include/Makefile lib/Makefile lib/format1/Makefile lib/format_pool/Makefile lib/locking/Makefile lib/mirror/Makefile lib/replicator/Makefile include/lvm-version.h lib/raid/Makefile lib/snapshot/Makefile lib/thin/Makefile lib/cache_segtype/Makefile libdaemon/Makefile libdaemon/client/Makefile libdaemon/server/Makefile libdm/Makefile libdm/libdevmapper.pc liblvm/Makefile liblvm/liblvm2app.pc man/Makefile po/Makefile python/Makefile python/setup.py scripts/blkdeactivate.sh scripts/blk_availability_init_red_hat scripts/blk_availability_systemd_red_hat.service scripts/clvmd_init_red_hat scripts/cmirrord_init_red_hat scripts/com.redhat.lvmdbus1.service scripts/dm_event_systemd_red_hat.service scripts/dm_event_systemd_red_hat.socket scripts/lvm2_cluster_activation_red_hat.sh scripts/lvm2_cluster_activation_systemd_red_hat.service scripts/lvm2_clvmd_systemd_red_hat.service scripts/lvm2_cmirrord_systemd_red_hat.service scripts/lvm2_lvmdbusd_systemd_red_hat.service scripts/lvm2_lvmetad_init_red_hat scripts/lvm2_lvmetad_systemd_red_hat.service scripts/lvm2_lvmetad_systemd_red_hat.socket scripts/lvm2_lvmpolld_init_red_hat scripts/lvm2_lvmpolld_systemd_red_hat.service scripts/lvm2_lvmpolld_systemd_red_hat.socket scripts/lvm2_lvmlockd_systemd_red_hat.service scripts/lvm2_lvmlocking_systemd_red_hat.service scripts/lvm2_monitoring_init_red_hat scripts/lvm2_monitoring_systemd_red_hat.service scripts/lvm2_pvscan_systemd_red_hat@.service scripts/lvm2_tmpfiles_red_hat.conf scripts/lvmdump.sh scripts/Makefile test/Makefile test/api/Makefile test/unit/Makefile tools/Makefile udev/Makefile unit-tests/datastruct/Makefile unit-tests/regex/Makefile unit-tests/mm/Makefile"
ac_config_files="$ac_config_files Makefile make.tmpl daemons/Makefile daemons/clvmd/Makefile daemons/cmirrord/Makefile daemons/dmeventd/Makefile daemons/dmeventd/libdevmapper-event.pc daemons/dmeventd/plugins/Makefile daemons/dmeventd/plugins/lvm2/Makefile daemons/dmeventd/plugins/raid/Makefile daemons/dmeventd/plugins/mirror/Makefile daemons/dmeventd/plugins/snapshot/Makefile daemons/dmeventd/plugins/thin/Makefile daemons/lvmdbusd/Makefile daemons/lvmdbusd/path.py daemons/lvmetad/Makefile daemons/lvmpolld/Makefile daemons/lvmlockd/Makefile conf/Makefile conf/example.conf conf/lvmlocal.conf conf/command_profile_template.profile conf/metadata_profile_template.profile include/.symlinks include/Makefile lib/Makefile lib/format1/Makefile lib/format_pool/Makefile lib/locking/Makefile lib/mirror/Makefile lib/replicator/Makefile include/lvm-version.h lib/raid/Makefile lib/snapshot/Makefile lib/thin/Makefile lib/cache_segtype/Makefile libdaemon/Makefile libdaemon/client/Makefile libdaemon/server/Makefile libdm/Makefile libdm/libdevmapper.pc liblvm/Makefile liblvm/liblvm2app.pc man/Makefile po/Makefile python/Makefile python/setup.py scripts/blkdeactivate.sh scripts/blk_availability_init_red_hat scripts/blk_availability_systemd_red_hat.service scripts/clvmd_init_red_hat scripts/cmirrord_init_red_hat scripts/com.redhat.lvmdbus1.service scripts/dm_event_systemd_red_hat.service scripts/dm_event_systemd_red_hat.socket scripts/lvm2_cluster_activation_red_hat.sh scripts/lvm2_cluster_activation_systemd_red_hat.service scripts/lvm2_clvmd_systemd_red_hat.service scripts/lvm2_cmirrord_systemd_red_hat.service scripts/lvm2_lvmdbusd_systemd_red_hat.service scripts/lvm2_lvmetad_init_red_hat scripts/lvm2_lvmetad_systemd_red_hat.service scripts/lvm2_lvmetad_systemd_red_hat.socket scripts/lvm2_lvmpolld_init_red_hat scripts/lvm2_lvmpolld_systemd_red_hat.service scripts/lvm2_lvmpolld_systemd_red_hat.socket scripts/lvm2_lvmlockd_systemd_red_hat.service scripts/lvm2_lvmlocking_systemd_red_hat.service scripts/lvm2_monitoring_init_red_hat scripts/lvm2_monitoring_systemd_red_hat.service scripts/lvm2_pvscan_systemd_red_hat@.service scripts/lvm2_tmpfiles_red_hat.conf scripts/lvmdump.sh scripts/Makefile test/Makefile test/api/Makefile test/unit/Makefile tools/Makefile udev/Makefile unit-tests/datastruct/Makefile unit-tests/regex/Makefile unit-tests/mm/Makefile"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
@@ -16343,7 +16096,6 @@ do
"daemons/dmeventd/plugins/mirror/Makefile") CONFIG_FILES="$CONFIG_FILES daemons/dmeventd/plugins/mirror/Makefile" ;;
"daemons/dmeventd/plugins/snapshot/Makefile") CONFIG_FILES="$CONFIG_FILES daemons/dmeventd/plugins/snapshot/Makefile" ;;
"daemons/dmeventd/plugins/thin/Makefile") CONFIG_FILES="$CONFIG_FILES daemons/dmeventd/plugins/thin/Makefile" ;;
"daemons/dmfilemapd/Makefile") CONFIG_FILES="$CONFIG_FILES daemons/dmfilemapd/Makefile" ;;
"daemons/lvmdbusd/Makefile") CONFIG_FILES="$CONFIG_FILES daemons/lvmdbusd/Makefile" ;;
"daemons/lvmdbusd/path.py") CONFIG_FILES="$CONFIG_FILES daemons/lvmdbusd/path.py" ;;
"daemons/lvmetad/Makefile") CONFIG_FILES="$CONFIG_FILES daemons/lvmetad/Makefile" ;;

View File

@@ -86,8 +86,6 @@ AC_PROG_RANLIB
AC_PATH_TOOL(CFLOW_CMD, cflow)
AC_PATH_TOOL(CSCOPE_CMD, cscope)
AC_PATH_TOOL(CHMOD, chmod)
AC_PATH_TOOL(WC, wc)
AC_PATH_TOOL(SORT, sort)
################################################################################
dnl -- Check for header files.
@@ -1271,21 +1269,6 @@ fi
AC_DEFINE_UNQUOTED(DEFAULT_USE_LVMPOLLD, [$DEFAULT_USE_LVMPOLLD],
[Use lvmpolld by default.])
################################################################################
dnl -- Check dmfilemapd
AC_MSG_CHECKING(whether to build dmfilemapd)
AC_ARG_ENABLE(dmfilemapd, AC_HELP_STRING([--enable-dmfilemapd],
[enable the dmstats filemap daemon]),
DMFILEMAPD=$enableval)
AC_MSG_RESULT($DMFILEMAPD)
BUILD_DMFILEMAPD=$DMFILEMAPD
AC_DEFINE([DMFILEMAPD], 1, [Define to 1 to enable the device-mapper filemap daemon.])
dnl -- dmfilemapd requires FIEMAP
if test "$DMFILEMAPD" = yes; then
AC_CHECK_HEADER([linux/fiemap.h], , [AC_MSG_ERROR(--enable-dmfilemapd requires fiemap.h)])
fi
################################################################################
dnl -- Build notifydbus
AC_MSG_CHECKING(whether to build notifydbus)
@@ -1870,10 +1853,6 @@ if test "$UDEV_SYNC" = yes; then
AC_CHECK_HEADERS(sys/ipc.h sys/sem.h,,hard_bailout)
fi
if test "$DMFILEMAPD" = yes; then
AC_CHECK_HEADERS([sys/inotify.h],,hard_bailout)
fi
################################################################################
AC_PATH_TOOL(MODPROBE_CMD, modprobe)
@@ -2013,7 +1992,6 @@ AC_SUBST(BUILD_LVMPOLLD)
AC_SUBST(BUILD_LVMLOCKD)
AC_SUBST(BUILD_LOCKDSANLOCK)
AC_SUBST(BUILD_LOCKDDLM)
AC_SUBST(BUILD_DMFILEMAPD)
AC_SUBST(BUILD_NOTIFYDBUS)
AC_SUBST(CACHE)
AC_SUBST(CFLAGS)
@@ -2063,7 +2041,6 @@ AC_SUBST(DLM_LIBS)
AC_SUBST(DL_LIBS)
AC_SUBST(DMEVENTD)
AC_SUBST(DMEVENTD_PATH)
AC_SUBST(DMFILEMAPD)
AC_SUBST(DM_LIB_PATCHLEVEL)
AC_SUBST(ELDFLAGS)
AC_SUBST(FSADM)
@@ -2179,7 +2156,6 @@ daemons/dmeventd/plugins/raid/Makefile
daemons/dmeventd/plugins/mirror/Makefile
daemons/dmeventd/plugins/snapshot/Makefile
daemons/dmeventd/plugins/thin/Makefile
daemons/dmfilemapd/Makefile
daemons/lvmdbusd/Makefile
daemons/lvmdbusd/path.py
daemons/lvmetad/Makefile

View File

@@ -71,17 +71,6 @@ void model_FD_ZERO(void *fdset)
((long*)fdset)[i] = 0;
}
/* Resent Coverity reports quite weird errors... */
int *__errno_location(void)
{
}
const unsigned short **__ctype_b_loc (void)
{
}
/*
* Added extra pointer check to not need these models,
* for now just keep then in file

View File

@@ -48,12 +48,8 @@ ifeq ("@BUILD_LVMDBUSD@", "yes")
SUBDIRS += lvmdbusd
endif
ifeq ("@BUILD_DMFILEMAPD@", "yes")
SUBDIRS += dmfilemapd
endif
ifeq ($(MAKECMDGOALS),distclean)
SUBDIRS = clvmd cmirrord dmeventd lvmetad lvmpolld lvmlockd lvmdbusd dmfilemapd
SUBDIRS = clvmd cmirrord dmeventd lvmetad lvmpolld lvmlockd lvmdbusd
endif
include $(top_builddir)/make.tmpl

View File

@@ -111,9 +111,6 @@ static int _remove_failed_devices(const char *cmd_lvscan, const char *cmd_lvconv
return 0;
}
if (!dmeventd_lvm2_run_with_lock(cmd_lvscan))
log_warn("WARNING: Re-scan of mirrored device %s failed.", device);
log_info("Repair of mirrored device %s finished successfully.", device);
return 1;
@@ -186,10 +183,17 @@ int register_device(const char *device,
if (!dmeventd_lvm2_init_with_pool("mirror_state", state))
goto_bad;
/* CANNOT use --config as this disables cached content */
if (!dmeventd_lvm2_command(state->mem, state->cmd_lvconvert, sizeof(state->cmd_lvconvert),
"lvconvert --repair --use-policies", device))
if (!dmeventd_lvm2_command(state->mem, state->cmd_lvscan, sizeof(state->cmd_lvscan),
"lvscan --cache", device)) {
dmeventd_lvm2_exit_with_pool(state);
goto_bad;
}
if (!dmeventd_lvm2_command(state->mem, state->cmd_lvconvert, sizeof(state->cmd_lvconvert),
"lvconvert --repair --use-policies", device)) {
dmeventd_lvm2_exit_with_pool(state);
goto_bad;
}
*user = state;
@@ -199,9 +203,6 @@ int register_device(const char *device,
bad:
log_error("Failed to monitor mirror %s.", device);
if (state)
dmeventd_lvm2_exit_with_pool(state);
return 0;
}

View File

@@ -140,8 +140,10 @@ int register_device(const char *device,
"lvscan --cache", device) ||
!dmeventd_lvm2_command(state->mem, state->cmd_lvconvert, sizeof(state->cmd_lvconvert),
"lvconvert --config devices{ignore_suspended_devices=1} "
"--repair --use-policies", device))
"--repair --use-policies", device)) {
dmeventd_lvm2_exit_with_pool(state);
goto_bad;
}
*user = state;
@@ -151,9 +153,6 @@ int register_device(const char *device,
bad:
log_error("Failed to monitor RAID %s.", device);
if (state)
dmeventd_lvm2_exit_with_pool(state);
return 0;
}

View File

@@ -254,8 +254,10 @@ int register_device(const char *device,
if (!dmeventd_lvm2_command(state->mem, state->cmd_lvextend,
sizeof(state->cmd_lvextend),
"lvextend --use-policies", device))
"lvextend --use-policies", device)) {
dmeventd_lvm2_exit_with_pool(state);
goto_bad;
}
state->percent_check = CHECK_MINIMUM;
*user = state;
@@ -266,9 +268,6 @@ int register_device(const char *device,
bad:
log_error("Failed to monitor snapshot %s.", device);
if (state)
dmeventd_lvm2_exit_with_pool(state);
return 0;
}

View File

@@ -359,8 +359,10 @@ int register_device(const char *device,
goto_bad;
if (!dmeventd_lvm2_command(state->mem, cmd_str, sizeof(cmd_str),
"_dmeventd_thin_command", device))
"_dmeventd_thin_command", device)) {
dmeventd_lvm2_exit_with_pool(state);
goto_bad;
}
if (strncmp(cmd_str, "lvm ", 4) == 0) {
if (!(state->cmd_str = dm_pool_strdup(state->mem, cmd_str + 4))) {
@@ -399,9 +401,6 @@ inval:
bad:
log_error("Failed to monitor thin pool %s.", device);
if (state)
dmeventd_lvm2_exit_with_pool(state);
return 0;
}

View File

@@ -1 +0,0 @@
dmfilemapd

View File

@@ -1,68 +0,0 @@
#
# Copyright (C) 2016 Red Hat, Inc. All rights reserved.
#
# This file is part of the device-mapper userspace tools.
#
# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
SOURCES = dmfilemapd.c
TARGETS = dmfilemapd
.PHONY: install_dmfilemapd install_dmfilemapd_static
INSTALL_DMFILEMAPD_TARGETS = install_dmfilemapd_dynamic
CLEAN_TARGETS = dmfilemapd.static
CFLOW_LIST = $(SOURCES)
CFLOW_LIST_TARGET = $(LIB_NAME).cflow
CFLOW_TARGET = dmfilemapd
include $(top_builddir)/make.tmpl
all: device-mapper
device-mapper: $(TARGETS)
LIBS += -ldevmapper
CFLAGS_dmfilemapd.o += $(EXTRA_EXEC_CFLAGS)
dmfilemapd: $(LIB_SHARED) dmfilemapd.o
$(CC) $(CFLAGS) $(LDFLAGS) $(EXTRA_EXEC_LDFLAGS) $(ELDFLAGS) -L. -o $@ dmfilemapd.o \
$(DL_LIBS) $(LVMLIBS) $(LIBS) -rdynamic
dmfilemapd.static: $(LIB_STATIC) dmfilemapd.o $(interfacebuilddir)/libdevmapper.a
$(CC) $(CFLAGS) $(LDFLAGS) $(ELDFLAGS) -static -L. -L$(interfacebuilddir) -o $@ \
dmfilemapd.o $(DL_LIBS) $(LVMLIBS) $(LIBS) $(STATIC_LIBS)
ifneq ("$(CFLOW_CMD)", "")
CFLOW_SOURCES = $(addprefix $(srcdir)/, $(SOURCES))
-include $(top_builddir)/libdm/libdevmapper.cflow
-include $(top_builddir)/lib/liblvm-internal.cflow
-include $(top_builddir)/lib/liblvm2cmd.cflow
-include $(top_builddir)/daemons/dmfilemapd/$(LIB_NAME).cflow
endif
install_dmfilemapd_dynamic: dmfilemapd
$(INSTALL_PROGRAM) -D $< $(sbindir)/$(<F)
install_dmfilemapd_static: dmfilemapd.static
$(INSTALL_PROGRAM) -D $< $(staticdir)/$(<F)
install_dmfilemapd: $(INSTALL_DMEVENTD_TARGETS)
install: install_dmfilemapd
install_device-mapper: install_dmfilemapd

View File

@@ -1,802 +0,0 @@
/*
* Copyright (C) 2016 Red Hat, Inc. All rights reserved.
*
* This file is part of the device-mapper userspace tools.
*
* It includes tree drawing code based on pstree: http://psmisc.sourceforge.net/
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "tool.h"
#include "dm-logging.h"
#include "defaults.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/inotify.h>
#include <dirent.h>
#include <ctype.h>
#ifdef __linux__
# include "kdev_t.h"
#else
# define MAJOR(x) major((x))
# define MINOR(x) minor((x))
# define MKDEV(x,y) makedev((x),(y))
#endif
/* limit to two updates/sec */
#define FILEMAPD_WAIT_USECS 500000
/* how long to wait for unlinked files */
#define FILEMAPD_NOFILE_WAIT_USECS 100000
#define FILEMAPD_NOFILE_WAIT_TRIES 10
struct filemap_monitor {
dm_filemapd_mode_t mode;
const char *program_id;
uint64_t group_id;
char *path;
int fd;
int inotify_fd;
int inotify_watch_fd;
/* monitoring heuristics */
int64_t blocks; /* allocated blocks, from stat.st_blocks */
int64_t nr_regions;
int deleted;
};
static int _foreground;
static int _verbose;
const char *const _usage = "dmfilemapd <fd> <group_id> <abs_path> <mode> "
"[<foreground>[<log_level>]]";
/*
* Daemon logging. By default, all messages are thrown away: messages
* are only written to the terminal if the daemon is run in the foreground.
*/
__attribute__((format(printf, 5, 0)))
static void _dmfilemapd_log_line(int level,
const char *file __attribute__((unused)),
int line __attribute__((unused)),
int dm_errno_or_class,
const char *f, va_list ap)
{
static int _abort_on_internal_errors = -1;
FILE *out = log_stderr(level) ? stderr : stdout;
level = log_level(level);
if (level <= _LOG_WARN || _verbose) {
if (level < _LOG_WARN)
out = stderr;
vfprintf(out, f, ap);
fputc('\n', out);
}
if (_abort_on_internal_errors < 0)
/* Set when env DM_ABORT_ON_INTERNAL_ERRORS is not "0" */
_abort_on_internal_errors =
strcmp(getenv("DM_ABORT_ON_INTERNAL_ERRORS") ? : "0", "0");
if (_abort_on_internal_errors &&
!strncmp(f, INTERNAL_ERROR, sizeof(INTERNAL_ERROR) - 1))
abort();
}
__attribute__((format(printf, 5, 6)))
static void _dmfilemapd_log_with_errno(int level,
const char *file, int line,
int dm_errno_or_class,
const char *f, ...)
{
va_list ap;
va_start(ap, f);
_dmfilemapd_log_line(level, file, line, dm_errno_or_class, f, ap);
va_end(ap);
}
/*
* Only used for reporting errors before daemonise().
*/
__attribute__((format(printf, 1, 2)))
static void _early_log(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
fputc('\n', stderr);
va_end(ap);
}
static void _setup_logging(void)
{
dm_log_init_verbose(_verbose - 1);
dm_log_with_errno_init(_dmfilemapd_log_with_errno);
}
#define PROC_FD_DELETED_STR "(deleted)"
/*
* Scan the /proc/<pid>/fd directory for pid and check for an fd
* symlink whose contents match path.
*/
static int _is_open_in_pid(pid_t pid, const char *path)
{
char deleted_path[PATH_MAX + sizeof(PROC_FD_DELETED_STR)];
struct dirent *pid_dp = NULL;
char path_buf[PATH_MAX];
char link_buf[PATH_MAX];
DIR *pid_d = NULL;
ssize_t len;
if (pid == getpid())
return 0;
if (dm_snprintf(path_buf, sizeof(path_buf),
DEFAULT_PROC_DIR "%d/fd", pid) < 0) {
log_error("Could not format pid path.");
goto bad;
}
/*
* Test for the kernel 'file (deleted)' form when scanning.
*/
if (dm_snprintf(deleted_path, sizeof(deleted_path), "%s %s",
path, PROC_FD_DELETED_STR) < 0) {
log_error("Could not format check path.");
}
pid_d = opendir(path_buf);
if (!pid_d) {
log_error("Could not open proc path: %s.", path_buf);
goto bad;
}
while ((pid_dp = readdir(pid_d)) != NULL) {
if (pid_dp->d_name[0] == '.')
continue;
if ((len = readlinkat(dirfd(pid_d), pid_dp->d_name, link_buf,
sizeof(link_buf))) < 0) {
log_error("readlink failed for " DEFAULT_PROC_DIR
"/%d/fd/.", pid);
goto bad;
}
link_buf[len] = '\0';
if (!strcmp(deleted_path, link_buf)) {
closedir(pid_d);
return 1;
}
}
bad:
closedir(pid_d);
return 0;
}
/*
* Attempt to determine whether a file is open by any process by
* scanning symbolic links in /proc/<pid>/fd.
*
* This is a heuristic since it cannot guarantee to detect brief
* access in all cases: a process that opens and then closes the
* file rapidly may never be seen by the scan.
*
* The method will also give false-positives if a process exists
* that has a deleted file open that had the same path, but a
* different inode number, to the file being monitored.
*
* For this reason the daemon only uses _is_open() for unlinked
* files when the mode is DM_FILEMAPD_FOLLOW_INODE, since these
* files can no longer be newly opened by processes.
*
* In this situation !is_open(path) provides an indication that
* the daemon should shut down: the file has been unlinked from
* the file system and we appear to hold the final reference.
*/
static int _is_open(const char *path)
{
struct dirent *proc_dp = NULL;
DIR *proc_d = NULL;
pid_t pid;
proc_d = opendir(DEFAULT_PROC_DIR);
if (!proc_d)
return 0;
while ((proc_dp = readdir(proc_d)) != NULL) {
if (!isdigit(proc_dp->d_name[0]))
continue;
pid = strtol(proc_dp->d_name, NULL, 10);
if (!pid)
continue;
if (_is_open_in_pid(pid, path)) {
closedir(proc_d);
return 1;
}
}
closedir(proc_d);
return 0;
}
static void _filemap_monitor_wait(uint64_t usecs)
{
if (_verbose) {
if (usecs == FILEMAPD_WAIT_USECS)
log_very_verbose("Waiting for check interval");
if (usecs == FILEMAPD_NOFILE_WAIT_USECS)
log_very_verbose("Waiting for unlinked path");
}
usleep((useconds_t) usecs);
}
static int _parse_args(int argc, char **argv, struct filemap_monitor *fm)
{
char *endptr;
/* we don't care what is in argv[0]. */
argc--;
argv++;
if (argc < 5) {
_early_log("Wrong number of arguments.");
_early_log("usage: %s", _usage);
return 0;
}
memset(fm, 0, sizeof(*fm));
/*
* We don't know the true nr_regions at daemon start time,
* and it is not worth a dm_stats_list()/group walk to count:
* we can assume that there is at least one region or the
* daemon would not have been started.
*
* A correct value will be obtained following the first update
* of the group's regions.
*/
fm->nr_regions = 1;
/* parse <fd> */
fm->fd = strtol(argv[0], &endptr, 10);
if (*endptr) {
_early_log("Could not parse file descriptor: %s", argv[0]);
return 0;
}
argc--;
argv++;
/* parse <group_id> */
fm->group_id = strtoull(argv[0], &endptr, 10);
if (*endptr) {
_early_log("Could not parse group identifier: %s", argv[0]);
return 0;
}
argc--;
argv++;
/* parse <path> */
if (!argv[0] || !strlen(argv[0])) {
_early_log("Path argument is required.");
return 0;
}
if (argv[0] != '/') {
_early_log("Path argument must specify an absolute path.");
return 0;
}
fm->path = dm_strdup(argv[0]);
if (!fm->path) {
_early_log("Could not allocate memory for path argument.");
return 0;
}
argc--;
argv++;
/* parse <mode> */
if (!argv[0] || !strlen(argv[0])) {
_early_log("Mode argument is required.");
return 0;
}
fm->mode = dm_filemapd_mode_from_string(argv[0]);
if (fm->mode == DM_FILEMAPD_FOLLOW_NONE)
return 0;
argc--;
argv++;
/* parse [<foreground>[<verbose>]] */
if (argc) {
_foreground = strtol(argv[0], &endptr, 10);
if (*endptr) {
_early_log("Could not parse debug argument: %s.",
argv[0]);
return 0;
}
argc--;
argv++;
if (argc) {
_verbose = strtol(argv[0], &endptr, 10);
if (*endptr) {
_early_log("Could not parse verbose "
"argument: %s", argv[0]);
return 0;
}
if (_verbose < 0 || _verbose > 3) {
_early_log("Verbose argument out of range: %d.",
_verbose);
return 0;
}
}
}
return 1;
}
static int _filemap_fd_check_changed(struct filemap_monitor *fm)
{
int64_t blocks, old_blocks;
struct stat buf;
if (fm->fd < 0) {
log_error("Filemap fd is not open.");
return -1;
}
if (fstat(fm->fd, &buf)) {
log_error("Failed to fstat filemap file descriptor.");
return -1;
}
blocks = buf.st_blocks;
/* first check? */
if (fm->blocks < 0)
old_blocks = buf.st_blocks;
else
old_blocks = fm->blocks;
fm->blocks = blocks;
return (fm->blocks != old_blocks);
}
static void _filemap_monitor_close_fd(struct filemap_monitor *fm)
{
if (close(fm->fd))
log_error("Error closing file descriptor.");
fm->fd = -1;
}
static void _filemap_monitor_end_notify(struct filemap_monitor *fm)
{
inotify_rm_watch(fm->inotify_fd, fm->inotify_watch_fd);
}
static int _filemap_monitor_set_notify(struct filemap_monitor *fm)
{
int inotify_fd, watch_fd;
/*
* Set IN_NONBLOCK since we do not want to block in event read()
* calls. Do not set IN_CLOEXEC as dmfilemapd is single-threaded
* and does not fork or exec.
*/
if ((inotify_fd = inotify_init1(IN_NONBLOCK)) < 0) {
_early_log("Failed to initialise inotify.");
return 0;
}
if ((watch_fd = inotify_add_watch(inotify_fd, fm->path,
IN_MODIFY | IN_DELETE_SELF)) < 0) {
_early_log("Failed to add inotify watch.");
return 0;
}
fm->inotify_fd = inotify_fd;
fm->inotify_watch_fd = watch_fd;
return 1;
}
static int _filemap_monitor_reopen_fd(struct filemap_monitor *fm)
{
int tries = FILEMAPD_NOFILE_WAIT_TRIES;
/*
* In DM_FILEMAPD_FOLLOW_PATH mode, inotify watches must be
* re-established whenever the file at the watched path is
* changed.
*
* FIXME: stat file and skip if inode is unchanged.
*/
if (fm->fd > 0)
log_error("Filemap file descriptor already open.");
while ((fm->fd < 0) && --tries)
if (((fm->fd = open(fm->path, O_RDONLY)) < 0) && tries)
_filemap_monitor_wait(FILEMAPD_NOFILE_WAIT_USECS);
if (!tries && (fm->fd < 0)) {
log_error("Could not re-open file descriptor.");
return 0;
}
return _filemap_monitor_set_notify(fm);
}
static int _filemap_monitor_get_events(struct filemap_monitor *fm)
{
/* alignment as per man(7) inotify */
char buf[sizeof(struct inotify_event) + NAME_MAX + 1]
__attribute__ ((aligned(__alignof__(struct inotify_event))));
struct inotify_event *event;
int check = 0;
ssize_t len;
char *ptr;
/*
* Close the file descriptor for the file being monitored here
* when mode=path: this will allow the inode to be de-allocated,
* and an IN_DELETE_SELF event generated in the case that the
* daemon is holding the last open reference to the file.
*/
if (fm->mode == DM_FILEMAPD_FOLLOW_PATH) {
_filemap_monitor_end_notify(fm);
_filemap_monitor_close_fd(fm);
}
len = read(fm->inotify_fd, (void *) &buf, sizeof(buf));
/* no events to read? */
if (len < 0 && (errno == EAGAIN))
goto out;
/* interrupted by signal? */
if (len < 0 && (errno == EINTR))
goto out;
if (len < 0)
return -1;
if (!len)
goto out;
for (ptr = buf; ptr < buf + len; ptr += sizeof(*event) + event->len) {
event = (struct inotify_event *) ptr;
if (event->mask & IN_DELETE_SELF)
fm->deleted = 1;
if (event->mask & IN_MODIFY)
check = 1;
/*
* Event IN_IGNORED is generated when a file has been deleted
* and IN_DELETE_SELF generated, and indicates that the file
* watch has been automatically removed.
*
* This can only happen for the DM_FILEMAPD_FOLLOW_PATH mode,
* since inotify IN_DELETE events are generated at the time
* the inode is destroyed: DM_FILEMAPD_FOLLOW_INODE will hold
* the file descriptor open, meaning that the event will not
* be generated until after the daemon closes the file.
*
* The event is ignored here since inotify monitoring will
* be reestablished (or the daemon will terminate) following
* deletion of a DM_FILEMAPD_FOLLOW_PATH monitored file.
*/
if (event->mask & IN_IGNORED)
log_very_verbose("Inotify watch removed: IN_IGNORED "
"in event->mask");
}
out:
/*
* Re-open file descriptor if required and log disposition.
*/
if (fm->mode == DM_FILEMAPD_FOLLOW_PATH)
if (!_filemap_monitor_reopen_fd(fm))
return -1;
log_very_verbose("exiting _filemap_monitor_get_events() with "
"deleted=%d, check=%d", fm->deleted, check);
return check;
}
static void _filemap_monitor_destroy(struct filemap_monitor *fm)
{
if (fm->fd > 0) {
_filemap_monitor_end_notify(fm);
_filemap_monitor_close_fd(fm);
}
dm_free((void *) fm->program_id);
}
static int _filemap_monitor_check_same_file(int fd1, int fd2)
{
struct stat buf1, buf2;
if ((fd1 < 0) || (fd2 < 0))
return 0;
if (fstat(fd1, &buf1)) {
log_error("Failed to fstat file descriptor %d", fd1);
return -1;
}
if (fstat(fd2, &buf2)) {
log_error("Failed to fstat file descriptor %d", fd2);
return -1;
}
return ((buf1.st_dev == buf2.st_dev) && (buf1.st_ino == buf2.st_ino));
}
static int _filemap_monitor_check_file_unlinked(struct filemap_monitor *fm)
{
char path_buf[PATH_MAX];
char link_buf[PATH_MAX];
int same, fd, len;
fm->deleted = 0;
if ((fd = open(fm->path, O_RDONLY)) < 0)
goto check_unlinked;
if ((same = _filemap_monitor_check_same_file(fm->fd, fd)) < 0)
return 0;
if (close(fd))
log_error("Error closing fd %d", fd);
if (same)
return 1;
check_unlinked:
/*
* The file has been unlinked from its original location: test
* whether it is still reachable in the filesystem, or if it is
* unlinked and anonymous.
*/
if (dm_snprintf(path_buf, sizeof(path_buf), DEFAULT_PROC_DIR
"/%d/fd/%d", getpid(), fm->fd) < 0) {
log_error("Could not format pid path.");
return 0;
}
if ((len = readlink(path_buf, link_buf, sizeof(link_buf))) < 0) {
log_error("readlink failed for " DEFAULT_PROC_DIR "/%d/fd/%d.",
getpid(), fm->fd);
return 0;
}
/*
* Try to re-open the file, from the path now reported in /proc/pid/fd.
*/
if ((fd = open(link_buf, O_RDONLY)) < 0)
fm->deleted = 1;
if ((same = _filemap_monitor_check_same_file(fm->fd, fd)) < 0)
return 0;
if ((fd > 0) && close(fd))
log_error("Error closing fd %d", fd);
/* Should not happen with normal /proc. */
if ((fd > 0) && !same) {
log_error("File descriptor mismatch: %d and %s (read from %s) "
"are not the same file!", fm->fd, link_buf, path_buf);
return 0;
}
return 1;
}
static int _daemonise(struct filemap_monitor *fm)
{
pid_t pid = 0, sid;
int fd;
if (!(sid = setsid())) {
_early_log("setsid failed.");
return 0;
}
if ((pid = fork()) < 0) {
_early_log("Failed to fork daemon process.");
return 0;
}
if (pid > 0) {
if (_verbose)
_early_log("Started dmfilemapd with pid=%d", pid);
exit(0);
}
if (chdir("/")) {
_early_log("Failed to change directory.");
return 0;
}
if (!_verbose) {
if (close(STDIN_FILENO))
_early_log("Error closing stdin");
if (close(STDOUT_FILENO))
_early_log("Error closing stdout");
if (close(STDERR_FILENO))
_early_log("Error closing stderr");
if ((open("/dev/null", O_RDONLY) < 0) ||
(open("/dev/null", O_WRONLY) < 0) ||
(open("/dev/null", O_WRONLY) < 0)) {
_early_log("Error opening stdio streams.");
return 0;
}
}
for (fd = sysconf(_SC_OPEN_MAX) - 1; fd > STDERR_FILENO; fd--) {
if (fd == fm->fd)
continue;
close(fd);
}
return 1;
}
static int _update_regions(struct dm_stats *dms, struct filemap_monitor *fm)
{
uint64_t *regions = NULL, *region, nr_regions = 0;
regions = dm_stats_update_regions_from_fd(dms, fm->fd, fm->group_id);
if (!regions) {
log_error("Failed to update filemap regions for group_id="
FMTu64 ".", fm->group_id);
return 0;
}
for (region = regions; *region != DM_STATS_REGIONS_ALL; region++)
nr_regions++;
if (regions[0] != fm->group_id) {
log_warn("group_id changed from " FMTu64 " to " FMTu64,
fm->group_id, regions[0]);
fm->group_id = regions[0];
}
fm->nr_regions = nr_regions;
return 1;
}
static int _dmfilemapd(struct filemap_monitor *fm)
{
int running = 1, check = 0, open = 0;
const char *program_id;
struct dm_stats *dms;
/*
* The correct program_id is retrieved from the group leader
* following the call to dm_stats_list().
*/
dms = dm_stats_create(NULL);
if (!dm_stats_bind_from_fd(dms, fm->fd)) {
log_error("Could not bind dm_stats handle to file descriptor "
"%d", fm->fd);
goto bad;
}
if (!_filemap_monitor_set_notify(fm))
goto bad;
if (!dm_stats_list(dms, DM_STATS_ALL_PROGRAMS)) {
log_error("Failed to list stats handle.");
goto bad;
}
/*
* Take the program_id for new regions (created by calls to
* dm_stats_update_regions_from_fd()) from the value used by
* the group leader.
*/
program_id = dm_stats_get_region_program_id(dms, fm->group_id);
if (program_id)
fm->program_id = dm_strdup(program_id);
else
fm->program_id = NULL;
dm_stats_set_program_id(dms, 1, program_id);
do {
if (!dm_stats_group_present(dms, fm->group_id)) {
log_info("Filemap group removed: exiting.");
running = 0;
continue;
}
if ((check = _filemap_monitor_get_events(fm)) < 0)
goto bad;
if (!check)
goto wait;
if ((check = _filemap_fd_check_changed(fm)) < 0)
goto bad;
if (!check)
goto wait;
if (!_update_regions(dms, fm))
goto bad;
wait:
_filemap_monitor_wait(FILEMAPD_WAIT_USECS);
running = !!fm->nr_regions;
/* mode=inode termination condions */
if (fm->mode == DM_FILEMAPD_FOLLOW_INODE) {
if (!_filemap_monitor_check_file_unlinked(fm))
goto bad;
if (fm->deleted && !(open = _is_open(fm->path))) {
log_info("File unlinked and closed: exiting.");
running = 0;
} else if (fm->deleted && open)
log_verbose("File unlinked and open: "
"continuing.");
}
if (!dm_stats_list(dms, NULL)) {
log_error("Failed to list stats handle.");
goto bad;
}
} while (running);
_filemap_monitor_destroy(fm);
dm_stats_destroy(dms);
return 0;
bad:
_filemap_monitor_destroy(fm);
dm_stats_destroy(dms);
log_error("Exiting");
return 1;
}
static const char * _mode_names[] = {
"inode",
"path"
};
/*
* dmfilemapd <fd> <group_id> <path> <mode> [<foreground>[<log_level>]]
*/
int main(int argc, char **argv)
{
struct filemap_monitor fm;
if (!_parse_args(argc, argv, &fm))
return 1;
_setup_logging();
log_info("Starting dmfilemapd with fd=%d, group_id=" FMTu64 " "
"mode=%s, path=%s", fm.fd, fm.group_id,
_mode_names[fm.mode], fm.path);
if (!_foreground && !_daemonise(&fm))
return 1;
return _dmfilemapd(&fm);
}

View File

@@ -38,7 +38,7 @@ class AutomatedProperties(dbus.service.Object):
props = {}
for i in self.interface():
props[i] = AutomatedProperties._get_all_prop(self, i)
props[i] = self.GetAll(i)
return self._ap_o_path, props
@@ -65,53 +65,32 @@ class AutomatedProperties(dbus.service.Object):
return self._ap_interface
@staticmethod
def _get_prop(obj, interface_name, property_name):
value = getattr(obj, property_name)
# Properties
# noinspection PyUnusedLocal
@dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE,
in_signature='ss', out_signature='v')
def Get(self, interface_name, property_name):
value = getattr(self, property_name)
# Note: If we get an exception in this handler we won't know about it,
# only the side effect of no returned value!
log_debug('Get (%s), type (%s), value(%s)' %
(property_name, str(type(value)), str(value)))
return value
# Properties
# noinspection PyUnusedLocal
@dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE,
in_signature='ss', out_signature='v',
async_callbacks=('cb', 'cbe'))
def Get(self, interface_name, property_name, cb, cbe):
# Note: If we get an exception in this handler we won't know about it,
# only the side effect of no returned value!
r = cfg.create_request_entry(
-1, AutomatedProperties._get_prop,
(self, interface_name, property_name),
cb, cbe, False)
cfg.worker_q.put(r)
@staticmethod
def _get_all_prop(obj, interface_name):
if interface_name in obj.interface(True):
in_signature='s', out_signature='a{sv}')
def GetAll(self, interface_name):
if interface_name in self.interface(True):
# Using introspection, lets build this dynamically
properties = get_properties(obj)
properties = get_properties(self)
if interface_name in properties:
return properties[interface_name][1]
return {}
raise dbus.exceptions.DBusException(
obj._ap_interface,
self._ap_interface,
'The object %s does not implement the %s interface'
% (self.__class__, interface_name))
@dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE,
in_signature='s', out_signature='a{sv}',
async_callbacks=('cb', 'cbe'))
def GetAll(self, interface_name, cb, cbe):
r = cfg.create_request_entry(
-1, AutomatedProperties._get_all_prop,
(self, interface_name),
cb, cbe, False)
cfg.worker_q.put(r)
@dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE,
in_signature='ssv')
def Set(self, interface_name, property_name, new_value):

View File

@@ -84,6 +84,3 @@ db = None
# lvm flight recorder
blackbox = None
# RequestEntry ctor
create_request_entry = None

View File

@@ -16,7 +16,7 @@ import traceback
import os
from lvmdbusd import cfg
from lvmdbusd.utils import pv_dest_ranges, log_debug, log_error, add_no_notify
from lvmdbusd.utils import pv_dest_ranges, log_debug, log_error
from lvmdbusd.lvm_shell_proxy import LVMShellProxy
try:
@@ -93,7 +93,6 @@ def call_lvm(command, debug=False):
# Prepend the full lvm executable so that we can run different versions
# in different locations on the same box
command.insert(0, cfg.LVM_CMD)
command = add_no_notify(command)
process = Popen(command, stdout=PIPE, stderr=PIPE, close_fds=True,
env=os.environ)

View File

@@ -29,7 +29,7 @@ except ImportError:
from lvmdbusd.cfg import LVM_CMD
from lvmdbusd.utils import log_debug, log_error, add_no_notify
from lvmdbusd.utils import log_debug, log_error
SHELL_PROMPT = "lvm> "
@@ -206,8 +206,6 @@ class LVMShellProxy(object):
self.lvm_shell.returncode,
"Underlying lvm shell process is not present!")
argv = add_no_notify(argv)
# create the command string
cmd = " ".join(_quote_arg(arg) for arg in argv)
cmd += "\n"

View File

@@ -30,7 +30,6 @@ import argparse
import os
import sys
from .cmdhandler import LvmFlightRecorder
from .request import RequestEntry
class Lvm(objectmanager.ObjectManager):
@@ -98,7 +97,6 @@ def main():
os.environ["LC_ALL"] = "C"
cfg.args = parser.parse_args()
cfg.create_request_entry = RequestEntry
# We create a flight recorder in cmdhandler too, but we replace it here
# as the user may be specifying a different size. The default one in
@@ -146,6 +144,7 @@ def main():
thread_list.append(updater.thread)
cfg.load = updater.load
cfg.event = updater.event
cfg.loop = GLib.MainLoop()

View File

@@ -6,7 +6,7 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from utils import log_debug
from .automatedproperties import AutomatedProperties
from . import utils
@@ -132,28 +132,11 @@ class Manager(AutomatedProperties):
r = RequestEntry(-1, Manager._refresh, (), cb, cbe, False)
cfg.worker_q.put(r)
@dbus.service.method(
dbus_interface=MANAGER_INTERFACE)
def FlightRecorderDump(self):
"""
Dump the flight recorder to syslog
"""
cfg.blackbox.dump()
@staticmethod
def _lookup_by_lvm_id(key):
p = cfg.om.get_object_path_by_uuid_lvm_id(key, key)
if not p:
p = '/'
log_debug('LookUpByLvmId: key = %s, result = %s' % (key, p))
return p
@dbus.service.method(
dbus_interface=MANAGER_INTERFACE,
in_signature='s',
out_signature='o',
async_callbacks=('cb', 'cbe'))
def LookUpByLvmId(self, key, cb, cbe):
out_signature='o')
def LookUpByLvmId(self, key):
"""
Given a lvm id in one of the forms:
@@ -167,8 +150,10 @@ class Manager(AutomatedProperties):
:param key: The lookup value
:return: Return the object path. If object not found you will get '/'
"""
r = RequestEntry(-1, Manager._lookup_by_lvm_id, (key,), cb, cbe, False)
cfg.worker_q.put(r)
p = cfg.om.get_object_path_by_uuid_lvm_id(key, key)
if p:
return p
return '/'
@staticmethod
def _use_lvm_shell(yes_no):
@@ -184,22 +169,16 @@ class Manager(AutomatedProperties):
:param yes_no:
:param cb: dbus python call back parameter, not client visible
:param cbe: dbus python error call back parameter, not client visible
:return: Boolean
:return: Nothing
"""
r = RequestEntry(-1, Manager._use_lvm_shell, (yes_no,), cb, cbe, False)
cfg.worker_q.put(r)
@staticmethod
def _external_event(command):
utils.log_debug("Processing _external_event= %s" % command,
'bg_black', 'fg_orange')
cfg.load()
@dbus.service.method(
dbus_interface=MANAGER_INTERFACE,
in_signature='s', out_signature='i')
def ExternalEvent(self, command):
utils.log_debug("ExternalEvent %s" % command)
# If a user didn't explicitly specify udev, we will turn it off now.
if not cfg.args.use_udev:
if udevwatch.remove():
@@ -207,10 +186,8 @@ class Manager(AutomatedProperties):
"udev monitoring")
# We are dependent on external events now to stay current!
cfg.ee = True
r = RequestEntry(
-1, Manager._external_event, (command,), None, None, False)
cfg.worker_q.put(r)
utils.log_debug("ExternalEvent %s" % command)
cfg.event()
return dbus.Int32(0)
@staticmethod

View File

@@ -32,12 +32,14 @@ class ObjectManager(AutomatedProperties):
self._id_to_object_path = {}
self.rlock = threading.RLock()
@staticmethod
def _get_managed_objects(obj):
with obj.rlock:
@dbus.service.method(
dbus_interface="org.freedesktop.DBus.ObjectManager",
out_signature='a{oa{sa{sv}}}')
def GetManagedObjects(self):
with self.rlock:
rc = {}
try:
for k, v in list(obj._objects.items()):
for k, v in list(self._objects.items()):
path, props = v[0].emit_data()
rc[path] = props
except Exception:
@@ -45,14 +47,6 @@ class ObjectManager(AutomatedProperties):
sys.exit(1)
return rc
@dbus.service.method(
dbus_interface="org.freedesktop.DBus.ObjectManager",
out_signature='a{oa{sa{sv}}}', async_callbacks=('cb', 'cbe'))
def GetManagedObjects(self, cb, cbe):
r = cfg.create_request_entry(-1, ObjectManager._get_managed_objects,
(self, ), cb, cbe, False)
cfg.worker_q.put(r)
def locked(self):
"""
If some external code need to run across a number of different

View File

@@ -10,18 +10,11 @@
import pyudev
import threading
from . import cfg
from .request import RequestEntry
from . import utils
observer = None
observer_lock = threading.RLock()
def _udev_event():
utils.log_debug("Processing udev event")
cfg.load()
# noinspection PyUnusedLocal
def filter_event(action, device):
# Filter for events of interest and add a request object to be processed
@@ -44,10 +37,7 @@ def filter_event(action, device):
refresh = True
if refresh:
# Place this on the queue so any other operations will sequence behind it
r = RequestEntry(
-1, _udev_event, (), None, None, False)
cfg.worker_q.put(r)
cfg.event()
def add():

View File

@@ -499,30 +499,6 @@ def validate_tag(interface, tag):
% (tag, _ALLOWABLE_TAG_CH))
def add_no_notify(cmdline):
"""
Given a command line to execute we will see if `--config` is present, if it
is we will add the global/notify_dbus=0 to it, otherwise we will append it
to the end of the list.
:param: cmdline: The command line to inspect
:type: cmdline: list
:return: cmdline with notify_dbus config option present
:rtype: list
"""
if 'help' in cmdline:
return cmdline
if '--config' in cmdline:
for i, arg in enumerate(cmdline):
if arg == '--config':
cmdline[i] += "global/notify_dbus=0"
break
else:
cmdline.extend(['--config', 'global/notify_dbus=0'])
return cmdline
# The methods below which start with mt_* are used to execute the desired code
# on the the main thread of execution to alleviate any issues the dbus-python
# library with regards to multi-threaded access. Essentially, we are trying to

View File

@@ -127,9 +127,6 @@
/* Path to dmeventd pidfile. */
#undef DMEVENTD_PIDFILE
/* Define to 1 to enable the device-mapper filemap daemon. */
#undef DMFILEMAPD
/* Define to enable compat protocol */
#undef DM_COMPAT

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2017 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004-2016 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -272,18 +272,10 @@ int lv_raid_percent(const struct logical_volume *lv, dm_percent_t *percent)
{
return 0;
}
int lv_raid_data_offset(const struct logical_volume *lv, uint64_t *data_offset)
{
return 0;
}
int lv_raid_dev_health(const struct logical_volume *lv, char **dev_health)
{
return 0;
}
int lv_raid_dev_count(const struct logical_volume *lv, uint32_t *dev_cnt)
{
return 0;
}
int lv_raid_mismatch_count(const struct logical_volume *lv, uint64_t *cnt)
{
return 0;
@@ -992,30 +984,6 @@ int lv_raid_percent(const struct logical_volume *lv, dm_percent_t *percent)
return lv_mirror_percent(lv->vg->cmd, lv, 0, percent, NULL);
}
int lv_raid_data_offset(const struct logical_volume *lv, uint64_t *data_offset)
{
int r;
struct dev_manager *dm;
struct dm_status_raid *status;
if (!lv_info(lv->vg->cmd, lv, 0, NULL, 0, 0))
return 0;
log_debug_activation("Checking raid data offset and dev sectors for LV %s/%s",
lv->vg->name, lv->name);
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
return_0;
if (!(r = dev_manager_raid_status(dm, lv, &status)))
stack;
*data_offset = status->data_offset;
dev_manager_destroy(dm);
return r;
}
int lv_raid_dev_health(const struct logical_volume *lv, char **dev_health)
{
int r;
@@ -1045,32 +1013,6 @@ int lv_raid_dev_health(const struct logical_volume *lv, char **dev_health)
return r;
}
int lv_raid_dev_count(const struct logical_volume *lv, uint32_t *dev_cnt)
{
struct dev_manager *dm;
struct dm_status_raid *status;
*dev_cnt = 0;
if (!lv_info(lv->vg->cmd, lv, 0, NULL, 0, 0))
return 0;
log_debug_activation("Checking raid device count for LV %s/%s",
lv->vg->name, lv->name);
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
return_0;
if (!dev_manager_raid_status(dm, lv, &status)) {
dev_manager_destroy(dm);
return_0;
}
*dev_cnt = status->dev_count;
dev_manager_destroy(dm);
return 1;
}
int lv_raid_mismatch_count(const struct logical_volume *lv, uint64_t *cnt)
{
struct dev_manager *dm;
@@ -2006,13 +1948,16 @@ int monitor_dev_for_events(struct cmd_context *cmd, const struct logical_volume
/* Check [un]monitor results */
/* Try a couple times if pending, but not forever... */
for (i = 0;; i++) {
for (i = 0; i < 40; i++) {
pending = 0;
monitored = seg->segtype->ops->target_monitored(seg, &pending);
if (!pending || i >= 40)
if (pending ||
(!monitored && monitor) ||
(monitored && !monitor))
log_very_verbose("%s %smonitoring still pending: waiting...",
display_lvname(lv), monitor ? "" : "un");
else
break;
log_very_verbose("%s %smonitoring still pending: waiting...",
display_lvname(lv), monitor ? "" : "un");
usleep(10000 * i);
}

View File

@@ -168,8 +168,6 @@ int lv_snapshot_percent(const struct logical_volume *lv, dm_percent_t *percent);
int lv_mirror_percent(struct cmd_context *cmd, const struct logical_volume *lv,
int wait, dm_percent_t *percent, uint32_t *event_nr);
int lv_raid_percent(const struct logical_volume *lv, dm_percent_t *percent);
int lv_raid_dev_count(const struct logical_volume *lv, uint32_t *dev_cnt);
int lv_raid_data_offset(const struct logical_volume *lv, uint64_t *data_offset);
int lv_raid_dev_health(const struct logical_volume *lv, char **dev_health);
int lv_raid_mismatch_count(const struct logical_volume *lv, uint64_t *cnt);
int lv_raid_sync_action(const struct logical_volume *lv, char **sync_action);

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2017 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004-2016 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -214,14 +214,6 @@ typedef enum {
STATUS, /* DM_DEVICE_STATUS ioctl */
} info_type_t;
/* Return length of segment depending on type and reshape_len */
static uint32_t _seg_len(const struct lv_segment *seg)
{
uint32_t reshape_len = seg_is_raid(seg) ? ((seg->area_count - seg->segtype->parity_devs) * seg->reshape_len) : 0;
return seg->len - reshape_len;
}
static int _info_run(const char *dlid, struct dm_info *dminfo,
uint32_t *read_ahead,
struct lv_seg_status *seg_status,
@@ -258,7 +250,7 @@ static int _info_run(const char *dlid, struct dm_info *dminfo,
if (seg_status && dminfo->exists) {
start = length = seg_status->seg->lv->vg->extent_size;
start *= seg_status->seg->le;
length *= _seg_len(seg_status->seg);
length *= seg_status->seg->len;
do {
target = dm_get_next_target(dmt, target, &target_start,
@@ -1316,13 +1308,14 @@ int dev_manager_raid_message(struct dev_manager *dm,
return 0;
}
/* These are the supported RAID messages for dm-raid v1.9.0 */
/* These are the supported RAID messages for dm-raid v1.5.0 */
if (strcmp(msg, "idle") &&
strcmp(msg, "frozen") &&
strcmp(msg, "resync") &&
strcmp(msg, "recover") &&
strcmp(msg, "check") &&
strcmp(msg, "repair")) {
strcmp(msg, "repair") &&
strcmp(msg, "reshape")) {
log_error(INTERNAL_ERROR "Unknown RAID message: %s.", msg);
return 0;
}
@@ -2221,7 +2214,7 @@ static char *_add_error_or_zero_device(struct dev_manager *dm, struct dm_tree *d
struct lv_segment *seg_i;
struct dm_info info;
int segno = -1, i = 0;
uint64_t size = (uint64_t) _seg_len(seg) * seg->lv->vg->extent_size;
uint64_t size = (uint64_t) seg->len * seg->lv->vg->extent_size;
dm_list_iterate_items(seg_i, &seg->lv->segments) {
if (seg == seg_i) {
@@ -2507,7 +2500,7 @@ static int _add_target_to_dtree(struct dev_manager *dm,
return seg->segtype->ops->add_target_line(dm, dm->mem, dm->cmd,
&dm->target_state, seg,
laopts, dnode,
extent_size * _seg_len(seg),
extent_size * seg->len,
&dm->pvmove_mirror_count);
}
@@ -2700,7 +2693,7 @@ static int _add_segment_to_dtree(struct dev_manager *dm,
/* Replace target and all its used devs with error mapping */
log_debug_activation("Using error for pending delete %s.",
display_lvname(seg->lv));
if (!dm_tree_node_add_error_target(dnode, (uint64_t)seg->lv->vg->extent_size * _seg_len(seg)))
if (!dm_tree_node_add_error_target(dnode, (uint64_t)seg->lv->vg->extent_size * seg->len))
return_0;
} else if (!_add_target_to_dtree(dm, dnode, seg, laopts))
return_0;
@@ -3172,6 +3165,7 @@ static int _tree_action(struct dev_manager *dm, const struct logical_volume *lv,
log_error(INTERNAL_ERROR "_tree_action: Action %u not supported.", action);
goto out;
}
r = 1;
out:

2
lib/cache/lvmetad.c vendored
View File

@@ -1304,7 +1304,7 @@ int lvmetad_vg_remove_pending(struct volume_group *vg)
reply = _lvmetad_send(vg->cmd, "set_vg_info",
"name = %s", vg->name,
"uuid = %s", uuid,
"version = %"PRId64, (int64_t)0,
"version = %d", 0,
NULL);
if (!_lvmetad_handle_reply(reply, "set_vg_info", vg->name, NULL)) {

View File

@@ -36,31 +36,6 @@ static unsigned _feature_mask;
log_error(t " segment %s of logical volume %s.", ## p, \
dm_config_parent_name(sn), seg->lv->name), 0;
static int _cache_out_line(const char *line, void *_f)
{
log_print(" Setting\t\t%s", line);
return 1;
}
static void _cache_display(const struct lv_segment *seg)
{
const struct dm_config_node *n;
const struct lv_segment *pool_seg =
seg_is_cache_pool(seg) ? seg : first_seg(seg->pool_lv);
log_print(" Chunk size\t\t%s",
display_size(seg->lv->vg->cmd, pool_seg->chunk_size));
log_print(" Metadata format\t%u", pool_seg->cache_metadata_format);
log_print(" Mode\t\t%s", get_cache_mode_name(pool_seg));
log_print(" Policy\t\t%s", pool_seg->policy_name);
if ((n = pool_seg->policy_settings->child))
dm_config_write_node(n, _cache_out_line, NULL);
log_print(" ");
}
/*
* When older metadata are loaded without newer settings,
* set then to default settings (the one that could have been
@@ -77,13 +52,7 @@ static void _fix_missing_defaults(struct lv_segment *cpool_seg)
cpool_seg->policy_name);
}
if (cpool_seg->cache_metadata_format == CACHE_METADATA_FORMAT_UNSELECTED) {
cpool_seg->cache_metadata_format = CACHE_METADATA_FORMAT_1;
log_verbose("Cache pool %s uses implicit metadata format %u.",
display_lvname(cpool_seg->lv), cpool_seg->cache_metadata_format);
}
if (cpool_seg->cache_mode == CACHE_MODE_UNSELECTED) {
if (cpool_seg->cache_mode == CACHE_MODE_UNDEFINED) {
cpool_seg->cache_mode = CACHE_MODE_WHEN_MISSING;
log_verbose("Cache pool %s is missing cache mode, using %s.",
display_lvname(cpool_seg->lv),
@@ -138,16 +107,6 @@ static int _cache_pool_text_import(struct lv_segment *seg,
return SEG_LOG_ERROR("Failed to duplicate policy in");
}
if (dm_config_has_node(sn, "metadata_format")) {
if (!dm_config_get_uint32(sn, "metadata_format", &seg->cache_metadata_format) ||
((seg->cache_metadata_format != CACHE_METADATA_FORMAT_1) &&
(seg->cache_metadata_format != CACHE_METADATA_FORMAT_2)))
return SEG_LOG_ERROR("Unknown cache metadata format %u number in",
seg->cache_metadata_format);
if (seg->cache_metadata_format == CACHE_METADATA_FORMAT_2)
seg->lv->status |= LV_METADATA_FORMAT;
}
/*
* Read in policy args:
* policy_settings {
@@ -205,31 +164,12 @@ static int _cache_pool_text_export(const struct lv_segment *seg,
outf(f, "metadata = \"%s\"", seg->metadata_lv->name);
outf(f, "chunk_size = %" PRIu32, seg->chunk_size);
switch (seg->cache_metadata_format) {
case CACHE_METADATA_FORMAT_UNSELECTED:
/* Unselected format is not printed */
break;
case CACHE_METADATA_FORMAT_1:
/* If format 1 was already specified with cache pool, store it,
* otherwise format gets stored when LV is cached.
* NB: format 1 could be lost anytime, it's a default format.
* Older lvm2 tool can easily drop it.
*/
case CACHE_METADATA_FORMAT_2: /* more in future ? */
outf(f, "metadata_format = " FMTu32, seg->cache_metadata_format);
break;
default:
log_error(INTERNAL_ERROR "LV %s is using unknown cache metadada format %u.",
display_lvname(seg->lv), seg->cache_metadata_format);
return 0;
}
/*
* Cache pool used by a cache LV holds data. Not ideal,
* but not worth to break backward compatibility, by shifting
* content to cache segment
*/
if (seg->cache_mode != CACHE_MODE_UNSELECTED) {
if (seg->cache_mode != CACHE_MODE_UNDEFINED) {
if (!(cache_mode = get_cache_mode_name(seg)))
return_0;
outf(f, "cache_mode = \"%s\"", cache_mode);
@@ -273,7 +213,6 @@ static int _target_present(struct cmd_context *cmd,
const char *aliasing;
} _features[] = {
/* Assumption: cache >=1.9 always aliases MQ policy */
{ 1, 10, CACHE_FEATURE_METADATA2, 0, "metadata2" },
{ 1, 9, CACHE_FEATURE_POLICY_SMQ, CACHE_FEATURE_POLICY_MQ, "policy_smq", "cache-smq",
" and aliases cache-mq" },
{ 1, 8, CACHE_FEATURE_POLICY_SMQ, 0, "policy_smq", "cache-smq" },
@@ -311,16 +250,6 @@ static int _target_present(struct cmd_context *cmd,
for (i = 0; i < DM_ARRAY_SIZE(_features); ++i) {
if (_attrs & _features[i].cache_feature)
continue; /* already present */
if (!_features[i].module[0]) {
if ((maj > _features[i].maj) ||
(maj == _features[i].maj && min >= _features[i].min)) {
log_debug_activation("Cache supports %s.",
_features[i].feature);
_attrs |= _features[i].cache_feature;
}
continue;
}
if (((maj > _features[i].maj) ||
(maj == _features[i].maj && min >= _features[i].min)) &&
module_present(cmd, _features[i].module)) {
@@ -381,7 +310,6 @@ static int _modules_needed(struct dm_pool *mem,
#endif /* DEVMAPPER_SUPPORT */
static struct segtype_handler _cache_pool_ops = {
.display = _cache_display,
.text_import = _cache_pool_text_import,
.text_import_area_count = _cache_pool_text_import_area_count,
.text_export = _cache_pool_text_export,
@@ -471,7 +399,6 @@ static int _cache_add_target_line(struct dev_manager *dm,
struct lv_segment *cache_pool_seg;
char *metadata_uuid, *data_uuid, *origin_uuid;
uint64_t feature_flags = 0;
unsigned attr;
if (!seg->pool_lv || !seg_is_cache(seg)) {
log_error(INTERNAL_ERROR "Passed segment is not cache.");
@@ -499,26 +426,6 @@ static int _cache_add_target_line(struct dev_manager *dm,
break;
}
switch (cache_pool_seg->cache_metadata_format) {
case CACHE_METADATA_FORMAT_1: break;
case CACHE_METADATA_FORMAT_2:
if (!_target_present(cmd, NULL, &attr))
return_0;
if (!(attr & CACHE_FEATURE_METADATA2)) {
log_error("LV %s has metadata format %u unsuported by kernel.",
display_lvname(seg->lv), cache_pool_seg->cache_metadata_format);
return 0;
}
feature_flags |= DM_CACHE_FEATURE_METADATA2;
log_debug_activation("Using metadata2 format for %s.", display_lvname(seg->lv));
break;
default:
log_error(INTERNAL_ERROR "LV %s has unknown metadata format %u.",
display_lvname(seg->lv), cache_pool_seg->cache_metadata_format);
return 0;
}
if (!(metadata_uuid = build_dm_uuid(mem, cache_pool_seg->metadata_lv, NULL)))
return_0;
@@ -545,7 +452,6 @@ static int _cache_add_target_line(struct dev_manager *dm,
#endif /* DEVMAPPER_SUPPORT */
static struct segtype_handler _cache_ops = {
.display = _cache_display,
.text_import = _cache_text_import,
.text_import_area_count = _cache_text_import_area_count,
.text_export = _cache_text_export,

View File

@@ -2442,13 +2442,21 @@ const char *get_default_activation_mirror_image_fault_policy_CFG(struct cmd_cont
int get_default_allocation_thin_pool_chunk_size_CFG(struct cmd_context *cmd, struct profile *profile)
{
const char *str;
uint32_t chunk_size;
int chunk_size_calc_method;
if (!get_default_allocation_thin_pool_chunk_size(cmd, profile, &chunk_size,
&chunk_size_calc_method)) {
stack; /* Ignore this error, never happens... */
if (!(str = find_config_tree_str(cmd, allocation_thin_pool_chunk_size_policy_CFG, profile))) {
log_error(INTERNAL_ERROR "Cannot find configuration.");
return 0;
}
if (!strcasecmp(str, "generic"))
chunk_size = DEFAULT_THIN_POOL_CHUNK_SIZE * 2;
else if (!strcasecmp(str, "performance"))
chunk_size = DEFAULT_THIN_POOL_CHUNK_SIZE_PERFORMANCE * 2;
else {
log_error("Thin pool chunk size calculation policy \"%s\" is unrecognised.", str);
return 0;
}
return (int) chunk_size;

View File

@@ -473,23 +473,14 @@ cfg(allocation_raid_stripe_all_devices_CFG, "raid_stripe_all_devices", allocatio
"when the command does not specify the number of stripes to use.\n"
"This was the default behaviour until release 2.02.162.\n")
cfg(allocation_cache_pool_metadata_require_separate_pvs_CFG, "cache_pool_metadata_require_separate_pvs", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA, CFG_TYPE_BOOL, DEFAULT_CACHE_POOL_METADATA_REQUIRE_SEPARATE_PVS, vsn(2, 2, 106), NULL, 0, NULL,
cfg(allocation_cache_pool_metadata_require_separate_pvs_CFG, "cache_pool_metadata_require_separate_pvs", allocation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_CACHE_POOL_METADATA_REQUIRE_SEPARATE_PVS, vsn(2, 2, 106), NULL, 0, NULL,
"Cache pool metadata and data will always use different PVs.\n")
cfg(allocation_cache_pool_cachemode_CFG, "cache_pool_cachemode", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_CACHE_MODE, vsn(2, 2, 113), NULL, vsn(2, 2, 128),
cfg(allocation_cache_pool_cachemode_CFG, "cache_pool_cachemode", allocation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_CACHE_MODE, vsn(2, 2, 113), NULL, vsn(2, 2, 128),
"This has been replaced by the allocation/cache_mode setting.\n",
"Cache mode.\n")
cfg(allocation_cache_metadata_format_CFG, "cache_metadata_format", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_CACHE_METADATA_FORMAT, vsn(2, 2, 169), NULL, 0, NULL,
"Sets default metadata format for new cache.\n"
"#\n"
"Accepted values:\n"
" 0 Automatically detected best available format\n"
" 1 Original format\n"
" 2 Improved 2nd. generation format\n"
"#\n")
cfg(allocation_cache_mode_CFG, "cache_mode", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_CACHE_MODE, vsn(2, 2, 128), NULL, 0, NULL,
cfg(allocation_cache_mode_CFG, "cache_mode", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_CACHE_MODE, vsn(2, 2, 128), NULL, 0, NULL,
"The default cache mode used for new cache.\n"
"#\n"
"Accepted values:\n"
@@ -501,20 +492,20 @@ cfg(allocation_cache_mode_CFG, "cache_mode", allocation_CFG_SECTION, CFG_PROFILA
"#\n"
"This setting replaces allocation/cache_pool_cachemode.\n")
cfg(allocation_cache_policy_CFG, "cache_policy", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, 0, vsn(2, 2, 128), NULL, 0, NULL,
cfg(allocation_cache_policy_CFG, "cache_policy", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, 0, vsn(2, 2, 128), NULL, 0, NULL,
"The default cache policy used for new cache volume.\n"
"Since kernel 4.2 the default policy is smq (Stochastic multiqueue),\n"
"Since kernel 4.2 the default policy is smq (Stochastic multique),\n"
"otherwise the older mq (Multiqueue) policy is selected.\n")
cfg_section(allocation_cache_settings_CFG_SECTION, "cache_settings", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, vsn(2, 2, 128), 0, NULL,
cfg_section(allocation_cache_settings_CFG_SECTION, "cache_settings", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_DEFAULT_COMMENTED, vsn(2, 2, 128), 0, NULL,
"Settings for the cache policy.\n"
"See documentation for individual cache policies for more info.\n")
cfg_section(policy_settings_CFG_SUBSECTION, "policy_settings", allocation_cache_settings_CFG_SECTION, CFG_NAME_VARIABLE | CFG_SECTION_NO_CHECK | CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, vsn(2, 2, 128), 0, NULL,
cfg_section(policy_settings_CFG_SUBSECTION, "policy_settings", allocation_cache_settings_CFG_SECTION, CFG_NAME_VARIABLE | CFG_SECTION_NO_CHECK | CFG_PROFILABLE | CFG_DEFAULT_COMMENTED, vsn(2, 2, 128), 0, NULL,
"Replace this subsection name with a policy name.\n"
"Multiple subsections for different policies can be created.\n")
cfg_runtime(allocation_cache_pool_chunk_size_CFG, "cache_pool_chunk_size", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_UNDEFINED, CFG_TYPE_INT, vsn(2, 2, 106), 0, NULL,
cfg_runtime(allocation_cache_pool_chunk_size_CFG, "cache_pool_chunk_size", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_DEFAULT_UNDEFINED, CFG_TYPE_INT, vsn(2, 2, 106), 0, NULL,
"The minimal chunk size in KiB for cache pool volumes.\n"
"Using a chunk_size that is too large can result in wasteful use of\n"
"the cache, where small reads and writes can cause large sections of\n"
@@ -525,7 +516,7 @@ cfg_runtime(allocation_cache_pool_chunk_size_CFG, "cache_pool_chunk_size", alloc
"on the smaller end of the spectrum. Supported values range from\n"
"32KiB to 1GiB in multiples of 32.\n")
cfg(allocation_cache_pool_max_chunks_CFG, "cache_pool_max_chunks", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_UNDEFINED, CFG_TYPE_INT, 0, vsn(2, 2, 165), NULL, 0, NULL,
cfg(allocation_cache_pool_max_chunks_CFG, "cache_pool_max_chunks", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_DEFAULT_UNDEFINED, CFG_TYPE_INT, 0, vsn(2, 2, 165), NULL, 0, NULL,
"The maximum number of chunks in a cache pool.\n"
"For cache target v1.9 the recommended maximumm is 1000000 chunks.\n"
"Using cache pool with more chunks may degrade cache performance.\n")
@@ -1001,7 +992,7 @@ cfg_array(global_thin_disabled_features_CFG, "thin_disabled_features", global_CF
cfg_array(global_cache_disabled_features_CFG, "cache_disabled_features", global_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(2, 2, 128), NULL, 0, NULL,
"Features to not use in the cache driver.\n"
"This can be helpful for testing, or to avoid using a feature that is\n"
"causing problems. Features include: policy_mq, policy_smq, metadata2.\n"
"causing problems. Features include: policy_mq, policy_smq.\n"
"#\n"
"Example\n"
"cache_disabled_features = [ \"policy_smq\" ]\n"

View File

@@ -71,7 +71,7 @@
* FIXME: Increase these to 64 and further to the MD maximum
* once the SubLVs split and name shift got enhanced
*/
#define DEFAULT_RAID1_MAX_IMAGES 64
#define DEFAULT_RAID1_MAX_IMAGES 10
#define DEFAULT_RAID_MAX_IMAGES 64
#define DEFAULT_ALLOCATION_STRIPE_ALL_DEVICES 0 /* Don't stripe across all devices if not -i/--stripes given */
@@ -132,7 +132,6 @@
#define DEFAULT_CACHE_POOL_MIN_METADATA_SIZE 2048 /* KB */
#define DEFAULT_CACHE_POOL_MAX_METADATA_SIZE (16 * 1024 * 1024) /* KB */
#define DEFAULT_CACHE_POLICY "mq"
#define DEFAULT_CACHE_METADATA_FORMAT CACHE_METADATA_FORMAT_UNSELECTED /* Autodetect */
#define DEFAULT_CACHE_MODE "writethrough"
#define DEFAULT_UMASK 0077

View File

@@ -386,7 +386,6 @@ int lvdisplay_full(struct cmd_context *cmd,
dm_percent_t thin_data_percent, thin_metadata_percent;
int thin_active = 0;
dm_percent_t thin_percent;
struct lv_status_cache *cache_status = NULL;
if (lv_is_historical(lv))
return _lvdisplay_historical_full(cmd, lv);
@@ -492,19 +491,6 @@ int lvdisplay_full(struct cmd_context *cmd,
seg = first_seg(lv);
log_print("LV Pool metadata %s", seg->metadata_lv->name);
log_print("LV Pool data %s", seg_lv(seg, 0)->name);
} else if (lv_is_cache_origin(lv)) {
log_print("LV origin of Cache LV %s",
get_only_segment_using_this_lv(lv)->lv->name);
} else if (lv_is_cache(lv)) {
seg = first_seg(lv);
if (inkernel && !lv_cache_status(lv, &cache_status))
return_0;
log_print("LV Cache pool name %s", seg->pool_lv->name);
log_print("LV Cache origin name %s", seg_lv(seg, 0)->name);
} else if (lv_is_cache_pool(lv)) {
seg = first_seg(lv);
log_print("LV Pool metadata %s", seg->metadata_lv->name);
log_print("LV Pool data %s", seg_lv(seg, 0)->name);
}
if (inkernel && info.suspended)
@@ -524,27 +510,6 @@ int lvdisplay_full(struct cmd_context *cmd,
display_size(cmd,
snap_seg ? snap_seg->origin->size : lv->size));
if (cache_status) {
log_print("Cache used blocks %.2f%%",
dm_percent_to_float(cache_status->data_usage));
log_print("Cache metadata blocks %.2f%%",
dm_percent_to_float(cache_status->metadata_usage));
log_print("Cache dirty blocks %.2f%%",
dm_percent_to_float(cache_status->dirty_usage));
log_print("Cache read hits/misses " FMTu64 " / " FMTu64,
cache_status->cache->read_hits,
cache_status->cache->read_misses);
log_print("Cache wrt hits/misses " FMTu64 " / " FMTu64,
cache_status->cache->write_hits,
cache_status->cache->write_misses);
log_print("Cache demotions " FMTu64,
cache_status->cache->demotions);
log_print("Cache promotions " FMTu64,
cache_status->cache->promotions);
dm_pool_destroy(cache_status->mem);
}
if (thin_data_active)
log_print("Allocated pool data %.2f%%",
dm_percent_to_float(thin_data_percent));

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2017 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -225,8 +225,8 @@ static int _read_linear(struct cmd_context *cmd, struct lv_map *lvm)
while (le < lvm->lv->le_count) {
len = _area_length(lvm, le);
if (!(seg = alloc_lv_segment(segtype, lvm->lv, le, len, 0, 0, 0,
NULL, 1, len, 0, 0, 0, 0, NULL))) {
if (!(seg = alloc_lv_segment(segtype, lvm->lv, le, len, 0, 0,
NULL, 1, len, 0, 0, 0, NULL))) {
log_error("Failed to allocate linear segment.");
return 0;
}
@@ -297,10 +297,10 @@ static int _read_stripes(struct cmd_context *cmd, struct lv_map *lvm)
if (!(seg = alloc_lv_segment(segtype, lvm->lv,
lvm->stripes * first_area_le,
lvm->stripes * area_len, 0,
lvm->stripes * area_len,
0, lvm->stripe_size, NULL,
lvm->stripes,
area_len, 0, 0, 0, 0, NULL))) {
area_len, 0, 0, 0, NULL))) {
log_error("Failed to allocate striped segment.");
return 0;
}

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2017 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -192,9 +192,9 @@ static int _add_stripe_seg(struct dm_pool *mem,
return_0;
if (!(seg = alloc_lv_segment(segtype, lv, *le_cur,
area_len * usp->num_devs, 0, 0,
area_len * usp->num_devs, 0,
usp->striping, NULL, usp->num_devs,
area_len, 0, 0, 0, 0, NULL))) {
area_len, 0, 0, 0, NULL))) {
log_error("Unable to allocate striped lv_segment structure");
return 0;
}
@@ -232,8 +232,8 @@ static int _add_linear_seg(struct dm_pool *mem,
area_len = (usp->devs[j].blocks) / POOL_PE_SIZE;
if (!(seg = alloc_lv_segment(segtype, lv, *le_cur,
area_len, 0, 0, usp->striping,
NULL, 1, area_len, 0,
area_len, 0, usp->striping,
NULL, 1, area_len,
POOL_PE_SIZE, 0, 0, NULL))) {
log_error("Unable to allocate linear lv_segment "
"structure");

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2017 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -583,10 +583,8 @@ static int _print_segment(struct formatter *f, struct volume_group *vg,
outf(f, "start_extent = %u", seg->le);
outsize(f, (uint64_t) seg->len * vg->extent_size,
"extent_count = %u", seg->len);
outnl(f);
if (seg->reshape_len)
outsize(f, (uint64_t) seg->reshape_len * vg->extent_size,
"reshape_count = %u", seg->reshape_len);
outf(f, "type = \"%s\"", seg->segtype->name);
if (!_out_list(f, &seg->tags, "tags"))

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2017 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004-2013 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -61,13 +61,9 @@ static const struct flag _lv_flags[] = {
{LOCKED, "LOCKED", STATUS_FLAG},
{LV_NOTSYNCED, "NOTSYNCED", STATUS_FLAG},
{LV_REBUILD, "REBUILD", STATUS_FLAG},
{LV_RESHAPE_DELTA_DISKS_PLUS, "RESHAPE_DELTA_DISKS_PLUS", STATUS_FLAG},
{LV_RESHAPE_DELTA_DISKS_MINUS, "RESHAPE_DELTA_DISKS_MINUS", STATUS_FLAG},
{LV_REMOVE_AFTER_RESHAPE, "REMOVE_AFTER_RESHAPE", STATUS_FLAG},
{LV_WRITEMOSTLY, "WRITEMOSTLY", STATUS_FLAG},
{LV_ACTIVATION_SKIP, "ACTIVATION_SKIP", COMPATIBLE_FLAG},
{LV_ERROR_WHEN_FULL, "ERROR_WHEN_FULL", COMPATIBLE_FLAG},
{LV_METADATA_FORMAT, "METADATA_FORMAT", STATUS_FLAG},
{LV_NOSCAN, NULL, 0},
{LV_TEMPORARY, NULL, 0},
{POOL_METADATA_SPARE, NULL, 0},

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2017 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -354,7 +354,7 @@ static int _read_segment(struct logical_volume *lv, const struct dm_config_node
struct lv_segment *seg;
const struct dm_config_node *sn_child = sn->child;
const struct dm_config_value *cv;
uint32_t area_extents, start_extent, extent_count, reshape_count, data_copies;
uint32_t start_extent, extent_count;
struct segment_type *segtype;
const char *segtype_str;
@@ -375,12 +375,6 @@ static int _read_segment(struct logical_volume *lv, const struct dm_config_node
return 0;
}
if (!_read_int32(sn_child, "reshape_count", &reshape_count))
reshape_count = 0;
if (!_read_int32(sn_child, "data_copies", &data_copies))
data_copies = 1;
segtype_str = SEG_TYPE_NAME_STRIPED;
if (!dm_config_get_str(sn_child, "type", &segtype_str)) {
@@ -395,11 +389,9 @@ static int _read_segment(struct logical_volume *lv, const struct dm_config_node
!segtype->ops->text_import_area_count(sn_child, &area_count))
return_0;
area_extents = segtype->parity_devs ?
raid_rimage_extents(segtype, extent_count, area_count - segtype->parity_devs, data_copies) : extent_count;
if (!(seg = alloc_lv_segment(segtype, lv, start_extent,
extent_count, reshape_count, 0, 0, NULL, area_count,
area_extents, data_copies, 0, 0, 0, NULL))) {
extent_count, 0, 0, NULL, area_count,
extent_count, 0, 0, 0, NULL))) {
log_error("Segment allocation failed");
return 0;
}

View File

@@ -35,7 +35,7 @@ const char *display_cache_mode(const struct lv_segment *seg)
seg = first_seg(seg->pool_lv);
if (!seg_is_cache_pool(seg) ||
(seg->cache_mode == CACHE_MODE_UNSELECTED))
(seg->cache_mode == CACHE_MODE_UNDEFINED))
return "";
return get_cache_mode_name(seg);
@@ -77,14 +77,13 @@ int set_cache_mode(cache_mode_t *mode, const char *cache_mode)
int cache_set_cache_mode(struct lv_segment *seg, cache_mode_t mode)
{
struct cmd_context *cmd = seg->lv->vg->cmd;
struct profile *profile = seg->lv->profile;
const char *str;
int id;
if (seg_is_cache(seg))
seg = first_seg(seg->pool_lv);
else if (seg_is_cache_pool(seg)) {
if (mode == CACHE_MODE_UNSELECTED)
if (mode == CACHE_MODE_UNDEFINED)
return 1; /* Defaults only for cache */
} else {
log_error(INTERNAL_ERROR "Cannot set cache mode for non cache volume %s.",
@@ -92,12 +91,12 @@ int cache_set_cache_mode(struct lv_segment *seg, cache_mode_t mode)
return 0;
}
if (mode != CACHE_MODE_UNSELECTED) {
if (mode != CACHE_MODE_UNDEFINED) {
seg->cache_mode = mode;
return 1;
}
if (seg->cache_mode != CACHE_MODE_UNSELECTED)
if (seg->cache_mode != CACHE_MODE_UNDEFINED)
return 1; /* Default already set in cache pool */
/* Figure default settings from config/profiles */
@@ -108,7 +107,7 @@ int cache_set_cache_mode(struct lv_segment *seg, cache_mode_t mode)
find_config_node(cmd, cmd->cft, allocation_cache_pool_cachemode_CFG))
id = allocation_cache_pool_cachemode_CFG;
if (!(str = find_config_tree_str(cmd, id, profile))) {
if (!(str = find_config_tree_str(cmd, id, NULL))) {
log_error(INTERNAL_ERROR "Cache mode is not determined.");
return 0;
}
@@ -153,30 +152,25 @@ static uint64_t _cache_min_metadata_size(uint64_t data_size, uint32_t chunk_size
return min_meta_size;
}
int update_cache_pool_params(struct cmd_context *cmd,
struct profile *profile,
uint32_t extent_size,
const struct segment_type *segtype,
unsigned attr,
uint32_t pool_data_extents,
int update_cache_pool_params(const struct segment_type *segtype,
struct volume_group *vg, unsigned attr,
int passed_args, uint32_t pool_data_extents,
uint32_t *pool_metadata_extents,
int *chunk_size_calc_method, uint32_t *chunk_size)
{
uint64_t min_meta_size;
uint32_t extent_size = vg->extent_size;
uint64_t pool_metadata_size = (uint64_t) *pool_metadata_extents * extent_size;
uint64_t pool_data_size = (uint64_t) pool_data_extents * extent_size;
const uint64_t max_chunks =
get_default_allocation_cache_pool_max_chunks_CFG(cmd, profile);
uint64_t max_chunks =
get_default_allocation_cache_pool_max_chunks_CFG(vg->cmd, vg->profile);
/* min chunk size in a multiple of DM_CACHE_MIN_DATA_BLOCK_SIZE */
uint64_t min_chunk_size = (((pool_data_size + max_chunks - 1) / max_chunks +
DM_CACHE_MIN_DATA_BLOCK_SIZE - 1) /
DM_CACHE_MIN_DATA_BLOCK_SIZE) * DM_CACHE_MIN_DATA_BLOCK_SIZE;
if (!*chunk_size) {
if (!(*chunk_size = find_config_tree_int(cmd, allocation_cache_pool_chunk_size_CFG,
profile) * 2))
*chunk_size = get_default_allocation_cache_pool_chunk_size_CFG(cmd,
profile);
if (!(passed_args & PASS_ARG_CHUNK_SIZE)) {
*chunk_size = DEFAULT_CACHE_POOL_CHUNK_SIZE * 2;
if (*chunk_size < min_chunk_size) {
/*
* When using more then 'standard' default,
@@ -184,25 +178,25 @@ int update_cache_pool_params(struct cmd_context *cmd,
*/
log_print_unless_silent("Using %s chunk size instead of default %s, "
"so cache pool has less then " FMTu64 " chunks.",
display_size(cmd, min_chunk_size),
display_size(cmd, *chunk_size),
display_size(vg->cmd, min_chunk_size),
display_size(vg->cmd, *chunk_size),
max_chunks);
*chunk_size = min_chunk_size;
} else
log_verbose("Setting chunk size to %s.",
display_size(cmd, *chunk_size));
display_size(vg->cmd, *chunk_size));
} else if (*chunk_size < min_chunk_size) {
log_error("Chunk size %s is less then required minimal chunk size %s "
"for a cache pool of %s size and limit " FMTu64 " chunks.",
display_size(cmd, *chunk_size),
display_size(cmd, min_chunk_size),
display_size(cmd, pool_data_size),
display_size(vg->cmd, *chunk_size),
display_size(vg->cmd, min_chunk_size),
display_size(vg->cmd, pool_data_size),
max_chunks);
log_error("To allow use of more chunks, see setting allocation/cache_pool_max_chunks.");
return 0;
}
if (!validate_cache_chunk_size(cmd, *chunk_size))
if (!validate_pool_chunk_size(vg->cmd, segtype, *chunk_size))
return_0;
min_meta_size = _cache_min_metadata_size((uint64_t) pool_data_extents * extent_size, *chunk_size);
@@ -216,31 +210,22 @@ int update_cache_pool_params(struct cmd_context *cmd,
if (pool_metadata_size > (2 * DEFAULT_CACHE_POOL_MAX_METADATA_SIZE)) {
pool_metadata_size = 2 * DEFAULT_CACHE_POOL_MAX_METADATA_SIZE;
if (*pool_metadata_extents)
if (passed_args & PASS_ARG_POOL_METADATA_SIZE)
log_warn("WARNING: Maximum supported pool metadata size is %s.",
display_size(cmd, pool_metadata_size));
display_size(vg->cmd, pool_metadata_size));
} else if (pool_metadata_size < min_meta_size) {
if (*pool_metadata_extents)
if (passed_args & PASS_ARG_POOL_METADATA_SIZE)
log_warn("WARNING: Minimum required pool metadata size is %s "
"(needs extra %s).",
display_size(cmd, min_meta_size),
display_size(cmd, min_meta_size - pool_metadata_size));
display_size(vg->cmd, min_meta_size),
display_size(vg->cmd, min_meta_size - pool_metadata_size));
pool_metadata_size = min_meta_size;
}
if (!(*pool_metadata_extents =
extents_from_size(cmd, pool_metadata_size, extent_size)))
extents_from_size(vg->cmd, pool_metadata_size, extent_size)))
return_0;
if ((uint64_t) *chunk_size > (uint64_t) pool_data_extents * extent_size) {
log_error("Size of %s data volume cannot be smaller than chunk size %s.",
segtype->name, display_size(cmd, *chunk_size));
return 0;
}
log_verbose("Preferred pool metadata size %s.",
display_size(cmd, (uint64_t)*pool_metadata_extents * extent_size));
return 1;
}
@@ -251,7 +236,7 @@ int update_cache_pool_params(struct cmd_context *cmd,
int validate_lv_cache_chunk_size(struct logical_volume *pool_lv, uint32_t chunk_size)
{
struct volume_group *vg = pool_lv->vg;
const uint64_t max_chunks = get_default_allocation_cache_pool_max_chunks_CFG(vg->cmd, pool_lv->profile);
uint64_t max_chunks = get_default_allocation_cache_pool_max_chunks_CFG(vg->cmd, vg->profile);
uint64_t min_size = _cache_min_metadata_size(pool_lv->size, chunk_size);
uint64_t chunks = pool_lv->size / chunk_size;
int r = 1;
@@ -307,7 +292,7 @@ int validate_lv_cache_create_pool(const struct logical_volume *pool_lv)
if (!dm_list_empty(&pool_lv->segs_using_this_lv)) {
seg = get_only_segment_using_this_lv(pool_lv);
log_error("Logical volume %s is already in use by %s.",
log_error("Logical volume %s is already in use by %s",
display_lvname(pool_lv),
seg ? display_lvname(seg->lv) : "another LV");
return 0;
@@ -348,30 +333,6 @@ int validate_lv_cache_create_origin(const struct logical_volume *origin_lv)
return 1;
}
int validate_cache_chunk_size(struct cmd_context *cmd, uint32_t chunk_size)
{
const uint32_t min_size = DM_CACHE_MIN_DATA_BLOCK_SIZE;
const uint32_t max_size = DM_CACHE_MAX_DATA_BLOCK_SIZE;
int r = 1;
if ((chunk_size < min_size) || (chunk_size > max_size)) {
log_error("Cache chunk size %s is not in the range %s to %s.",
display_size(cmd, chunk_size),
display_size(cmd, min_size),
display_size(cmd, max_size));
r = 0;
}
if (chunk_size & (min_size - 1)) {
log_error("Cache chunk size %s must be a multiple of %s.",
display_size(cmd, chunk_size),
display_size(cmd, min_size));
r = 0;
}
return r;
}
/*
* lv_cache_create
* @pool
@@ -409,9 +370,6 @@ struct logical_volume *lv_cache_create(struct logical_volume *pool_lv,
if (!attach_pool_lv(seg, pool_lv, NULL, NULL, NULL))
return_NULL;
if (!seg->lv->profile) /* Inherit profile from cache-pool */
seg->lv->profile = seg->pool_lv->profile;
return cache_lv;
}
@@ -675,26 +633,6 @@ static const char *_get_default_cache_policy(struct cmd_context *cmd)
return def;
}
/* Autodetect best available cache metadata format for a user */
static cache_metadata_format_t _get_default_cache_metadata_format(struct cmd_context *cmd)
{
const struct segment_type *segtype = get_segtype_from_string(cmd, SEG_TYPE_NAME_CACHE);
unsigned attr;
cache_metadata_format_t f;
if (!segtype ||
!segtype->ops->target_present ||
!segtype->ops->target_present(cmd, NULL, &attr)) {
f = CACHE_METADATA_FORMAT_1;
log_warn("WARNING: Cannot detect default cache metadata format, using format: %u.", f);
} else {
f = (attr & CACHE_FEATURE_METADATA2) ? CACHE_METADATA_FORMAT_2 : CACHE_METADATA_FORMAT_1;
log_debug_metadata("Detected default cache metadata format: %u.", f);
}
return f;
}
int cache_set_policy(struct lv_segment *seg, const char *name,
const struct dm_config_tree *settings)
{
@@ -702,36 +640,28 @@ int cache_set_policy(struct lv_segment *seg, const char *name,
const struct dm_config_node *cns;
struct dm_config_tree *old = NULL, *new = NULL, *tmp = NULL;
int r = 0;
struct profile *profile = seg->lv->profile;
const int passed_seg_is_cache = seg_is_cache(seg);
if (seg_is_cache(seg))
if (passed_seg_is_cache)
seg = first_seg(seg->pool_lv);
else if (seg_is_cache_pool(seg)) {
if (!name && !settings)
return 1; /* Policy and settings can be selected later when caching LV */
} else {
log_error(INTERNAL_ERROR "Cannot set cache metadata format for non cache volume %s.",
display_lvname(seg->lv));
return 0;
}
if (name) {
if (!(seg->policy_name = dm_pool_strdup(seg->lv->vg->vgmem, name))) {
log_error("Failed to duplicate policy name.");
return 0;
}
} else if (!seg->policy_name) {
if (!(seg->policy_name = find_config_tree_str(seg->lv->vg->cmd, allocation_cache_policy_CFG,
profile)) &&
} else if (!seg->policy_name && passed_seg_is_cache) {
if (!(seg->policy_name = find_config_tree_str(seg->lv->vg->cmd, allocation_cache_policy_CFG, NULL)) &&
!(seg->policy_name = _get_default_cache_policy(seg->lv->vg->cmd)))
return_0;
}
if (settings) {
if (!seg->policy_name) {
log_error(INTERNAL_ERROR "Can't set policy settings without policy name.");
return 0;
}
}
if (settings) {
if (seg->policy_settings) {
if (!(old = dm_config_create()))
goto_out;
@@ -747,26 +677,30 @@ int cache_set_policy(struct lv_segment *seg, const char *name,
if ((cn = dm_config_find_node((tmp) ? tmp->root : settings->root, "policy_settings")) &&
!(seg->policy_settings = dm_config_clone_node_with_mem(seg->lv->vg->vgmem, cn, 0)))
goto_out;
} else if (!seg->policy_settings) {
if ((cns = find_config_tree_node(seg->lv->vg->cmd, allocation_cache_settings_CFG_SECTION,
profile))) {
/* Try to find our section for given policy */
for (cn = cns->child; cn; cn = cn->sib) {
if (!cn->child)
continue; /* Ignore section without settings */
} else if (passed_seg_is_cache && /* Look for command's profile cache_policies */
(cns = find_config_tree_node(seg->lv->vg->cmd, allocation_cache_settings_CFG_SECTION, NULL))) {
/* Try to find our section for given policy */
for (cn = cns->child; cn; cn = cn->sib) {
/* Only matching section names */
if (cn->v || strcmp(cn->key, seg->policy_name) != 0)
continue;
if (cn->v || strcmp(cn->key, seg->policy_name) != 0)
continue; /* Ignore mismatching sections */
if (!cn->child)
break;
/* Clone nodes with policy name */
if (!(seg->policy_settings = dm_config_clone_node_with_mem(seg->lv->vg->vgmem,
cn, 0)))
return_0;
if (!(new = dm_config_create()))
goto_out;
/* Replace policy name key with 'policy_settings' */
seg->policy_settings->key = "policy_settings";
break; /* Only first match counts */
}
if (!(new->root = dm_config_clone_node_with_mem(new->mem,
cn->child, 1)))
goto_out;
if (!(seg->policy_settings = dm_config_create_node(new, "policy_settings")))
goto_out;
seg->policy_settings->child = new->root;
break; /* Only first match counts */
}
}
@@ -793,94 +727,17 @@ out:
return r;
}
/*
* Sets metadata format on cache pool segment with these rules:
* 1. When 'cache-pool' segment is passed, sets only for selected formats (1 or 2).
* 2. For 'cache' segment passed in we know cache pool segment.
* When passed format is 0 (UNSELECTED) with 'cache' segment - it's the moment
* lvm2 has to figure out 'default' metadata format (1 or 2) from
* configuration or profiles.
* 3. If still unselected or selected format is != 1, figure the best supported format
* and either use it or validate users settings is possible.
*
* Reasoning: A user may create cache-pool and may or may not specify CMFormat.
* If the CMFormat has been selected (1 or 2) store this in metadata, otherwise
* for an unused cache-pool UNSELECTED CMFormat is used. When caching LV, CMFormat
* must be decided and from this moment it's always stored. To support backward
* compatibility 'CMFormat 1' is used when it is NOT specified for a cached LV in
* lvm2 metadata (no metadata_format=#F element in cache-pool segment).
*/
int cache_set_metadata_format(struct lv_segment *seg, cache_metadata_format_t format)
{
cache_metadata_format_t best;
struct profile *profile = seg->lv->profile;
if (seg_is_cache(seg))
seg = first_seg(seg->pool_lv);
else if (seg_is_cache_pool(seg)) {
if (format == CACHE_METADATA_FORMAT_UNSELECTED)
return 1; /* Format can be selected later when caching LV */
} else {
log_error(INTERNAL_ERROR "Cannot set cache metadata format for non cache volume %s.",
display_lvname(seg->lv));
return 0;
}
/* Check if we need to search for configured cache metadata format */
if (format == CACHE_METADATA_FORMAT_UNSELECTED) {
if (seg->cache_metadata_format != CACHE_METADATA_FORMAT_UNSELECTED)
return 1; /* Format already selected in cache pool */
/* Check configurations and profiles */
format = find_config_tree_int(seg->lv->vg->cmd, allocation_cache_metadata_format_CFG,
profile);
}
/* See what is a 'best' available cache metadata format
* when the specifed format is other then always existing CMFormat 1 */
if (format != CACHE_METADATA_FORMAT_1) {
best = _get_default_cache_metadata_format(seg->lv->vg->cmd);
/* Format was not selected, so use best present on a system */
if (format == CACHE_METADATA_FORMAT_UNSELECTED)
format = best;
else if (format != best) {
/* Format is not valid (Only Format 1 or 2 is supported ATM) */
log_error("Cache metadata format %u is not supported by kernel target.", format);
return 0;
}
}
switch (format) {
case CACHE_METADATA_FORMAT_2: seg->lv->status |= LV_METADATA_FORMAT; break;
case CACHE_METADATA_FORMAT_1: seg->lv->status &= ~LV_METADATA_FORMAT; break;
default:
log_error(INTERNAL_ERROR "Invalid cache metadata format %u for cache volume %s.",
format, display_lvname(seg->lv));
return 0;
}
seg->cache_metadata_format = format;
return 1;
}
/*
* Universal 'wrapper' function do-it-all
* to update all commonly specified cache parameters
*/
int cache_set_params(struct lv_segment *seg,
uint32_t chunk_size,
cache_metadata_format_t format,
cache_mode_t mode,
const char *policy_name,
const struct dm_config_tree *policy_settings)
const struct dm_config_tree *policy_settings,
uint32_t chunk_size)
{
struct lv_segment *pool_seg;
struct cmd_context *cmd = seg->lv->vg->cmd;
if (!cache_set_metadata_format(seg, format))
return_0;
if (!cache_set_cache_mode(seg, mode))
return_0;
@@ -891,35 +748,16 @@ int cache_set_params(struct lv_segment *seg,
pool_seg = seg_is_cache(seg) ? first_seg(seg->pool_lv) : seg;
if (chunk_size) {
if (seg_is_cache(seg) &&
!validate_lv_cache_chunk_size(pool_seg->lv, chunk_size))
if (!validate_lv_cache_chunk_size(pool_seg->lv, chunk_size))
return_0;
pool_seg->chunk_size = chunk_size;
} else if (seg_is_cache(seg)) {
/* Chunk size in profile has priority over cache-pool chunk size */
if ((chunk_size = find_config_tree_int(cmd, allocation_cache_pool_chunk_size_CFG,
seg->lv->profile) * 2)) {
if (!validate_lv_cache_chunk_size(pool_seg->lv, chunk_size))
return_0;
if (pool_seg->chunk_size != chunk_size)
log_verbose("Replacing chunk size %s in cache pool %s with "
"chunk size %s from profile.",
display_size(cmd, pool_seg->chunk_size),
display_lvname(seg->lv),
display_size(cmd, chunk_size));
pool_seg->chunk_size = chunk_size;
}
} else if (seg_is_cache_pool(seg)) {
if (!pool_seg->chunk_size &&
/* TODO: some calc_policy solution for cache ? */
!recalculate_pool_chunk_size_with_dev_hints(pool_seg->lv,
} else {
/* TODO: some calc_policy solution for cache ? */
if (!recalculate_pool_chunk_size_with_dev_hints(pool_seg->lv, 0,
THIN_CHUNK_SIZE_CALC_METHOD_GENERIC))
return_0;
}
if (seg_is_cache(seg))
cache_check_for_warns(seg);
return 1;
}

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2017 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004-2016 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -227,23 +227,12 @@ char *lvseg_kernel_discards_dup_with_info_and_seg_status(struct dm_pool *mem, co
{
const char *s = "";
char *ret;
thin_discards_t d;
if (lvdm->seg_status.type == SEG_STATUS_THIN_POOL) {
switch (lvdm->seg_status.thin_pool->discards) {
case DM_THIN_DISCARDS_IGNORE: d = THIN_DISCARDS_IGNORE; break;
case DM_THIN_DISCARDS_NO_PASSDOWN: d = THIN_DISCARDS_NO_PASSDOWN; break;
case DM_THIN_DISCARDS_PASSDOWN: d = THIN_DISCARDS_PASSDOWN; break;
default:
log_error("Kernel reports unknown discards status %u.",
lvdm->seg_status.thin_pool->discards);
return 0;
}
s = get_pool_discards_name(d);
}
if (lvdm->seg_status.type == SEG_STATUS_THIN_POOL)
s = get_pool_discards_name(lvdm->seg_status.thin_pool->discards);
if (!(ret = dm_pool_strdup(mem, s))) {
log_error("lvseg_kernel_discards_dup_with_info_and_seg_status: dm_pool_strdup failed.");
log_error("lvseg_kernel_discards_dup_with_info_and_seg_status: dm_pool_strdup failed");
return NULL;
}
@@ -1115,19 +1104,6 @@ int lv_raid_healthy(const struct logical_volume *lv)
return 1;
}
/* Helper: check for any sub LVs after a disk removing reshape */
static int _sublvs_remove_after_reshape(const struct logical_volume *lv)
{
uint32_t s;
struct lv_segment *seg = first_seg(lv);
for (s = seg->area_count -1; s; s--)
if (seg_lv(seg, s)->status & LV_REMOVE_AFTER_RESHAPE)
return 1;
return 0;
}
char *lv_attr_dup_with_info_and_seg_status(struct dm_pool *mem, const struct lv_with_info_and_seg_status *lvdm)
{
const struct logical_volume *lv = lvdm->lv;
@@ -1279,7 +1255,7 @@ char *lv_attr_dup_with_info_and_seg_status(struct dm_pool *mem, const struct lv_
if (((lv_is_thin_volume(lv) && (seg = first_seg(lv)) && seg->pool_lv && (seg = first_seg(seg->pool_lv))) ||
(lv_is_thin_pool(lv) && (seg = first_seg(lv)))) &&
(seg->zero_new_blocks == THIN_ZERO_YES))
seg->zero_new_blocks)
repstr[7] = 'z';
else
repstr[7] = '-';
@@ -1293,8 +1269,6 @@ char *lv_attr_dup_with_info_and_seg_status(struct dm_pool *mem, const struct lv_
repstr[8] = 'p';
else if (lv_is_raid_type(lv)) {
uint64_t n;
char *sync_action;
if (!activation())
repstr[8] = 'X'; /* Unknown */
else if (!lv_raid_healthy(lv))
@@ -1302,17 +1276,8 @@ char *lv_attr_dup_with_info_and_seg_status(struct dm_pool *mem, const struct lv_
else if (lv_is_raid(lv)) {
if (lv_raid_mismatch_count(lv, &n) && n)
repstr[8] = 'm'; /* RAID has 'm'ismatches */
else if (lv_raid_sync_action(lv, &sync_action) &&
!strcmp(sync_action, "reshape"))
repstr[8] = 's'; /* LV is re(s)haping */
else if (_sublvs_remove_after_reshape(lv))
repstr[8] = 'R'; /* sub-LV got freed from raid set by reshaping
and has to be 'R'emoved */
} else if (lv->status & LV_WRITEMOSTLY)
repstr[8] = 'w'; /* sub-LV has 'w'ritemostly */
else if (lv->status & LV_REMOVE_AFTER_RESHAPE)
repstr[8] = 'R'; /* sub-LV got freed from raid set by reshaping
and has to be 'R'emoved */
} else if (lvdm->seg_status.type == SEG_STATUS_CACHE) {
if (lvdm->seg_status.cache->fail)
repstr[8] = 'F';

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2017 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004-2012 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -21,13 +21,11 @@
struct lv_segment *alloc_lv_segment(const struct segment_type *segtype,
struct logical_volume *lv,
uint32_t le, uint32_t len,
uint32_t reshape_len,
uint64_t status,
uint32_t stripe_size,
struct logical_volume *log_lv,
uint32_t area_count,
uint32_t area_len,
uint32_t data_copies,
uint32_t chunk_size,
uint32_t region_size,
uint32_t extents_copied,

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2017 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004-2014 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -912,13 +912,11 @@ static uint32_t _round_to_stripe_boundary(struct volume_group *vg, uint32_t exte
struct lv_segment *alloc_lv_segment(const struct segment_type *segtype,
struct logical_volume *lv,
uint32_t le, uint32_t len,
uint32_t reshape_len,
uint64_t status,
uint32_t stripe_size,
struct logical_volume *log_lv,
uint32_t area_count,
uint32_t area_len,
uint32_t data_copies,
uint32_t chunk_size,
uint32_t region_size,
uint32_t extents_copied,
@@ -952,12 +950,10 @@ struct lv_segment *alloc_lv_segment(const struct segment_type *segtype,
seg->lv = lv;
seg->le = le;
seg->len = len;
seg->reshape_len = reshape_len;
seg->status = status;
seg->stripe_size = stripe_size;
seg->area_count = area_count;
seg->area_len = area_len;
seg->data_copies = data_copies ? : lv_raid_data_copies(segtype, area_count);
seg->chunk_size = chunk_size;
seg->region_size = region_size;
seg->extents_copied = extents_copied;
@@ -1051,10 +1047,11 @@ static int _release_and_discard_lv_segment_area(struct lv_segment *seg, uint32_t
if (lv_is_raid_image(lv)) {
/* Calculate the amount of extents to reduce per rmate/rimage LV */
uint32_t rimage_extents;
struct lv_segment *seg1 = first_seg(lv);
/* FIXME: avoid extra seg_is_*() conditionals here */
rimage_extents = raid_rimage_extents(seg1->segtype, area_reduction, seg_is_any_raid0(seg) ? 0 : _raid_stripes_count(seg),
/* FIXME: avoid extra seg_is_*() conditonals */
area_reduction =_round_to_stripe_boundary(lv->vg, area_reduction,
(seg_is_raid1(seg) || seg_is_any_raid0(seg)) ? 0 : _raid_stripes_count(seg), 0);
rimage_extents = raid_rimage_extents(seg->segtype, area_reduction, seg_is_any_raid0(seg) ? 0 : _raid_stripes_count(seg),
seg_is_raid10(seg) ? 1 :_raid_data_copies(seg));
if (!rimage_extents)
return 0;
@@ -1261,7 +1258,7 @@ static uint32_t _calc_area_multiple(const struct segment_type *segtype,
* the 'stripes' argument will always need to
* be given.
*/
if (segtype_is_raid10(segtype)) {
if (!strcmp(segtype->name, _lv_type_names[LV_TYPE_RAID10])) {
if (!stripes)
return area_count / 2;
return stripes;
@@ -1281,17 +1278,16 @@ static uint32_t _calc_area_multiple(const struct segment_type *segtype,
static int _lv_segment_reduce(struct lv_segment *seg, uint32_t reduction)
{
uint32_t area_reduction, s;
uint32_t areas = (seg->area_count / (seg_is_raid10(seg) ? seg->data_copies : 1)) - seg->segtype->parity_devs;
/* Caller must ensure exact divisibility */
if (seg_is_striped(seg) || seg_is_striped_raid(seg)) {
if (reduction % areas) {
if (seg_is_striped(seg)) {
if (reduction % seg->area_count) {
log_error("Segment extent reduction %" PRIu32
" not divisible by #stripes %" PRIu32,
reduction, seg->area_count);
return 0;
}
area_reduction = reduction / areas;
area_reduction = (reduction / seg->area_count);
} else
area_reduction = reduction;
@@ -1300,11 +1296,7 @@ static int _lv_segment_reduce(struct lv_segment *seg, uint32_t reduction)
return_0;
seg->len -= reduction;
if (seg_is_raid(seg))
seg->area_len = seg->len;
else
seg->area_len -= area_reduction;
seg->area_len -= area_reduction;
return 1;
}
@@ -1314,13 +1306,11 @@ static int _lv_segment_reduce(struct lv_segment *seg, uint32_t reduction)
*/
static int _lv_reduce(struct logical_volume *lv, uint32_t extents, int delete)
{
struct lv_segment *seg = first_seg(lv);;
struct lv_segment *seg;
uint32_t count = extents;
uint32_t reduction;
struct logical_volume *pool_lv;
struct logical_volume *external_lv = NULL;
int is_raid10 = seg_is_any_raid10(seg) && seg->reshape_len;
uint32_t data_copies = seg->data_copies;
if (lv_is_merging_origin(lv)) {
log_debug_metadata("Dropping snapshot merge of %s to removed origin %s.",
@@ -1383,18 +1373,8 @@ static int _lv_reduce(struct logical_volume *lv, uint32_t extents, int delete)
count -= reduction;
}
seg = first_seg(lv);
if (is_raid10) {
lv->le_count -= extents * data_copies;
if (seg)
seg->len = seg->area_len = lv->le_count;
} else
lv->le_count -= extents;
lv->le_count -= extents;
lv->size = (uint64_t) lv->le_count * lv->vg->extent_size;
if (seg)
seg->extents_copied = seg->len;
if (!delete)
return 1;
@@ -1507,10 +1487,11 @@ int lv_reduce(struct logical_volume *lv, uint32_t extents)
{
struct lv_segment *seg = first_seg(lv);
/* Ensure stripe boundary extents on RAID LVs */
/* Ensure stipe boundary extents on RAID LVs */
if (lv_is_raid(lv) && extents != lv->le_count)
extents =_round_to_stripe_boundary(lv->vg, extents,
seg_is_raid1(seg) ? 0 : _raid_stripes_count(seg), 0);
return _lv_reduce(lv, extents, 1);
}
@@ -1812,10 +1793,10 @@ static int _setup_alloced_segment(struct logical_volume *lv, uint64_t status,
area_multiple = _calc_area_multiple(segtype, area_count, 0);
extents = aa[0].len * area_multiple;
if (!(seg = alloc_lv_segment(segtype, lv, lv->le_count, extents, 0,
if (!(seg = alloc_lv_segment(segtype, lv, lv->le_count, extents,
status, stripe_size, NULL,
area_count,
aa[0].len, 0, 0u, region_size, 0u, NULL))) {
aa[0].len, 0u, region_size, 0u, NULL))) {
log_error("Couldn't allocate new LV segment.");
return 0;
}
@@ -3253,9 +3234,9 @@ int lv_add_virtual_segment(struct logical_volume *lv, uint64_t status,
seg->area_len += extents;
seg->len += extents;
} else {
if (!(seg = alloc_lv_segment(segtype, lv, lv->le_count, extents, 0,
if (!(seg = alloc_lv_segment(segtype, lv, lv->le_count, extents,
status, 0, NULL, 0,
extents, 0, 0, 0, 0, NULL))) {
extents, 0, 0, 0, NULL))) {
log_error("Couldn't allocate new %s segment.", segtype->name);
return 0;
}
@@ -3581,10 +3562,10 @@ static struct lv_segment *_convert_seg_to_mirror(struct lv_segment *seg,
}
if (!(newseg = alloc_lv_segment(get_segtype_from_string(seg->lv->vg->cmd, SEG_TYPE_NAME_MIRROR),
seg->lv, seg->le, seg->len, 0,
seg->lv, seg->le, seg->len,
seg->status, seg->stripe_size,
log_lv,
seg->area_count, seg->area_len, 0,
seg->area_count, seg->area_len,
seg->chunk_size, region_size,
seg->extents_copied, NULL))) {
log_error("Couldn't allocate converted LV segment.");
@@ -3686,8 +3667,8 @@ int lv_add_segmented_mirror_image(struct alloc_handle *ah,
}
if (!(new_seg = alloc_lv_segment(segtype, copy_lv,
seg->le, seg->len, 0, PVMOVE, 0,
NULL, 1, seg->len, 0,
seg->le, seg->len, PVMOVE, 0,
NULL, 1, seg->len,
0, 0, 0, NULL)))
return_0;
@@ -3882,9 +3863,9 @@ static int _lv_insert_empty_sublvs(struct logical_volume *lv,
/*
* First, create our top-level segment for our top-level LV
*/
if (!(mapseg = alloc_lv_segment(segtype, lv, 0, 0, 0, lv->status,
if (!(mapseg = alloc_lv_segment(segtype, lv, 0, 0, lv->status,
stripe_size, NULL,
devices, 0, 0, 0, region_size, 0, NULL))) {
devices, 0, 0, region_size, 0, NULL))) {
log_error("Failed to create mapping segment for %s.",
display_lvname(lv));
return 0;
@@ -3944,7 +3925,7 @@ bad:
static int _lv_extend_layered_lv(struct alloc_handle *ah,
struct logical_volume *lv,
uint32_t extents, uint32_t first_area,
uint32_t mirrors, uint32_t stripes, uint32_t stripe_size)
uint32_t stripes, uint32_t stripe_size)
{
const struct segment_type *segtype;
struct logical_volume *sub_lv, *meta_lv;
@@ -3972,7 +3953,7 @@ static int _lv_extend_layered_lv(struct alloc_handle *ah,
for (fa = first_area, s = 0; s < seg->area_count; s++) {
if (is_temporary_mirror_layer(seg_lv(seg, s))) {
if (!_lv_extend_layered_lv(ah, seg_lv(seg, s), extents / area_multiple,
fa, mirrors, stripes, stripe_size))
fa, stripes, stripe_size))
return_0;
fa += lv_mirror_count(seg_lv(seg, s));
continue;
@@ -3986,8 +3967,6 @@ static int _lv_extend_layered_lv(struct alloc_handle *ah,
return 0;
}
last_seg(lv)->data_copies = mirrors;
/* Extend metadata LVs only on initial creation */
if (seg_is_raid_with_meta(seg) && !lv->le_count) {
if (!seg->meta_areas) {
@@ -4084,11 +4063,8 @@ static int _lv_extend_layered_lv(struct alloc_handle *ah,
lv_set_hidden(seg_metalv(seg, s));
}
seg->area_len += extents / area_multiple;
seg->len += extents;
if (seg_is_raid(seg))
seg->area_len = seg->len;
else
seg->area_len += extents / area_multiple;
if (!_setup_lv_size(lv, lv->le_count + extents))
return_0;
@@ -4195,7 +4171,7 @@ int lv_extend(struct logical_volume *lv,
}
if (!(r = _lv_extend_layered_lv(ah, lv, new_extents - lv->le_count, 0,
mirrors, stripes, stripe_size)))
stripes, stripe_size)))
goto_out;
/*
@@ -5415,17 +5391,6 @@ int lv_resize(struct logical_volume *lv,
if (!_lvresize_check(lv, lp))
return_0;
if (seg->reshape_len) {
/* Prevent resizing on out-of-sync reshapable raid */
if (!lv_raid_in_sync(lv)) {
log_error("Can't resize reshaping LV %s.", display_lvname(lv));
return 0;
}
/* Remove any striped raid reshape space for LV resizing */
if (!lv_raid_free_reshape_space(lv))
return_0;
}
if (lp->use_policies) {
lp->extents = 0;
lp->sign = SIGN_PLUS;
@@ -5937,7 +5902,6 @@ int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv,
int ask_discard;
struct lv_list *lvl;
struct seg_list *sl;
struct lv_segment *seg = first_seg(lv);
int is_last_pool = lv_is_pool(lv);
vg = lv->vg;
@@ -6044,13 +6008,6 @@ int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv,
is_last_pool = 1;
}
/* Special case removing a striped raid LV with allocated reshape space */
if (seg && seg->reshape_len) {
if (!(seg->segtype = get_segtype_from_string(cmd, SEG_TYPE_NAME_STRIPED)))
return_0;
lv->le_count = seg->len = seg->area_len = seg_lv(seg, 0)->le_count * seg->area_count;
}
/* Used cache pool, COW or historical LV cannot be activated */
if ((!lv_is_cache_pool(lv) || dm_list_empty(&lv->segs_using_this_lv)) &&
!lv_is_cow(lv) && !lv_is_historical(lv) &&
@@ -6272,21 +6229,12 @@ int lv_remove_with_dependencies(struct cmd_context *cmd, struct logical_volume *
/* Remove snapshot LVs first */
if ((force == PROMPT) &&
/* Active snapshot already needs to confirm each active LV */
(yes_no_prompt("Do you really want to remove%s "
"%sorigin logical volume %s with %u snapshot(s)? [y/n]: ",
lv_is_active(lv) ? " active" : "",
vg_is_clustered(lv->vg) ? "clustered " : "",
display_lvname(lv),
lv->origin_count) == 'n'))
!lv_is_active(lv) &&
yes_no_prompt("Removing origin %s will also remove %u "
"snapshots(s). Proceed? [y/n]: ",
lv->name, lv->origin_count) == 'n')
goto no_remove;
if (!deactivate_lv(cmd, lv)) {
stack;
goto no_remove;
}
log_verbose("Removing origin logical volume %s with %u snapshots(s).",
display_lvname(lv), lv->origin_count);
dm_list_iterate_safe(snh, snht, &lv->snapshot_segs)
if (!lv_remove_with_dependencies(cmd, dm_list_struct_base(snh, struct lv_segment,
origin_list)->cow,
@@ -6352,6 +6300,7 @@ static int _lv_update_and_reload(struct logical_volume *lv, int origin_only)
log_very_verbose("Updating logical volume %s on disk(s)%s.",
display_lvname(lock_lv), origin_only ? " (origin only)": "");
if (!vg_write(vg))
return_0;
@@ -6818,8 +6767,8 @@ struct logical_volume *insert_layer_for_lv(struct cmd_context *cmd,
return_NULL;
/* allocate a new linear segment */
if (!(mapseg = alloc_lv_segment(segtype, lv_where, 0, layer_lv->le_count, 0,
status, 0, NULL, 1, layer_lv->le_count, 0,
if (!(mapseg = alloc_lv_segment(segtype, lv_where, 0, layer_lv->le_count,
status, 0, NULL, 1, layer_lv->le_count,
0, 0, 0, NULL)))
return_NULL;
@@ -6875,8 +6824,8 @@ static int _extend_layer_lv_for_segment(struct logical_volume *layer_lv,
/* allocate a new segment */
if (!(mapseg = alloc_lv_segment(segtype, layer_lv, layer_lv->le_count,
seg->area_len, 0, status, 0,
NULL, 1, seg->area_len, 0, 0, 0, 0, seg)))
seg->area_len, status, 0,
NULL, 1, seg->area_len, 0, 0, 0, seg)))
return_0;
/* map the new segment to the original underlying are */
@@ -7402,20 +7351,29 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
return NULL;
}
if (seg_is_thin_volume(lp)) {
/* Validate volume size to to aling on chunk for small extents */
size = first_seg(pool_lv)->chunk_size;
if (size > vg->extent_size) {
/* Align extents on chunk boundary size */
size = ((uint64_t)vg->extent_size * lp->extents + size - 1) /
size * size / vg->extent_size;
if (size != lp->extents) {
log_print_unless_silent("Rounding size (%d extents) up to chunk boundary "
"size (%d extents).", lp->extents, size);
lp->extents = size;
}
}
if (seg_is_cache(lp)) {
/* validate metadata size */
if (!validate_lv_cache_chunk_size(pool_lv, lp->chunk_size))
return_0;
first_seg(pool_lv)->chunk_size = lp->chunk_size;
}
/* Validate volume size to to aling on chunk for small extents */
/* Cache chunk size is always set */
size = first_seg(pool_lv)->chunk_size;
if (size > vg->extent_size) {
/* Align extents on chunk boundary size */
size = ((uint64_t)vg->extent_size * lp->extents + size - 1) /
size * size / vg->extent_size;
if (size != lp->extents) {
log_print_unless_silent("Rounding size (%d extents) up to chunk boundary "
"size (%d extents).", lp->extents, size);
lp->extents = size;
}
}
if (seg_is_thin_volume(lp)) {
thin_pool_was_active = lv_is_active(pool_lv);
if (lv_is_new_thin_pool(pool_lv)) {
if (!check_new_thin_pool(pool_lv))
@@ -7425,7 +7383,7 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
if (!activate_lv_excl_local(cmd, pool_lv)) {
log_error("Aborting. Failed to locally activate thin pool %s.",
display_lvname(pool_lv));
return NULL;
return 0;
}
if (!pool_below_threshold(first_seg(pool_lv))) {
log_error("Cannot create new thin volume, free space in "
@@ -7663,11 +7621,10 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
if (lv_is_cache_pool(lv)) {
if (!cache_set_params(first_seg(lv),
lp->chunk_size,
lp->cache_metadata_format,
lp->cache_mode,
lp->policy_name,
lp->policy_settings)) {
lp->policy_settings,
lp->chunk_size)) {
stack;
goto revert_new_lv;
}
@@ -7676,9 +7633,10 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
first_seg(lv)->max_recovery_rate = lp->max_recovery_rate;
} else if (lv_is_thin_pool(lv)) {
first_seg(lv)->chunk_size = lp->chunk_size;
first_seg(lv)->zero_new_blocks = lp->zero_new_blocks;
first_seg(lv)->zero_new_blocks = lp->zero ? 1 : 0;
first_seg(lv)->discards = lp->discards;
if (!recalculate_pool_chunk_size_with_dev_hints(lv, lp->thin_chunk_size_calc_policy)) {
if (!recalculate_pool_chunk_size_with_dev_hints(lv, lp->passed_args,
lp->thin_chunk_size_calc_policy)) {
stack;
goto revert_new_lv;
}
@@ -7872,13 +7830,14 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
lv = tmp_lv;
if (!cache_set_params(first_seg(lv),
lp->chunk_size,
lp->cache_metadata_format,
lp->cache_mode,
lp->policy_name,
lp->policy_settings))
lp->policy_settings,
(lp->passed_args & PASS_ARG_CHUNK_SIZE) ? lp->chunk_size : 0))
return_NULL; /* revert? */
cache_check_for_warns(first_seg(lv));
if (!lv_update_and_reload(lv)) {
/* FIXME Do a better revert */
log_error("Aborting. Manual intervention required.");

View File

@@ -236,7 +236,7 @@ static void _check_raid_seg(struct lv_segment *seg, int *error_count)
if (!seg->areas)
raid_seg_error("zero areas");
if (seg->extents_copied > seg->len)
if (seg->extents_copied > seg->area_len)
raid_seg_error_val("extents_copied too large", seg->extents_copied);
/* Default < 10, change once raid1 split shift and rename SubLVs works! */
@@ -328,13 +328,6 @@ static void _check_lv_segment(struct logical_volume *lv, struct lv_segment *seg,
if (seg_is_cache_pool(seg)) {
if (!dm_list_empty(&seg->lv->segs_using_this_lv)) {
switch (seg->cache_metadata_format) {
case CACHE_METADATA_FORMAT_2:
case CACHE_METADATA_FORMAT_1:
break;
default:
seg_error("has invalid cache metadata format");
}
switch (seg->cache_mode) {
case CACHE_MODE_WRITETHROUGH:
case CACHE_MODE_WRITEBACK:
@@ -346,24 +339,13 @@ static void _check_lv_segment(struct logical_volume *lv, struct lv_segment *seg,
if (!seg->policy_name)
seg_error("is missing cache policy name");
}
if (!validate_cache_chunk_size(lv->vg->cmd, seg->chunk_size))
seg_error("has invalid chunk size.");
if (seg->lv->status & LV_METADATA_FORMAT) {
if (seg->cache_metadata_format != CACHE_METADATA_FORMAT_2)
seg_error("sets METADATA_FORMAT flag");
} else if (seg->cache_metadata_format == CACHE_METADATA_FORMAT_2)
seg_error("is missing METADATA_FORMAT flag");
} else { /* !cache_pool */
if (seg->cache_metadata_format)
seg_error("sets cache metadata format");
if (seg->cache_mode)
seg_error("sets cache mode");
if (seg->policy_name)
seg_error("sets policy name");
if (seg->policy_settings)
seg_error("sets policy settings");
if (seg->lv->status & LV_METADATA_FORMAT)
seg_error("sets METADATA_FORMAT flag");
}
if (!seg_can_error_when_full(seg) && lv_is_error_when_full(lv))
@@ -398,6 +380,9 @@ static void _check_lv_segment(struct logical_volume *lv, struct lv_segment *seg,
seg_error("is missing a pool metadata LV");
} else if (!(seg2 = first_seg(seg->metadata_lv)) || (find_pool_seg(seg2) != seg))
seg_error("metadata LV does not refer back to pool LV");
if (!validate_pool_chunk_size(lv->vg->cmd, seg->segtype, seg->chunk_size))
seg_error("has invalid chunk size.");
} else { /* !thin_pool && !cache_pool */
if (seg->metadata_lv)
seg_error("must not have pool metadata LV set");
@@ -409,17 +394,10 @@ static void _check_lv_segment(struct logical_volume *lv, struct lv_segment *seg,
if (lv_is_thin_volume(lv))
seg_error("is a thin volume that must not contain thin pool segment");
if (!validate_thin_pool_chunk_size(lv->vg->cmd, seg->chunk_size))
seg_error("has invalid chunk size.");
if (seg->zero_new_blocks != THIN_ZERO_YES &&
seg->zero_new_blocks != THIN_ZERO_NO)
seg_error("zero_new_blocks is invalid");
} else { /* !thin_pool */
if (seg->zero_new_blocks != THIN_ZERO_UNSELECTED)
if (seg->zero_new_blocks)
seg_error("sets zero_new_blocks");
if (seg->discards != THIN_DISCARDS_UNSELECTED)
if (seg->discards)
seg_error("sets discards");
if (!dm_list_empty(&seg->thin_messages))
seg_error("sets thin_messages list");
@@ -497,7 +475,7 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
struct lv_segment *seg, *seg2;
uint32_t le = 0;
unsigned seg_count = 0, seg_found, external_lv_found = 0;
uint32_t data_rimage_count, s;
uint32_t area_multiplier, s;
struct seg_list *sl;
struct glv_list *glvl;
int error_count = 0;
@@ -520,13 +498,13 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
inc_error_count;
}
data_rimage_count = seg->area_count - seg->segtype->parity_devs;
/* FIXME: raid varies seg->area_len? */
if (seg->len != seg->area_len &&
seg->len != seg->area_len * data_rimage_count) {
log_error("LV %s: segment %u with len=%u "
" has inconsistent area_len %u",
lv->name, seg_count, seg->len, seg->area_len);
area_multiplier = segtype_is_striped(seg->segtype) ?
seg->area_count : 1;
if (seg->area_len * area_multiplier != seg->len) {
log_error("LV %s: segment %u has inconsistent "
"area_len %u",
lv->name, seg_count, seg->area_len);
inc_error_count;
}
@@ -788,10 +766,10 @@ static int _lv_split_segment(struct logical_volume *lv, struct lv_segment *seg,
/* Clone the existing segment */
if (!(split_seg = alloc_lv_segment(seg->segtype,
seg->lv, seg->le, seg->len, seg->reshape_len,
seg->lv, seg->le, seg->len,
seg->status, seg->stripe_size,
seg->log_lv,
seg->area_count, seg->area_len, seg->data_copies,
seg->area_count, seg->area_len,
seg->chunk_size, seg->region_size,
seg->extents_copied, seg->pvmove_source_seg))) {
log_error("Couldn't allocate cloned LV segment.");

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2017 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004-2016 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -137,12 +137,7 @@
e.g. to prohibit allocation of a RAID image
on a PV already holing an image of the RAID set */
#define LOCKD_SANLOCK_LV UINT64_C(0x0080000000000000) /* LV - Internal use only */
#define LV_RESHAPE_DELTA_DISKS_PLUS UINT64_C(0x0100000000000000) /* LV reshape flag delta disks plus image(s) */
#define LV_RESHAPE_DELTA_DISKS_MINUS UINT64_C(0x0200000000000000) /* LV reshape flag delta disks minus image(s) */
#define LV_REMOVE_AFTER_RESHAPE UINT64_C(0x0400000000000000) /* LV needs to be removed after a shrinking reshape */
#define LV_METADATA_FORMAT UINT64_C(0x0800000000000000) /* LV has segments with metadata format */
/* Next unused flag: UINT64_C(0x1000000000000000) */
/* Next unused flag: UINT64_C(0x0100000000000000) */
/* Format features flags */
#define FMT_SEGMENTS 0x00000001U /* Arbitrary segment params? */
@@ -276,32 +271,18 @@ enum {
};
typedef enum {
THIN_ZERO_UNSELECTED = 0,
THIN_ZERO_NO,
THIN_ZERO_YES,
} thin_zero_t;
typedef enum {
THIN_DISCARDS_UNSELECTED = 0,
THIN_DISCARDS_IGNORE,
THIN_DISCARDS_NO_PASSDOWN,
THIN_DISCARDS_PASSDOWN,
} thin_discards_t;
typedef enum {
CACHE_MODE_UNSELECTED = 0,
CACHE_MODE_UNDEFINED = 0,
CACHE_MODE_WRITETHROUGH,
CACHE_MODE_WRITEBACK,
CACHE_MODE_PASSTHROUGH,
} cache_mode_t;
/* ATM used for cache only */
typedef enum {
CACHE_METADATA_FORMAT_UNSELECTED = 0, /* On input means 'auto' */
CACHE_METADATA_FORMAT_1,
CACHE_METADATA_FORMAT_2,
} cache_metadata_format_t;
typedef enum {
LOCK_TYPE_INVALID = -1,
LOCK_TYPE_NONE = 0,
@@ -465,7 +446,6 @@ struct lv_segment {
const struct segment_type *segtype;
uint32_t le;
uint32_t len;
uint32_t reshape_len; /* For RAID: user hidden additional out of place reshaping length off area_len and len */
uint64_t status;
@@ -474,7 +454,6 @@ struct lv_segment {
uint32_t writebehind; /* For RAID (RAID1 only) */
uint32_t min_recovery_rate; /* For RAID */
uint32_t max_recovery_rate; /* For RAID */
uint32_t data_offset; /* For RAID: data offset in sectors on each data component image */
uint32_t area_count;
uint32_t area_len;
uint32_t chunk_size; /* For snapshots/thin_pool. In sectors. */
@@ -485,7 +464,6 @@ struct lv_segment {
struct logical_volume *cow;
struct dm_list origin_list;
uint32_t region_size; /* For mirrors, replicators - in sectors */
uint32_t data_copies; /* For RAID: number of data copies (e.g. 3 for RAID 6 */
uint32_t extents_copied;/* Number of extents synced for raids/mirrors */
struct logical_volume *log_lv;
struct lv_segment *pvmove_source_seg;
@@ -497,14 +475,13 @@ struct lv_segment {
struct lv_segment_area *meta_areas; /* For RAID */
struct logical_volume *metadata_lv; /* For thin_pool */
uint64_t transaction_id; /* For thin_pool, thin */
thin_zero_t zero_new_blocks; /* For thin_pool */
unsigned zero_new_blocks; /* For thin_pool */
thin_discards_t discards; /* For thin_pool */
struct dm_list thin_messages; /* For thin_pool */
struct logical_volume *external_lv; /* For thin */
struct logical_volume *pool_lv; /* For thin, cache */
uint32_t device_id; /* For thin, 24bit */
cache_metadata_format_t cache_metadata_format;/* For cache_pool */
cache_mode_t cache_mode; /* For cache_pool */
const char *policy_name; /* For cache_pool */
struct dm_config_node *policy_settings; /* For cache_pool */
@@ -861,22 +838,26 @@ int pool_is_active(const struct logical_volume *pool_lv);
int pool_supports_external_origin(const struct lv_segment *pool_seg, const struct logical_volume *external_lv);
int thin_pool_feature_supported(const struct logical_volume *pool_lv, int feature);
int recalculate_pool_chunk_size_with_dev_hints(struct logical_volume *pool_lv,
int passed_args,
int chunk_size_calc_policy);
int validate_cache_chunk_size(struct cmd_context *cmd, uint32_t chunk_size);
int validate_thin_pool_chunk_size(struct cmd_context *cmd, uint32_t chunk_size);
int validate_pool_chunk_size(struct cmd_context *cmd, const struct segment_type *segtype, uint32_t chunk_size);
int update_pool_lv(struct logical_volume *lv, int activate);
int get_default_allocation_thin_pool_chunk_size(struct cmd_context *cmd, struct profile *profile,
uint32_t *chunk_size, int *chunk_size_calc_method);
int update_thin_pool_params(struct cmd_context *cmd,
struct profile *profile,
uint32_t extent_size,
const struct segment_type *segtype,
unsigned attr,
uint32_t pool_data_extents,
int update_pool_params(const struct segment_type *segtype,
struct volume_group *vg, unsigned target_attr,
int passed_args, uint32_t pool_data_extents,
uint32_t *pool_metadata_extents,
int *chunk_size_calc_policy, uint32_t *chunk_size,
thin_discards_t *discards, int *zero);
int update_profilable_pool_params(struct cmd_context *cmd, struct profile *profile,
int passed_args, int *chunk_size_calc_method,
uint32_t *chunk_size, thin_discards_t *discards,
int *zero);
int update_thin_pool_params(const struct segment_type *segtype,
struct volume_group *vg, unsigned attr,
int passed_args, uint32_t pool_data_extents,
uint32_t *pool_metadata_extents,
int *chunk_size_calc_method, uint32_t *chunk_size,
thin_discards_t *discards, thin_zero_t *zero_new_blocks);
thin_discards_t *discards, int *zero);
const char *get_pool_discards_name(thin_discards_t discards);
int set_pool_discards(thin_discards_t *discards, const char *str);
struct logical_volume *alloc_pool_metadata(struct logical_volume *pool_lv,
@@ -928,8 +909,8 @@ struct lvcreate_params {
int wipe_signatures; /* all */
int32_t major; /* all */
int32_t minor; /* all */
int log_count; /* mirror/RAID */
int nosync; /* mirror/RAID */
int log_count; /* mirror */
int nosync; /* mirror */
int pool_metadata_spare; /* pools */
int type; /* type arg is given */
int temporary; /* temporary LV */
@@ -939,7 +920,6 @@ struct lvcreate_params {
int activation_skip; /* activation skip flags */
activation_change_t activate; /* non-snapshot, non-mirror */
thin_discards_t discards; /* thin */
thin_zero_t zero_new_blocks;
#define THIN_CHUNK_SIZE_CALC_METHOD_GENERIC 0x01
#define THIN_CHUNK_SIZE_CALC_METHOD_PERFORMANCE 0x02
int thin_chunk_size_calc_policy;
@@ -953,20 +933,27 @@ struct lvcreate_params {
const char *lock_args;
uint32_t stripes; /* striped/RAID */
uint32_t stripe_size; /* striped/RAID */
/* Keep args given by the user on command line */
/* FIXME: create some more universal solution here */
#define PASS_ARG_CHUNK_SIZE 0x01
#define PASS_ARG_DISCARDS 0x02
#define PASS_ARG_POOL_METADATA_SIZE 0x04
#define PASS_ARG_ZERO 0x08
int passed_args;
uint32_t stripes; /* striped */
uint32_t stripe_size; /* striped */
uint32_t chunk_size; /* snapshot */
uint32_t region_size; /* mirror/RAID */
uint32_t region_size; /* mirror */
unsigned stripes_supplied; /* striped/RAID */
unsigned stripe_size_supplied; /* striped/RAID */
unsigned stripes_supplied; /* striped */
unsigned stripe_size_supplied; /* striped */
uint32_t mirrors; /* mirror/RAID */
uint32_t mirrors; /* mirror */
uint32_t min_recovery_rate; /* RAID */
uint32_t max_recovery_rate; /* RAID */
cache_metadata_format_t cache_metadata_format; /* cache */
cache_mode_t cache_mode; /* cache */
const char *policy_name; /* cache */
struct dm_config_tree *policy_settings; /* cache */
@@ -1218,14 +1205,10 @@ struct logical_volume *first_replicator_dev(const struct logical_volume *lv);
int lv_is_raid_with_tracking(const struct logical_volume *lv);
uint32_t lv_raid_image_count(const struct logical_volume *lv);
int lv_raid_change_image_count(struct logical_volume *lv,
int yes,
uint32_t new_count,
uint32_t new_region_size,
struct dm_list *allocate_pvs);
int lv_raid_split(struct logical_volume *lv, int yes, const char *split_name,
uint32_t new_count, struct dm_list *allocate_pvs);
int lv_raid_split(struct logical_volume *lv, const char *split_name,
uint32_t new_count, struct dm_list *splittable_pvs);
int lv_raid_split_and_track(struct logical_volume *lv,
int yes,
struct dm_list *splittable_pvs);
int lv_raid_merge(struct logical_volume *lv);
int lv_raid_convert(struct logical_volume *lv,
@@ -1249,9 +1232,6 @@ uint32_t raid_rimage_extents(const struct segment_type *segtype,
uint32_t raid_ensure_min_region_size(const struct logical_volume *lv, uint64_t raid_size, uint32_t region_size);
int lv_raid_change_region_size(struct logical_volume *lv,
int yes, int force, uint32_t new_region_size);
int lv_raid_in_sync(const struct logical_volume *lv);
uint32_t lv_raid_data_copies(const struct segment_type *segtype, uint32_t area_count);
int lv_raid_free_reshape_space(const struct logical_volume *lv);
/* -- metadata/raid_manip.c */
/* ++ metadata/cache_manip.c */
@@ -1267,22 +1247,17 @@ const char *display_cache_mode(const struct lv_segment *seg);
const char *get_cache_mode_name(const struct lv_segment *cache_seg);
int set_cache_mode(cache_mode_t *mode, const char *cache_mode);
int cache_set_cache_mode(struct lv_segment *cache_seg, cache_mode_t mode);
int cache_set_metadata_format(struct lv_segment *cache_seg, cache_metadata_format_t format);
int cache_set_policy(struct lv_segment *cache_seg, const char *name,
const struct dm_config_tree *settings);
int cache_set_params(struct lv_segment *seg,
uint32_t chunk_size,
cache_metadata_format_t format,
cache_mode_t mode,
const char *policy_name,
const struct dm_config_tree *policy_settings);
const struct dm_config_tree *policy_settings,
uint32_t chunk_size);
void cache_check_for_warns(const struct lv_segment *seg);
int update_cache_pool_params(struct cmd_context *cmd,
struct profile *profile,
uint32_t extent_size,
const struct segment_type *segtype,
unsigned attr,
uint32_t pool_data_extents,
int update_cache_pool_params(const struct segment_type *segtype,
struct volume_group *vg, unsigned attr,
int passed_args, uint32_t pool_data_extents,
uint32_t *pool_metadata_extents,
int *chunk_size_calc_method, uint32_t *chunk_size);
int validate_lv_cache_chunk_size(struct logical_volume *pool_lv, uint32_t chunk_size);

View File

@@ -394,13 +394,44 @@ int validate_pool_chunk_size(struct cmd_context *cmd,
const struct segment_type *segtype,
uint32_t chunk_size)
{
if (segtype_is_cache(segtype) || segtype_is_cache_pool(segtype))
return validate_cache_chunk_size(cmd, chunk_size);
uint32_t min_size, max_size;
const char *name;
int r = 1;
return validate_thin_pool_chunk_size(cmd, chunk_size);
if (segtype_is_cache(segtype) || segtype_is_cache_pool(segtype)) {
min_size = DM_CACHE_MIN_DATA_BLOCK_SIZE;
max_size = DM_CACHE_MAX_DATA_BLOCK_SIZE;
name = "Cache";
} else if (segtype_is_thin(segtype)) {
min_size = DM_THIN_MIN_DATA_BLOCK_SIZE;
max_size = DM_THIN_MAX_DATA_BLOCK_SIZE;
name = "Thin";
} else {
log_error(INTERNAL_ERROR "Cannot validate chunk size of "
"%s segtype.", segtype->name);
return 0;
}
if ((chunk_size < min_size) || (chunk_size > max_size)) {
log_error("%s pool chunk size %s is not in the range %s to %s.",
name, display_size(cmd, chunk_size),
display_size(cmd, min_size),
display_size(cmd, max_size));
r = 0;
}
if (chunk_size & (min_size - 1)) {
log_error("%s pool chunk size %s must be a multiple of %s.",
name, display_size(cmd, chunk_size),
display_size(cmd, min_size));
r = 0;
}
return r;
}
int recalculate_pool_chunk_size_with_dev_hints(struct logical_volume *pool_lv,
int passed_args,
int chunk_size_calc_policy)
{
struct logical_volume *pool_data_lv;
@@ -408,17 +439,24 @@ int recalculate_pool_chunk_size_with_dev_hints(struct logical_volume *pool_lv,
struct physical_volume *pv;
struct cmd_context *cmd = pool_lv->vg->cmd;
unsigned long previous_hint = 0, hint = 0;
uint32_t default_chunk_size;
uint32_t min_chunk_size, max_chunk_size;
if (!chunk_size_calc_policy)
return 1; /* Chunk size was specified by user */
if (passed_args & PASS_ARG_CHUNK_SIZE)
return 1;
if (lv_is_thin_pool(pool_lv)) {
if (find_config_tree_int(cmd, allocation_thin_pool_chunk_size_CFG, NULL))
return 1;
min_chunk_size = DM_THIN_MIN_DATA_BLOCK_SIZE;
max_chunk_size = DM_THIN_MAX_DATA_BLOCK_SIZE;
default_chunk_size = get_default_allocation_thin_pool_chunk_size_CFG(cmd, NULL);
} else if (lv_is_cache_pool(pool_lv)) {
if (find_config_tree_int(cmd, allocation_cache_pool_chunk_size_CFG, NULL))
return 1;
min_chunk_size = DM_CACHE_MIN_DATA_BLOCK_SIZE;
max_chunk_size = DM_CACHE_MAX_DATA_BLOCK_SIZE;
default_chunk_size = get_default_allocation_cache_pool_chunk_size_CFG(cmd, NULL);
} else {
log_error(INTERNAL_ERROR "%s is not a pool logical volume.", display_lvname(pool_lv));
return 0;
@@ -456,14 +494,40 @@ int recalculate_pool_chunk_size_with_dev_hints(struct logical_volume *pool_lv,
display_size(cmd, hint), display_lvname(pool_lv),
display_size(cmd, min_chunk_size),
display_size(cmd, max_chunk_size));
else if (hint > first_seg(pool_lv)->chunk_size) {
log_debug_alloc("Updating chunk size %s for pool %s to %s.",
display_size(cmd, first_seg(pool_lv)->chunk_size),
display_lvname(pool_lv),
display_size(cmd, hint));
first_seg(pool_lv)->chunk_size = hint;
else
first_seg(pool_lv)->chunk_size =
(hint >= default_chunk_size) ? hint : default_chunk_size;
return 1;
}
int update_pool_params(const struct segment_type *segtype,
struct volume_group *vg, unsigned target_attr,
int passed_args, uint32_t pool_data_extents,
uint32_t *pool_metadata_extents,
int *chunk_size_calc_policy, uint32_t *chunk_size,
thin_discards_t *discards, int *zero)
{
if (segtype_is_cache_pool(segtype) || segtype_is_cache(segtype)) {
if (!update_cache_pool_params(segtype, vg, target_attr, passed_args,
pool_data_extents, pool_metadata_extents,
chunk_size_calc_policy, chunk_size))
return_0;
} else if (!update_thin_pool_params(segtype, vg, target_attr, passed_args,
pool_data_extents, pool_metadata_extents,
chunk_size_calc_policy, chunk_size,
discards, zero)) /* thin-pool */
return_0;
if ((uint64_t) *chunk_size > (uint64_t) pool_data_extents * vg->extent_size) {
log_error("Size of %s data volume cannot be smaller than chunk size %s.",
segtype->name, display_size(vg->cmd, *chunk_size));
return 0;
}
log_verbose("Preferred pool metadata size %s.",
display_size(vg->cmd, (uint64_t)*pool_metadata_extents * vg->extent_size));
return 1;
}

File diff suppressed because it is too large Load Diff

View File

@@ -43,8 +43,7 @@ struct segment_type *get_segtype_from_flag(struct cmd_context *cmd, uint64_t fla
{
struct segment_type *segtype;
/* Iterate backwards to provide aliases; e.g. raid5 instead of raid5_ls */
dm_list_iterate_back_items(segtype, &cmd->segtypes)
dm_list_iterate_items(segtype, &cmd->segtypes)
if (flag & segtype->flags)
return segtype;

View File

@@ -140,11 +140,7 @@ struct dev_manager;
#define segtype_is_any_raid10(segtype) ((segtype)->flags & SEG_RAID10 ? 1 : 0)
#define segtype_is_raid10(segtype) ((segtype)->flags & SEG_RAID10 ? 1 : 0)
#define segtype_is_raid10_near(segtype) segtype_is_raid10(segtype)
/* FIXME: once raid10_offset supported */
#define segtype_is_raid10_offset(segtype) 0 // ((segtype)->flags & SEG_RAID10_OFFSET ? 1 : 0)
#define segtype_is_raid_with_meta(segtype) (segtype_is_raid(segtype) && !segtype_is_raid0(segtype))
#define segtype_is_striped_raid(segtype) (segtype_is_raid(segtype) && !segtype_is_raid1(segtype))
#define segtype_is_reshapable_raid(segtype) ((segtype_is_striped_raid(segtype) && !segtype_is_any_raid0(segtype)) || segtype_is_raid10_near(segtype) || segtype_is_raid10_offset(segtype))
#define segtype_is_snapshot(segtype) ((segtype)->flags & SEG_SNAPSHOT ? 1 : 0)
#define segtype_is_striped(segtype) ((segtype)->flags & SEG_AREAS_STRIPED ? 1 : 0)
#define segtype_is_thin(segtype) ((segtype)->flags & (SEG_THIN_POOL|SEG_THIN_VOLUME) ? 1 : 0)
@@ -194,8 +190,6 @@ struct dev_manager;
#define seg_is_raid10(seg) segtype_is_raid10((seg)->segtype)
#define seg_is_raid10_near(seg) segtype_is_raid10_near((seg)->segtype)
#define seg_is_raid_with_meta(seg) segtype_is_raid_with_meta((seg)->segtype)
#define seg_is_striped_raid(seg) segtype_is_striped_raid((seg)->segtype)
#define seg_is_reshapable_raid(seg) segtype_is_reshapable_raid((seg)->segtype)
#define seg_is_replicator(seg) ((seg)->segtype->flags & SEG_REPLICATOR ? 1 : 0)
#define seg_is_replicator_dev(seg) ((seg)->segtype->flags & SEG_REPLICATOR_DEV ? 1 : 0)
#define seg_is_snapshot(seg) segtype_is_snapshot((seg)->segtype)
@@ -286,7 +280,6 @@ struct segment_type *init_unknown_segtype(struct cmd_context *cmd,
#define RAID_FEATURE_RAID0 (1U << 1) /* version 1.7 */
#define RAID_FEATURE_RESHAPING (1U << 2) /* version 1.8 */
#define RAID_FEATURE_RAID4 (1U << 3) /* ! version 1.8 or 1.9.0 */
#define RAID_FEATURE_RESHAPE (1U << 4) /* version 1.10.1 */
#ifdef RAID_INTERNAL
int init_raid_segtypes(struct cmd_context *cmd, struct segtype_library *seglib);
@@ -315,7 +308,6 @@ int init_cache_segtypes(struct cmd_context *cmd, struct segtype_library *seglib)
#define CACHE_FEATURE_POLICY_MQ (1U << 0)
#define CACHE_FEATURE_POLICY_SMQ (1U << 1)
#define CACHE_FEATURE_METADATA2 (1U << 2)
#define SNAPSHOT_FEATURE_FIXED_LEAK (1U << 0) /* version 1.12 */

View File

@@ -238,8 +238,8 @@ static struct lv_segment *_alloc_snapshot_seg(struct logical_volume *lv)
return NULL;
}
if (!(seg = alloc_lv_segment(segtype, lv, 0, lv->le_count, 0, 0, 0,
NULL, 0, lv->le_count, 0, 0, 0, 0, NULL))) {
if (!(seg = alloc_lv_segment(segtype, lv, 0, lv->le_count, 0, 0,
NULL, 0, lv->le_count, 0, 0, 0, NULL))) {
log_error("Couldn't allocate new snapshot segment.");
return NULL;
}

View File

@@ -58,13 +58,13 @@
#define r1__r0m _takeover_from_raid1_to_raid0_meta
#define r1__r1 _takeover_from_raid1_to_raid1
#define r1__r10 _takeover_from_raid1_to_raid10
#define r1__r5 _takeover_from_raid1_to_raid5
#define r1__r45 _takeover_from_raid1_to_raid45
#define r1__str _takeover_from_raid1_to_striped
#define r45_lin _takeover_from_raid45_to_linear
#define r45_mir _takeover_from_raid45_to_mirrored
#define r45_r0 _takeover_from_raid45_to_raid0
#define r45_r0m _takeover_from_raid45_to_raid0_meta
#define r5_r1 _takeover_from_raid5_to_raid1
#define r45_r1 _takeover_from_raid45_to_raid1
#define r45_r54 _takeover_from_raid45_to_raid54
#define r45_r6 _takeover_from_raid45_to_raid6
#define r45_str _takeover_from_raid45_to_striped
@@ -109,8 +109,8 @@ static takeover_fn_t _takeover_fns[][11] = {
/* mirror */ { X , X , N , mir_r0, mir_r0m, mir_r1, mir_r45, X , mir_r10, X , X },
/* raid0 */ { r0__lin, r0__str, r0__mir, N , r0__r0m, r0__r1, r0__r45, r0__r6, r0__r10, X , X },
/* raid0_meta */ { r0m_lin, r0m_str, r0m_mir, r0m_r0, N , r0m_r1, r0m_r45, r0m_r6, r0m_r10, X , X },
/* raid1 */ { r1__lin, r1__str, r1__mir, r1__r0, r1__r0m, r1__r1, r1__r5, X , r1__r10, X , X },
/* raid4/5 */ { r45_lin, r45_str, r45_mir, r45_r0, r45_r0m, r5_r1 , r45_r54, r45_r6, X , X , X },
/* raid1 */ { r1__lin, r1__str, r1__mir, r1__r0, r1__r0m, r1__r1, r1__r45, X , r1__r10, X , X },
/* raid4/5 */ { r45_lin, r45_str, r45_mir, r45_r0, r45_r0m, r45_r1, r45_r54, r45_r6, X , X , X },
/* raid6 */ { X , r6__str, X , r6__r0, r6__r0m, X , r6__r45, X , X , X , X },
/* raid10 */ { r10_lin, r10_str, r10_mir, r10_r0, r10_r0m, r10_r1, X , X , X , X , X },
/* raid01 */ // { X , r01_str, X , X , X , X , X , X , r01_r10, r01_r01, X },

View File

@@ -547,31 +547,19 @@ int update_pool_lv(struct logical_volume *lv, int activate)
return ret;
}
static uint64_t _estimate_size(uint32_t data_extents, uint32_t extent_size, uint64_t size)
/* Estimate thin pool chunk size from data and metadata size (in sector units) */
static size_t _estimate_chunk_size(uint64_t data_size, uint64_t metadata_size, int attr)
{
/*
* nr_pool_blocks = data_size / metadata_size
* chunk_size = nr_pool_blocks * 64b / sector_size
*/
return (uint64_t) data_extents * extent_size / (size * (SECTOR_SIZE / UINT64_C(64)));
}
/* Estimate thin pool metadata size from data size and chunks size (in sector units) */
static uint64_t _estimate_metadata_size(uint32_t data_extents, uint32_t extent_size, uint32_t chunk_size)
{
return _estimate_size(data_extents, extent_size, chunk_size);
}
/* Estimate thin pool chunk size from data and metadata size (in sector units) */
static uint32_t _estimate_chunk_size(uint32_t data_extents, uint32_t extent_size,
uint64_t metadata_size, int attr)
{
uint32_t chunk_size = _estimate_size(data_extents, extent_size, metadata_size);
size_t chunk_size = data_size / (metadata_size * (SECTOR_SIZE / 64));
if (attr & THIN_FEATURE_BLOCK_SIZE) {
/* Round up to 64KB */
chunk_size += DM_THIN_MIN_DATA_BLOCK_SIZE - 1;
chunk_size &= ~(uint32_t)(DM_THIN_MIN_DATA_BLOCK_SIZE - 1);
chunk_size &= ~(size_t)(DM_THIN_MIN_DATA_BLOCK_SIZE - 1);
} else {
/* Round up to nearest power of 2 */
chunk_size--;
@@ -583,64 +571,47 @@ static uint32_t _estimate_chunk_size(uint32_t data_extents, uint32_t extent_size
chunk_size++;
}
if (chunk_size < DM_THIN_MIN_DATA_BLOCK_SIZE)
chunk_size = DM_THIN_MIN_DATA_BLOCK_SIZE;
else if (chunk_size > DM_THIN_MAX_DATA_BLOCK_SIZE)
chunk_size = DM_THIN_MAX_DATA_BLOCK_SIZE;
return chunk_size;
}
int get_default_allocation_thin_pool_chunk_size(struct cmd_context *cmd, struct profile *profile,
uint32_t *chunk_size, int *chunk_size_calc_method)
{
const char *str;
if (!(str = find_config_tree_str(cmd, allocation_thin_pool_chunk_size_policy_CFG, profile))) {
log_error(INTERNAL_ERROR "Cannot find configuration.");
return 0;
}
if (!strcasecmp(str, "generic")) {
*chunk_size = DEFAULT_THIN_POOL_CHUNK_SIZE * 2;
*chunk_size_calc_method = THIN_CHUNK_SIZE_CALC_METHOD_GENERIC;
} else if (!strcasecmp(str, "performance")) {
*chunk_size = DEFAULT_THIN_POOL_CHUNK_SIZE_PERFORMANCE * 2;
*chunk_size_calc_method = THIN_CHUNK_SIZE_CALC_METHOD_PERFORMANCE;
} else {
log_error("Thin pool chunk size calculation policy \"%s\" is unrecognised.", str);
return 0;
}
return 1;
}
int update_thin_pool_params(struct cmd_context *cmd,
struct profile *profile,
uint32_t extent_size,
const struct segment_type *segtype,
unsigned attr,
int update_thin_pool_params(const struct segment_type *segtype,
struct volume_group *vg,
unsigned attr, int passed_args,
uint32_t pool_data_extents,
uint32_t *pool_metadata_extents,
int *chunk_size_calc_method, uint32_t *chunk_size,
thin_discards_t *discards, thin_zero_t *zero_new_blocks)
thin_discards_t *discards, int *zero)
{
struct cmd_context *cmd = vg->cmd;
struct profile *profile = vg->profile;
uint32_t extent_size = vg->extent_size;
uint64_t pool_metadata_size = (uint64_t) *pool_metadata_extents * extent_size;
uint32_t estimate_chunk_size;
size_t estimate_chunk_size;
const char *str;
if (!*chunk_size &&
find_config_tree_node(cmd, allocation_thin_pool_chunk_size_CFG, profile))
*chunk_size = find_config_tree_int(cmd, allocation_thin_pool_chunk_size_CFG, profile) * 2;
if (*chunk_size && !(attr & THIN_FEATURE_BLOCK_SIZE) &&
!is_power_of_2(*chunk_size)) {
log_error("Chunk size must be a power of 2 for this thin target version.");
return 0;
if (!(passed_args & PASS_ARG_CHUNK_SIZE)) {
if (!(*chunk_size = find_config_tree_int(cmd, allocation_thin_pool_chunk_size_CFG, profile) * 2)) {
if (!(str = find_config_tree_str(cmd, allocation_thin_pool_chunk_size_policy_CFG, profile))) {
log_error(INTERNAL_ERROR "Could not find configuration.");
return 0;
}
if (!strcasecmp(str, "generic"))
*chunk_size_calc_method = THIN_CHUNK_SIZE_CALC_METHOD_GENERIC;
else if (!strcasecmp(str, "performance"))
*chunk_size_calc_method = THIN_CHUNK_SIZE_CALC_METHOD_PERFORMANCE;
else {
log_error("Thin pool chunk size calculation policy \"%s\" is unrecognised.", str);
return 0;
}
if (!(*chunk_size = get_default_allocation_thin_pool_chunk_size_CFG(cmd, profile)))
return_0;
}
}
if ((*discards == THIN_DISCARDS_UNSELECTED) &&
find_config_tree_node(cmd, allocation_thin_pool_discards_CFG, profile)) {
if (!validate_pool_chunk_size(cmd, segtype, *chunk_size))
return_0;
if (!(passed_args & PASS_ARG_DISCARDS)) {
if (!(str = find_config_tree_str(cmd, allocation_thin_pool_discards_CFG, profile))) {
log_error(INTERNAL_ERROR "Could not find configuration.");
return 0;
@@ -649,21 +620,21 @@ int update_thin_pool_params(struct cmd_context *cmd,
return_0;
}
if ((*zero_new_blocks == THIN_ZERO_UNSELECTED) &&
find_config_tree_node(cmd, allocation_thin_pool_zero_CFG, profile))
*zero_new_blocks = find_config_tree_bool(cmd, allocation_thin_pool_zero_CFG, profile)
? THIN_ZERO_YES : THIN_ZERO_NO;
if (!(passed_args & PASS_ARG_ZERO))
*zero = find_config_tree_bool(cmd, allocation_thin_pool_zero_CFG, profile);
if (!(attr & THIN_FEATURE_BLOCK_SIZE) &&
!is_power_of_2(*chunk_size)) {
log_error("Chunk size must be a power of 2 for this thin target version.");
return 0;
}
if (!pool_metadata_size) {
if (!*chunk_size) {
if (!get_default_allocation_thin_pool_chunk_size(cmd, profile,
chunk_size,
chunk_size_calc_method))
return_0;
pool_metadata_size = _estimate_metadata_size(pool_data_extents, extent_size, *chunk_size);
/* Check if we should eventually use bigger chunk size */
/* Defaults to nr_pool_blocks * 64b converted to size in sectors */
pool_metadata_size = (uint64_t) pool_data_extents * extent_size /
(*chunk_size * (SECTOR_SIZE / UINT64_C(64)));
/* Check if we could eventually use bigger chunk size */
if (!(passed_args & PASS_ARG_CHUNK_SIZE)) {
while ((pool_metadata_size >
(DEFAULT_THIN_POOL_OPTIMAL_SIZE / SECTOR_SIZE)) &&
(*chunk_size < DM_THIN_MAX_DATA_BLOCK_SIZE)) {
@@ -672,28 +643,29 @@ int update_thin_pool_params(struct cmd_context *cmd,
}
log_verbose("Setting chunk size to %s.",
display_size(cmd, *chunk_size));
} else {
pool_metadata_size = _estimate_metadata_size(pool_data_extents, extent_size, *chunk_size);
if (pool_metadata_size > (DEFAULT_THIN_POOL_MAX_METADATA_SIZE * 2)) {
/* Suggest bigger chunk size */
estimate_chunk_size =
_estimate_chunk_size(pool_data_extents, extent_size,
(DEFAULT_THIN_POOL_MAX_METADATA_SIZE * 2), attr);
log_warn("WARNING: Chunk size is too small for pool, suggested minimum is %s.",
display_size(cmd, estimate_chunk_size));
}
} else if (pool_metadata_size > (DEFAULT_THIN_POOL_MAX_METADATA_SIZE * 2)) {
/* Suggest bigger chunk size */
estimate_chunk_size =
_estimate_chunk_size((uint64_t) pool_data_extents * extent_size,
(DEFAULT_THIN_POOL_MAX_METADATA_SIZE * 2), attr);
log_warn("WARNING: Chunk size is too small for pool, suggested minimum is %s.",
display_size(cmd, estimate_chunk_size));
}
/* Round up to extent size silently */
if (pool_metadata_size % extent_size)
pool_metadata_size += extent_size - pool_metadata_size % extent_size;
} else {
estimate_chunk_size = _estimate_chunk_size(pool_data_extents, extent_size,
pool_metadata_size, attr);
estimate_chunk_size =
_estimate_chunk_size((uint64_t) pool_data_extents * extent_size,
pool_metadata_size, attr);
if (estimate_chunk_size < DM_THIN_MIN_DATA_BLOCK_SIZE)
estimate_chunk_size = DM_THIN_MIN_DATA_BLOCK_SIZE;
else if (estimate_chunk_size > DM_THIN_MAX_DATA_BLOCK_SIZE)
estimate_chunk_size = DM_THIN_MAX_DATA_BLOCK_SIZE;
/* Check to eventually use bigger chunk size */
if (!*chunk_size) {
if (!(passed_args & PASS_ARG_CHUNK_SIZE)) {
*chunk_size = estimate_chunk_size;
log_verbose("Setting chunk size %s.", display_size(cmd, *chunk_size));
} else if (*chunk_size < estimate_chunk_size) {
@@ -703,41 +675,22 @@ int update_thin_pool_params(struct cmd_context *cmd,
}
}
if (!validate_thin_pool_chunk_size(cmd, *chunk_size))
return_0;
if (pool_metadata_size > (2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE)) {
pool_metadata_size = 2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE;
if (*pool_metadata_extents)
if (passed_args & PASS_ARG_POOL_METADATA_SIZE)
log_warn("WARNING: Maximum supported pool metadata size is %s.",
display_size(cmd, pool_metadata_size));
} else if (pool_metadata_size < (2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE)) {
pool_metadata_size = 2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE;
if (*pool_metadata_extents)
if (passed_args & PASS_ARG_POOL_METADATA_SIZE)
log_warn("WARNING: Minimum supported pool metadata size is %s.",
display_size(cmd, pool_metadata_size));
}
if (!(*pool_metadata_extents =
extents_from_size(cmd, pool_metadata_size, extent_size)))
extents_from_size(vg->cmd, pool_metadata_size, extent_size)))
return_0;
if ((uint64_t) *chunk_size > (uint64_t) pool_data_extents * extent_size) {
log_error("Size of %s data volume cannot be smaller than chunk size %s.",
segtype->name, display_size(cmd, *chunk_size));
return 0;
}
if ((*discards == THIN_DISCARDS_UNSELECTED) &&
!set_pool_discards(discards, DEFAULT_THIN_POOL_DISCARDS))
return_0;
if (*zero_new_blocks == THIN_ZERO_UNSELECTED)
*zero_new_blocks = (DEFAULT_THIN_POOL_ZERO) ? THIN_ZERO_YES : THIN_ZERO_NO;
log_verbose("Preferred pool metadata size %s.",
display_size(cmd, (uint64_t)*pool_metadata_extents * extent_size));
return 1;
}
@@ -766,10 +719,11 @@ const char *get_pool_discards_name(thin_discards_t discards)
return "nopassdown";
case THIN_DISCARDS_IGNORE:
return "ignore";
default:
log_error(INTERNAL_ERROR "Unknown discards type encountered.");
return "unknown";
}
log_error(INTERNAL_ERROR "Unknown discards type encountered.");
return "unknown";
}
int lv_is_thin_origin(const struct logical_volume *lv, unsigned int *snap_count)
@@ -780,16 +734,20 @@ int lv_is_thin_origin(const struct logical_volume *lv, unsigned int *snap_count)
if (snap_count)
*snap_count = 0;
if (lv_is_thin_volume(lv))
dm_list_iterate_items(segl, &lv->segs_using_this_lv)
if (segl->seg->origin == lv) {
r = 1;
if (!snap_count)
break;/* not interested in number of snapshots */
if (!lv_is_thin_volume(lv) ||
dm_list_empty(&lv->segs_using_this_lv))
return 0;
dm_list_iterate_items(segl, &lv->segs_using_this_lv) {
if (segl->seg->origin == lv) {
r = 1;
if (snap_count)
(*snap_count)++;
}
else
/* not interested in number of snapshots */
break;
}
}
return r;
}
@@ -858,27 +816,3 @@ int check_new_thin_pool(const struct logical_volume *pool_lv)
return 1;
}
int validate_thin_pool_chunk_size(struct cmd_context *cmd, uint32_t chunk_size)
{
const uint32_t min_size = DM_THIN_MIN_DATA_BLOCK_SIZE;
const uint32_t max_size = DM_THIN_MAX_DATA_BLOCK_SIZE;
int r = 1;
if ((chunk_size < min_size) || (chunk_size > max_size)) {
log_error("Thin pool chunk size %s is not in the range %s to %s.",
display_size(cmd, chunk_size),
display_size(cmd, min_size),
display_size(cmd, max_size));
r = 0;
}
if (chunk_size & (min_size - 1)) {
log_error("Thin pool chunk size %s must be a multiple of %s.",
display_size(cmd, chunk_size),
display_size(cmd, min_size));
r = 0;
}
return r;
}

View File

@@ -137,7 +137,6 @@ static int _raid_text_import(struct lv_segment *seg,
} raid_attr_import[] = {
{ "region_size", &seg->region_size },
{ "stripe_size", &seg->stripe_size },
{ "data_copies", &seg->data_copies },
{ "writebehind", &seg->writebehind },
{ "min_recovery_rate", &seg->min_recovery_rate },
{ "max_recovery_rate", &seg->max_recovery_rate },
@@ -147,10 +146,6 @@ static int _raid_text_import(struct lv_segment *seg,
for (i = 0; i < DM_ARRAY_SIZE(raid_attr_import); i++, aip++) {
if (dm_config_has_node(sn, aip->name)) {
if (!dm_config_get_uint32(sn, aip->name, aip->var)) {
if (!strcmp(aip->name, "data_copies")) {
*aip->var = 0;
continue;
}
log_error("Couldn't read '%s' for segment %s of logical volume %s.",
aip->name, dm_config_parent_name(sn), seg->lv->name);
return 0;
@@ -170,9 +165,6 @@ static int _raid_text_import(struct lv_segment *seg,
return 0;
}
if (seg->data_copies < 2)
seg->data_copies = lv_raid_data_copies(seg->segtype, seg->area_count);
if (seg_is_any_raid0(seg))
seg->area_len /= seg->area_count;
@@ -191,31 +183,18 @@ static int _raid_text_export_raid0(const struct lv_segment *seg, struct formatte
static int _raid_text_export_raid(const struct lv_segment *seg, struct formatter *f)
{
int raid0 = seg_is_any_raid0(seg);
if (raid0)
outfc(f, (seg->area_count == 1) ? "# linear" : NULL,
"stripe_count = %u", seg->area_count);
else {
outf(f, "device_count = %u", seg->area_count);
if (seg_is_any_raid10(seg) && seg->data_copies > 0)
outf(f, "data_copies = %" PRIu32, seg->data_copies);
if (seg->region_size)
outf(f, "region_size = %" PRIu32, seg->region_size);
}
outf(f, "device_count = %u", seg->area_count);
if (seg->stripe_size)
outf(f, "stripe_size = %" PRIu32, seg->stripe_size);
if (!raid0) {
if (seg_is_raid1(seg) && seg->writebehind)
outf(f, "writebehind = %" PRIu32, seg->writebehind);
if (seg->min_recovery_rate)
outf(f, "min_recovery_rate = %" PRIu32, seg->min_recovery_rate);
if (seg->max_recovery_rate)
outf(f, "max_recovery_rate = %" PRIu32, seg->max_recovery_rate);
}
if (seg->region_size)
outf(f, "region_size = %" PRIu32, seg->region_size);
if (seg->writebehind)
outf(f, "writebehind = %" PRIu32, seg->writebehind);
if (seg->min_recovery_rate)
outf(f, "min_recovery_rate = %" PRIu32, seg->min_recovery_rate);
if (seg->max_recovery_rate)
outf(f, "max_recovery_rate = %" PRIu32, seg->max_recovery_rate);
return out_areas(f, seg, "raid");
}
@@ -237,16 +216,14 @@ static int _raid_add_target_line(struct dev_manager *dm __attribute__((unused)),
struct dm_tree_node *node, uint64_t len,
uint32_t *pvmove_mirror_count __attribute__((unused)))
{
int delta_disks = 0, delta_disks_minus = 0, delta_disks_plus = 0, data_offset = 0;
uint32_t s;
uint64_t flags = 0;
uint64_t rebuilds[RAID_BITMAP_SIZE];
uint64_t writemostly[RAID_BITMAP_SIZE];
struct dm_tree_node_raid_params_v2 params;
uint64_t rebuilds = 0;
uint64_t writemostly = 0;
struct dm_tree_node_raid_params params;
int raid0 = seg_is_any_raid0(seg);
memset(&params, 0, sizeof(params));
memset(&rebuilds, 0, sizeof(rebuilds));
memset(&writemostly, 0, sizeof(writemostly));
if (!seg->area_count) {
log_error(INTERNAL_ERROR "_raid_add_target_line called "
@@ -255,85 +232,64 @@ static int _raid_add_target_line(struct dev_manager *dm __attribute__((unused)),
}
/*
* 253 device restriction imposed by kernel due to MD and dm-raid bitfield limitation in superblock.
* It is not strictly a userspace limitation.
* 64 device restriction imposed by kernel as well. It is
* not strictly a userspace limitation.
*/
if (seg->area_count > DEFAULT_RAID_MAX_IMAGES) {
log_error("Unable to handle more than %u devices in a "
"single RAID array", DEFAULT_RAID_MAX_IMAGES);
if (seg->area_count > 64) {
log_error("Unable to handle more than 64 devices in a "
"single RAID array");
return 0;
}
if (!seg_is_any_raid0(seg)) {
if (!raid0) {
if (!seg->region_size) {
log_error("Missing region size for raid segment in %s.",
seg_lv(seg, 0)->name);
log_error("Missing region size for mirror segment.");
return 0;
}
for (s = 0; s < seg->area_count; s++) {
uint64_t status = seg_lv(seg, s)->status;
for (s = 0; s < seg->area_count; s++)
if (seg_lv(seg, s)->status & LV_REBUILD)
rebuilds |= 1ULL << s;
if (status & LV_REBUILD)
rebuilds[s/64] |= 1ULL << (s%64);
if (status & LV_RESHAPE_DELTA_DISKS_PLUS) {
delta_disks++;
delta_disks_plus++;
} else if (status & LV_RESHAPE_DELTA_DISKS_MINUS) {
delta_disks--;
delta_disks_minus++;
}
if (delta_disks_plus && delta_disks_minus) {
log_error(INTERNAL_ERROR "Invalid request for delta disks minus and delta disks plus!");
return 0;
}
if (status & LV_WRITEMOSTLY)
writemostly[s/64] |= 1ULL << (s%64);
}
data_offset = seg->data_offset;
for (s = 0; s < seg->area_count; s++)
if (seg_lv(seg, s)->status & LV_WRITEMOSTLY)
writemostly |= 1ULL << s;
if (mirror_in_sync())
flags = DM_NOSYNC;
}
params.raid_type = lvseg_name(seg);
if (seg->segtype->parity_devs) {
/* RAID 4/5/6 */
params.mirrors = 1;
params.stripes = seg->area_count - seg->segtype->parity_devs;
} else if (seg_is_any_raid0(seg)) {
params.mirrors = 1;
params.stripes = seg->area_count;
} else if (seg_is_any_raid10(seg)) {
params.data_copies = seg->data_copies;
params.stripes = seg->area_count;
} else {
/* RAID 1 */
params.mirrors = seg->data_copies;
params.stripes = 1;
params.writebehind = seg->writebehind;
memcpy(params.writemostly, writemostly, sizeof(params.writemostly));
}
/* RAID 0 doesn't have a bitmap, thus no region_size, rebuilds etc. */
if (!seg_is_any_raid0(seg)) {
params.region_size = seg->region_size;
memcpy(params.rebuilds, rebuilds, sizeof(params.rebuilds));
params.min_recovery_rate = seg->min_recovery_rate;
params.max_recovery_rate = seg->max_recovery_rate;
params.delta_disks = delta_disks;
params.data_offset = data_offset;
}
params.stripe_size = seg->stripe_size;
params.flags = flags;
if (!dm_tree_node_add_raid_target_with_params_v2(node, len, &params))
if (raid0) {
params.mirrors = 1;
params.stripes = seg->area_count;
} else if (seg->segtype->parity_devs) {
/* RAID 4/5/6 */
params.mirrors = 1;
params.stripes = seg->area_count - seg->segtype->parity_devs;
} else if (seg_is_raid10(seg)) {
/* RAID 10 only supports 2 mirrors now */
params.mirrors = 2;
params.stripes = seg->area_count / 2;
} else {
/* RAID 1 */
params.mirrors = seg->area_count;
params.stripes = 1;
params.writebehind = seg->writebehind;
}
if (!raid0) {
params.region_size = seg->region_size;
params.rebuilds = rebuilds;
params.writemostly = writemostly;
params.min_recovery_rate = seg->min_recovery_rate;
params.max_recovery_rate = seg->max_recovery_rate;
}
if (!dm_tree_node_add_raid_target_with_params(node, len, &params))
return_0;
return add_areas_line(dm, seg, node, 0u, seg->area_count);
@@ -448,32 +404,19 @@ out:
return r;
}
/* Define raid feature based on the tuple(major, minor, patchlevel) of raid target */
struct raid_feature {
uint32_t maj;
uint32_t min;
uint32_t patchlevel;
unsigned raid_feature;
const char *feature;
};
/* Return true if tuple(@maj, @min, @patchlevel) is greater/equal to @*feature members */
static int _check_feature(const struct raid_feature *feature, uint32_t maj, uint32_t min, uint32_t patchlevel)
{
return (maj > feature->maj) ||
(maj == feature->maj && min >= feature->min) ||
(maj == feature->maj && min == feature->min && patchlevel >= feature->patchlevel);
}
static int _raid_target_present(struct cmd_context *cmd,
const struct lv_segment *seg __attribute__((unused)),
unsigned *attributes)
{
/* List of features with their kernel target version */
const struct raid_feature _features[] = {
{ 1, 3, 0, RAID_FEATURE_RAID10, SEG_TYPE_NAME_RAID10 },
{ 1, 7, 0, RAID_FEATURE_RAID0, SEG_TYPE_NAME_RAID0 },
{ 1, 10, 1, RAID_FEATURE_RESHAPE, "reshaping" },
static const struct feature {
uint32_t maj;
uint32_t min;
unsigned raid_feature;
const char *feature;
} _features[] = {
{ 1, 3, RAID_FEATURE_RAID10, SEG_TYPE_NAME_RAID10 },
{ 1, 7, RAID_FEATURE_RAID0, SEG_TYPE_NAME_RAID0 },
};
static int _raid_checked = 0;
@@ -495,19 +438,13 @@ static int _raid_target_present(struct cmd_context *cmd,
return_0;
for (i = 0; i < DM_ARRAY_SIZE(_features); ++i)
if (_check_feature(_features + i, maj, min, patchlevel))
if ((maj > _features[i].maj) ||
(maj == _features[i].maj && min >= _features[i].min))
_raid_attrs |= _features[i].raid_feature;
else
log_very_verbose("Target raid does not support %s.",
_features[i].feature);
/*
* Seperate check for proper raid4 mapping supported
*
* If we get more of these range checks, avoid them
* altogether by enhancing 'struct raid_feature'
* and _check_feature() to handle them.
*/
if (!(maj == 1 && (min == 8 || (min == 9 && patchlevel == 0))))
_raid_attrs |= RAID_FEATURE_RAID4;
else

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2017 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004-2013 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -69,7 +69,7 @@ FIELD(LVS, lv, BIN, "ActExcl", lvid, 10, lvactiveexclusively, lv_active_exclusiv
FIELD(LVS, lv, SNUM, "Maj", major, 0, int32, lv_major, "Persistent major number or -1 if not persistent.", 0)
FIELD(LVS, lv, SNUM, "Min", minor, 0, int32, lv_minor, "Persistent minor number or -1 if not persistent.", 0)
FIELD(LVS, lv, SIZ, "Rahead", lvid, 0, lvreadahead, lv_read_ahead, "Read ahead setting in current units.", 0)
FIELD(LVS, lv, SIZ, "LSize", lvid, 0, lv_size, lv_size, "Size of LV in current units.", 0)
FIELD(LVS, lv, SIZ, "LSize", size, 0, size64, lv_size, "Size of LV in current units.", 0)
FIELD(LVS, lv, SIZ, "MSize", lvid, 0, lvmetadatasize, lv_metadata_size, "For thin and cache pools, the size of the LV that holds the metadata.", 0)
FIELD(LVS, lv, NUM, "#Seg", lvid, 0, lvsegcount, seg_count, "Number of segments in LV.", 0)
FIELD(LVS, lv, STR, "Origin", lvid, 0, origin, origin, "For snapshots and thins, the origin device of this LV.", 0)
@@ -140,7 +140,6 @@ FIELD(LVSSTATUS, lv, NUM, "CacheWriteHits", lvid, 16, cache_write_hits, cache_wr
FIELD(LVSSTATUS, lv, NUM, "CacheWriteMisses", lvid, 0, cache_write_misses, cache_write_misses, "Cache write misses.", 0)
FIELD(LVSSTATUS, lv, STR_LIST, "KCacheSettings", lvid, 18, kernel_cache_settings, kernel_cache_settings, "Cache settings/parameters as set in kernel, including default values (cached segments only).", 0)
FIELD(LVSSTATUS, lv, STR, "KCachePolicy", lvid, 18, kernel_cache_policy, kernel_cache_policy, "Cache policy used in kernel.", 0)
FIELD(LVSSTATUS, lv, NUM, "KMFmt", lvid, 0, kernelmetadataformat, kernel_metadata_format, "Cache metadata format used in kernel.", 0)
FIELD(LVSSTATUS, lv, STR, "Health", lvid, 15, lvhealthstatus, lv_health_status, "LV health status.", 0)
FIELD(LVSSTATUS, lv, STR, "KDiscards", lvid, 0, kdiscards, kernel_discards, "For thin pools, how discards are handled in kernel.", 0)
FIELD(LVSSTATUS, lv, BIN, "CheckNeeded", lvid, 15, lvcheckneeded, lv_check_needed, "For thin pools and cache volumes, whether metadata check is needed.", 0)
@@ -242,21 +241,13 @@ FIELD(VGS, vg, NUM, "#VMdaCps", cmd, 0, vgmdacopies, vg_mda_copies, "Target numb
* SEGS type fields
*/
FIELD(SEGS, seg, STR, "Type", list, 0, segtype, segtype, "Type of LV segment.", 0)
FIELD(SEGS, seg, NUM, "#Str", list, 0, seg_stripes, stripes, "Number of stripes or mirror/raid1 legs.", 0)
FIELD(SEGS, seg, NUM, "#DStr", list, 0, seg_data_stripes, data_stripes, "Number of data stripes or mirror/raid1 legs.", 0)
FIELD(SEGS, seg, SIZ, "RSize", list, 0, seg_reshape_len, reshape_len, "Size of out-of-place reshape space in current units.", 0)
FIELD(SEGS, seg, NUM, "RSize", list, 0, seg_reshape_len_le, reshape_len_le, "Size of out-of-place reshape space in logical extents.", 0)
FIELD(SEGS, seg, NUM, "#Cpy", list, 0, seg_data_copies, data_copies, "Number of data copies.", 0)
FIELD(SEGS, seg, NUM, "DOff", list, 0, seg_data_offset, data_offset, "Data offset on each image device.", 0)
FIELD(SEGS, seg, NUM, "NOff", list, 0, seg_new_data_offset, new_data_offset, "New data offset after any reshape on each image device.", 0)
FIELD(SEGS, seg, NUM, "#Par", list, 0, seg_parity_chunks, parity_chunks, "Number of (rotating) parity chunks.", 0)
FIELD(SEGS, seg, NUM, "#Str", area_count, 0, uint32, stripes, "Number of stripes or mirror legs.", 0)
FIELD(SEGS, seg, SIZ, "Stripe", stripe_size, 0, size32, stripe_size, "For stripes, amount of data placed on one device before switching to the next.", 0)
FIELD(SEGS, seg, SIZ, "Region", region_size, 0, size32, region_size, "For mirrors/raids, the unit of data per leg when synchronizing devices.", 0)
FIELD(SEGS, seg, SIZ, "Region", region_size, 0, size32, region_size, "For mirrors, the unit of data copied when synchronising devices.", 0)
FIELD(SEGS, seg, SIZ, "Chunk", list, 0, chunksize, chunk_size, "For snapshots, the unit of data used when tracking changes.", 0)
FIELD(SEGS, seg, NUM, "#Thins", list, 0, thincount, thin_count, "For thin pools, the number of thin volumes in this pool.", 0)
FIELD(SEGS, seg, STR, "Discards", list, 0, discards, discards, "For thin pools, how discards are handled.", 0)
FIELD(SEGS, seg, NUM, "CMFmt", list, 0, cachemetadataformat, cache_metadata_format, "For cache, metadata format in use.", 0)
FIELD(SEGS, seg, STR, "CacheMode", list, 0, cachemode, cache_mode, "For cache, how writes are cached.", 0)
FIELD(SEGS, seg, STR, "CacheMode", list, 0, cachemode, cache_mode, "For cache pools, how writes are cached.", 0)
FIELD(SEGS, seg, BIN, "Zero", list, 0, thinzero, zero, "For thin pools and volumes, if zeroing is enabled.", 0)
FIELD(SEGS, seg, NUM, "TransId", list, 0, transactionid, transaction_id, "For thin pools, the transaction id and creation transaction id for thins.", 0)
FIELD(SEGS, seg, NUM, "ThId", list, 0, thinid, thin_id, "For thin volume, the thin device id.", 0)

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2010-2017 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2013 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -446,22 +446,8 @@ GET_VG_NUM_PROPERTY_FN(vg_missing_pv_count, vg_missing_pv_count(vg))
/* LVSEG */
GET_LVSEG_STR_PROPERTY_FN(segtype, lvseg_segtype_dup(lvseg->lv->vg->vgmem, lvseg))
#define _segtype_set prop_not_implemented_set
GET_LVSEG_NUM_PROPERTY_FN(data_copies, lvseg->data_copies)
#define _data_copies_set prop_not_implemented_set
GET_LVSEG_NUM_PROPERTY_FN(reshape_len, lvseg->reshape_len)
#define _reshape_len_set prop_not_implemented_set
GET_LVSEG_NUM_PROPERTY_FN(reshape_len_le, lvseg->reshape_len)
#define _reshape_len_le_set prop_not_implemented_set
GET_LVSEG_NUM_PROPERTY_FN(data_offset, lvseg->data_offset)
#define _data_offset_set prop_not_implemented_set
GET_LVSEG_NUM_PROPERTY_FN(new_data_offset, lvseg->data_offset)
#define _new_data_offset_set prop_not_implemented_set
GET_LVSEG_NUM_PROPERTY_FN(parity_chunks, lvseg->data_offset)
#define _parity_chunks_set prop_not_implemented_set
GET_LVSEG_NUM_PROPERTY_FN(stripes, lvseg->area_count)
#define _stripes_set prop_not_implemented_set
GET_LVSEG_NUM_PROPERTY_FN(data_stripes, lvseg->area_count)
#define _data_stripes_set prop_not_implemented_set
GET_LVSEG_NUM_PROPERTY_FN(stripe_size, (SECTOR_SIZE * lvseg->stripe_size))
#define _stripe_size_set prop_not_implemented_set
GET_LVSEG_NUM_PROPERTY_FN(region_size, (SECTOR_SIZE * lvseg->region_size))
@@ -470,7 +456,7 @@ GET_LVSEG_NUM_PROPERTY_FN(chunk_size, (SECTOR_SIZE * lvseg_chunksize(lvseg)))
#define _chunk_size_set prop_not_implemented_set
GET_LVSEG_NUM_PROPERTY_FN(thin_count, dm_list_size(&lvseg->lv->segs_using_this_lv))
#define _thin_count_set prop_not_implemented_set
GET_LVSEG_NUM_PROPERTY_FN(zero, (lvseg->zero_new_blocks == THIN_ZERO_YES))
GET_LVSEG_NUM_PROPERTY_FN(zero, lvseg->zero_new_blocks)
#define _zero_set prop_not_implemented_set
GET_LVSEG_NUM_PROPERTY_FN(transaction_id, lvseg->transaction_id)
#define _transaction_id_set prop_not_implemented_set
@@ -482,8 +468,6 @@ GET_LVSEG_STR_PROPERTY_FN(kernel_discards, lvseg_kernel_discards_dup(lvseg->lv->
#define _kernel_discards_set prop_not_implemented_set
GET_LVSEG_STR_PROPERTY_FN(cache_mode, lvseg_cachemode_dup(lvseg->lv->vg->vgmem, lvseg))
#define _cache_mode_set prop_not_implemented_set
GET_LVSEG_NUM_PROPERTY_FN(cache_metadata_format, lvseg->cache_metadata_format)
#define _cache_metadata_format_set prop_not_implemented_set
GET_LVSEG_NUM_PROPERTY_FN(seg_start, (SECTOR_SIZE * lvseg_start(lvseg)))
#define _seg_start_set prop_not_implemented_set
GET_LVSEG_NUM_PROPERTY_FN(seg_start_pe, lvseg->le)
@@ -515,8 +499,6 @@ GET_LVSEG_STR_PROPERTY_FN(seg_monitor, lvseg_monitor_dup(lvseg->lv->vg->vgmem, l
#define _kernel_cache_settings_set prop_not_implemented_set
#define _kernel_cache_policy_get prop_not_implemented_get
#define _kernel_cache_policy_set prop_not_implemented_set
#define _kernel_metadata_format_get prop_not_implemented_get
#define _kernel_metadata_format_set prop_not_implemented_set
/* PVSEG */
GET_PVSEG_NUM_PROPERTY_FN(pvseg_start, pvseg->pe)

View File

@@ -54,7 +54,6 @@ enum {
static const uint64_t _zero64 = UINT64_C(0);
static const uint64_t _one64 = UINT64_C(1);
static const uint64_t _two64 = UINT64_C(2);
static const char _str_zero[] = "0";
static const char _str_one[] = "1";
static const char _str_no[] = "no";
@@ -1538,21 +1537,6 @@ static int _kernel_cache_policy_disp(struct dm_report *rh, struct dm_pool *mem,
GET_FIELD_RESERVED_VALUE(cache_policy_undef));
}
static int _kernelmetadataformat_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
{
const struct lv_with_info_and_seg_status *lvdm = (const struct lv_with_info_and_seg_status *) data;
unsigned format;
if (lvdm->seg_status.type == SEG_STATUS_CACHE) {
format = (lvdm->seg_status.cache->feature_flags & DM_CACHE_FEATURE_METADATA2);
return dm_report_field_uint64(rh, field, format ? &_two64 : &_one64);
}
return _field_set_value(field, "", &GET_TYPE_RESERVED_VALUE(num_undef_64));
}
static int _cache_policy_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
@@ -2312,22 +2296,6 @@ static int _size64_disp(struct dm_report *rh __attribute__((unused)),
return _field_set_value(field, repstr, sortval);
}
static int _lv_size_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;
const struct lv_segment *seg = first_seg(lv);
uint64_t size = lv->le_count;
if (seg && !lv_is_raid_image(lv))
size -= seg->reshape_len * (seg->area_count > 2 ? (seg->area_count - seg->segtype->parity_devs) : 1);
size *= lv->vg->extent_size;
return _size64_disp(rh, mem, field, &size, private);
}
static int _uint32_disp(struct dm_report *rh, struct dm_pool *mem __attribute__((unused)),
struct dm_report_field *field,
const void *data, void *private __attribute__((unused)))
@@ -2444,197 +2412,6 @@ static int _segstartpe_disp(struct dm_report *rh,
return dm_report_field_uint32(rh, field, &seg->le);
}
/* Hepler: get used stripes = total stripes minux any to remove after reshape */
static int _get_seg_used_stripes(const struct lv_segment *seg)
{
uint32_t s;
uint32_t stripes = seg->area_count;
for (s = seg->area_count - 1; stripes && s; s--) {
if (seg_type(seg, s) == AREA_LV &&
seg_lv(seg, s)->status & LV_REMOVE_AFTER_RESHAPE)
stripes--;
else
break;
}
return stripes;
}
static int _seg_stripes_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->area_count);
}
/* Report the number of data stripes, which is less than total stripes (e.g. 2 less for raid6) */
static int _seg_data_stripes_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;
uint32_t stripes = _get_seg_used_stripes(seg) - seg->segtype->parity_devs;
/* FIXME: in case of odd numbers of raid10 stripes */
if (seg_is_raid10(seg))
stripes /= seg->data_copies;
return dm_report_field_uint32(rh, field, &stripes);
}
/* Helper: return the top-level, reshapable raid LV in case @seg belongs to an raid rimage LV */
static struct logical_volume *_lv_for_raid_image_seg(const struct lv_segment *seg, struct dm_pool *mem)
{
char *lv_name;
if (seg_is_reshapable_raid(seg))
return seg->lv;
if (seg->lv &&
lv_is_raid_image(seg->lv) && !seg->le &&
(lv_name = dm_pool_strdup(mem, seg->lv->name))) {
char *p = strchr(lv_name, '_');
if (p) {
/* Handle duplicated sub LVs */
if (strstr(p, "_dup_"))
p = strchr(p + 5, '_');
if (p) {
struct lv_list *lvl;
*p = '\0';
if ((lvl = find_lv_in_vg(seg->lv->vg, lv_name)) &&
seg_is_reshapable_raid(first_seg(lvl->lv)))
return lvl->lv;
}
}
}
return NULL;
}
/* Helper: return the top-level raid LV in case it is reshapale for @seg or @seg if it is */
static const struct lv_segment *_get_reshapable_seg(const struct lv_segment *seg, struct dm_pool *mem)
{
return _lv_for_raid_image_seg(seg, mem) ? seg : NULL;
}
/* Display segment reshape length in current units */
static int _seg_reshape_len_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
{
const struct lv_segment *seg = _get_reshapable_seg((const struct lv_segment *) data, mem);
if (seg) {
uint32_t reshape_len = seg->reshape_len * seg->area_count * seg->lv->vg->extent_size;
return _size32_disp(rh, mem, field, &reshape_len, private);
}
return _field_set_value(field, "", &GET_TYPE_RESERVED_VALUE(num_undef_64));
}
/* Display segment reshape length of in logical extents */
static int _seg_reshape_len_le_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
{
const struct lv_segment *seg = _get_reshapable_seg((const struct lv_segment *) data, mem);
if (seg) {
uint32_t reshape_len = seg->reshape_len* seg->area_count;
return dm_report_field_uint32(rh, field, &reshape_len);
}
return _field_set_value(field, "", &GET_TYPE_RESERVED_VALUE(num_undef_64));
}
/* Display segment data copies (e.g. 3 for raid6) */
static int _seg_data_copies_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;
if (seg->data_copies)
return dm_report_field_uint32(rh, field, &seg->data_copies);
return _field_set_value(field, "", &GET_TYPE_RESERVED_VALUE(num_undef_64));
}
/* Helper: display segment data offset/new data offset in sectors */
static int _segdata_offset(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private, int new_data_offset)
{
const struct lv_segment *seg = (const struct lv_segment *) data;
struct logical_volume *lv;
if ((lv = _lv_for_raid_image_seg(seg, mem))) {
uint64_t data_offset;
if (lv_raid_data_offset(lv, &data_offset)) {
if (new_data_offset && !lv_raid_image_in_sync(seg->lv))
data_offset = data_offset ? 0 : (uint64_t) seg->reshape_len * lv->vg->extent_size;
return dm_report_field_uint64(rh, field, &data_offset);
}
}
return _field_set_value(field, "", &GET_TYPE_RESERVED_VALUE(num_undef_64));
}
static int _seg_data_offset_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
{
return _segdata_offset(rh, mem, field, data, private, 0);
}
static int _seg_new_data_offset_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
{
return _segdata_offset(rh, mem, field, data, private, 1);
}
static int _seg_parity_chunks_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;
uint32_t parity_chunks = seg->segtype->parity_devs ?: seg->data_copies - 1;
if (parity_chunks) {
uint32_t s, resilient_sub_lvs = 0;
for (s = 0; s < seg->area_count; s++) {
if (seg_type(seg, s) == AREA_LV) {
struct lv_segment *seg1 = first_seg(seg_lv(seg, s));
if (seg1->segtype->parity_devs ||
seg1->data_copies > 1)
resilient_sub_lvs++;
}
}
if (resilient_sub_lvs && resilient_sub_lvs == seg->area_count)
parity_chunks++;
return dm_report_field_uint32(rh, field, &parity_chunks);
}
return _field_set_value(field, "", &GET_TYPE_RESERVED_VALUE(num_undef_64));
}
static int _segsize_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
@@ -2734,29 +2511,6 @@ static int _cachemode_disp(struct dm_report *rh, struct dm_pool *mem,
return _field_string(rh, field, display_cache_mode(seg));
}
static int _cachemetadataformat_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;
const uint64_t *fmt;
if (seg_is_cache(seg))
seg = first_seg(seg->pool_lv);
if (seg_is_cache_pool(seg)) {
switch (seg->cache_metadata_format) {
case CACHE_METADATA_FORMAT_1:
case CACHE_METADATA_FORMAT_2:
fmt = (seg->cache_metadata_format == CACHE_METADATA_FORMAT_2) ? &_two64 : &_one64;
return dm_report_field_uint64(rh, field, fmt);
default: /* unselected/undefined for all other cases */;
}
}
return _field_set_value(field, "", &GET_TYPE_RESERVED_VALUE(num_undef_64));
}
static int _originsize_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
@@ -3693,7 +3447,7 @@ static int _thinzero_disp(struct dm_report *rh, struct dm_pool *mem,
seg = first_seg(seg->pool_lv);
if (seg_is_thin_pool(seg))
return _binary_disp(rh, mem, field, (seg->zero_new_blocks == THIN_ZERO_YES), GET_FIRST_RESERVED_NAME(zero_y), private);
return _binary_disp(rh, mem, field, seg->zero_new_blocks, GET_FIRST_RESERVED_NAME(zero_y), private);
return _binary_undef_disp(rh, mem, field, private);
}

View File

@@ -45,7 +45,7 @@ static void _thin_pool_display(const struct lv_segment *seg)
dm_list_size(&seg->lv->segs_using_this_lv));
log_print(" Transaction ID\t%" PRIu64, seg->transaction_id);
log_print(" Zero new blocks\t%s",
(seg->zero_new_blocks == THIN_ZERO_YES) ? "yes" : "no");
seg->zero_new_blocks ? "yes" : "no");
log_print(" ");
}
@@ -84,7 +84,6 @@ static int _thin_pool_text_import(struct lv_segment *seg,
const char *lv_name;
struct logical_volume *pool_data_lv, *pool_metadata_lv;
const char *discards_str = NULL;
uint32_t zero = 0;
if (!dm_config_get_str(sn, "metadata", &lv_name))
return SEG_LOG_ERROR("Metadata must be a string in");
@@ -125,11 +124,9 @@ static int _thin_pool_text_import(struct lv_segment *seg,
seg->device_id);
if (dm_config_has_node(sn, "zero_new_blocks") &&
!dm_config_get_uint32(sn, "zero_new_blocks", &zero))
!dm_config_get_uint32(sn, "zero_new_blocks", &seg->zero_new_blocks))
return SEG_LOG_ERROR("Could not read zero_new_blocks for");
seg->zero_new_blocks = (zero) ? THIN_ZERO_YES : THIN_ZERO_NO;
/* Read messages */
for (; sn; sn = sn->sib)
if (!(sn->v) && !_thin_pool_add_message(seg, sn->key, sn->child))
@@ -168,13 +165,8 @@ static int _thin_pool_text_export(const struct lv_segment *seg, struct formatter
return 0;
}
if (seg->zero_new_blocks == THIN_ZERO_YES)
if (seg->zero_new_blocks)
outf(f, "zero_new_blocks = 1");
else if (seg->zero_new_blocks != THIN_ZERO_NO) {
log_error(INTERNAL_ERROR "Invalid zero new blocks value %d.",
seg->zero_new_blocks);
return 0;
}
dm_list_iterate_items(tmsg, &seg->thin_messages) {
/* Extra validation */
@@ -312,7 +304,7 @@ static int _thin_pool_add_target_line(struct dev_manager *dm,
seg->transaction_id,
metadata_dlid, pool_dlid,
seg->chunk_size, low_water_mark,
(seg->zero_new_blocks == THIN_ZERO_YES) ? 0 : 1))
seg->zero_new_blocks ? 0 : 1))
return_0;
if (attr & THIN_FEATURE_DISCARDS) {

View File

@@ -260,7 +260,7 @@ struct dm_config_node *config_make_nodes_v(struct dm_config_tree *cft,
key[fmt - next] = '\0';
fmt += 2;
if (!strcmp(fmt, FMTd64)) {
if (!strcmp(fmt, "%d") || !strcmp(fmt, FMTd64)) {
int64_t value = va_arg(ap, int64_t);
if (!(cn = make_int_node(cft, key, value, parent, pre_sib)))
return 0;

View File

@@ -234,6 +234,7 @@ dm_tree_free
dm_tree_get_cookie
dm_tree_children_use_uuid
dm_tree_next_child
dm_tree_node_add_cache_target
dm_tree_node_add_crypt_target
dm_tree_node_add_error_target
dm_tree_node_add_linear_target

View File

@@ -1,9 +1,5 @@
dm_bit_get_last
dm_bit_get_prev
dm_filemapd_mode_from_string
dm_stats_update_regions_from_fd
dm_bitset_parse_list
dm_stats_bind_from_fd
dm_stats_start_filemapd
dm_tree_node_add_raid_target_with_params_v2
dm_tree_node_add_cache_target

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2017 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004-2015 Red Hat, Inc. All rights reserved.
* Copyright (C) 2006 Rackable Systems All rights reserved.
*
* This file is part of the device-mapper userspace tools.
@@ -331,7 +331,6 @@ struct dm_status_raid {
char *dev_health;
/* idle, frozen, resync, recover, check, repair */
char *sync_action;
uint64_t data_offset; /* RAID out-of-place reshaping */
};
int dm_get_status_raid(struct dm_pool *mem, const char *params,
@@ -359,7 +358,7 @@ struct dm_status_cache {
uint64_t demotions;
uint64_t promotions;
uint64_t feature_flags; /* DM_CACHE_FEATURE_? */
uint64_t feature_flags;
int core_argc;
char **core_argv;
@@ -1369,73 +1368,6 @@ uint64_t *dm_stats_create_regions_from_fd(struct dm_stats *dms, int fd,
uint64_t *dm_stats_update_regions_from_fd(struct dm_stats *dms, int fd,
uint64_t group_id);
/*
* The file map monitoring daemon can monitor files in two distinct
* ways: the mode affects the behaviour of the daemon when a file
* under monitoring is renamed or unlinked, and the conditions which
* cause the daemon to terminate.
*
* In both modes, the daemon will always shut down when the group
* being monitored is deleted.
*
* Follow inode:
* The daemon follows the inode of the file, as it was at the time the
* daemon started. The file descriptor referencing the file is kept
* open at all times, and the daemon will exit when it detects that
* the file has been unlinked and it is the last holder of a reference
* to the file.
*
* This mode is useful if the file is expected to be renamed, or moved
* within the file system, while it is being monitored.
*
* Follow path:
* The daemon follows the path that was given on the daemon command
* line. The file descriptor referencing the file is re-opened on each
* iteration of the daemon, and the daemon will exit if no file exists
* at this location (a tolerance is allowed so that a brief delay
* between unlink() and creat() is permitted).
*
* This mode is useful if the file is updated by unlinking the original
* and placing a new file at the same path.
*/
typedef enum {
DM_FILEMAPD_FOLLOW_INODE,
DM_FILEMAPD_FOLLOW_PATH,
DM_FILEMAPD_FOLLOW_NONE
} dm_filemapd_mode_t;
/*
* Parse a string representation of a dmfilemapd mode.
*
* Returns a valid dm_filemapd_mode_t value on success, or
* DM_FILEMAPD_FOLLOW_NONE on error.
*/
dm_filemapd_mode_t dm_filemapd_mode_from_string(const char *mode_str);
/*
* Start the dmfilemapd filemap monitoring daemon for the specified
* file descriptor, group, and file system path. The daemon will
* monitor the file for allocation changes, and when a change is
* detected, call dm_stats_update_regions_from_fd() to update the
* mapped regions for the file.
*
* The path provided to dm_stats_start_filemapd() must be an absolute
* path, and should reflect the path of 'fd' at the time that it was
* opened.
*
* The mode parameter controls the behaviour of the daemon when the
* file being monitored is unlinked or moved: see the comments for
* dm_filemapd_mode_t for a full description and possible values.
*
* The daemon can be stopped at any time by sending SIGTERM to the
* daemon pid.
*/
int dm_stats_start_filemapd(int fd, uint64_t group_id, const char *path,
dm_filemapd_mode_t mode, unsigned foreground,
unsigned verbose);
/*
* Call this to actually run the ioctl.
*/
@@ -1806,11 +1738,6 @@ int dm_tree_node_add_raid_target(struct dm_tree_node *node,
*/
#define DM_CACHE_METADATA_MAX_SECTORS DM_THIN_METADATA_MAX_SECTORS
/*
* Define number of elements in rebuild and writemostly arrays
* 'of struct dm_tree_node_raid_params'.
*/
struct dm_tree_node_raid_params {
const char *raid_type;
@@ -1822,75 +1749,29 @@ struct dm_tree_node_raid_params {
/*
* 'rebuilds' and 'writemostly' are bitfields that signify
* which devices in the array are to be rebuilt or marked
* writemostly. The kernel supports up to 253 legs.
* We limit ourselves by choosing a lower value
* for DEFAULT_RAID{1}_MAX_IMAGES in defaults.h.
* writemostly. By choosing a 'uint64_t', we limit ourself
* to RAID arrays with 64 devices.
*/
uint64_t rebuilds;
uint64_t writemostly;
uint32_t writebehind; /* I/Os (kernel default COUNTER_MAX / 2) */
uint32_t sync_daemon_sleep; /* ms (kernel default = 5sec) */
uint32_t max_recovery_rate; /* kB/sec/disk */
uint32_t min_recovery_rate; /* kB/sec/disk */
uint32_t stripe_cache; /* sectors */
uint64_t flags; /* [no]sync */
uint32_t reserved2;
};
/*
* Version 2 of above node raid params struct to keeep API compatibility.
*
* Extended for more than 64 legs (max 253 in the MD kernel runtime!),
* delta_disks for disk add/remove reshaping,
* data_offset for out-of-place reshaping
* and data_copies for odd number of raid10 legs.
*/
#define RAID_BITMAP_SIZE 4 /* 4 * 64 bit elements in rebuilds/writemostly arrays */
struct dm_tree_node_raid_params_v2 {
const char *raid_type;
uint32_t stripes;
uint32_t mirrors;
uint32_t region_size;
uint32_t stripe_size;
int delta_disks; /* +/- number of disks to add/remove (reshaping) */
int data_offset; /* data offset to set (out-of-place reshaping) */
/*
* 'rebuilds' and 'writemostly' are bitfields that signify
* which devices in the array are to be rebuilt or marked
* writemostly. The kernel supports up to 253 legs.
* We limit ourselvs by choosing a lower value
* for DEFAULT_RAID_MAX_IMAGES.
*/
uint64_t rebuilds[RAID_BITMAP_SIZE];
uint64_t writemostly[RAID_BITMAP_SIZE];
uint32_t writebehind; /* I/Os (kernel default COUNTER_MAX / 2) */
uint32_t data_copies; /* RAID # of data copies */
uint32_t writebehind; /* I/Os (kernel default COUNTER_MAX / 2) */
uint32_t sync_daemon_sleep; /* ms (kernel default = 5sec) */
uint32_t max_recovery_rate; /* kB/sec/disk */
uint32_t min_recovery_rate; /* kB/sec/disk */
uint32_t stripe_cache; /* sectors */
uint64_t flags; /* [no]sync */
uint64_t reserved2;
};
int dm_tree_node_add_raid_target_with_params(struct dm_tree_node *node,
uint64_t size,
const struct dm_tree_node_raid_params *p);
/* Version 2 API function taking dm_tree_node_raid_params_v2 for aforementioned extensions. */
int dm_tree_node_add_raid_target_with_params_v2(struct dm_tree_node *node,
uint64_t size,
const struct dm_tree_node_raid_params_v2 *p);
/* Cache feature_flags */
#define DM_CACHE_FEATURE_WRITEBACK 0x00000001
#define DM_CACHE_FEATURE_WRITETHROUGH 0x00000002
#define DM_CACHE_FEATURE_PASSTHROUGH 0x00000004
#define DM_CACHE_FEATURE_METADATA2 0x00000008 /* cache v1.10 */
struct dm_config_node;
/*

View File

@@ -205,14 +205,11 @@ struct load_segment {
struct dm_tree_node *replicator;/* Replicator-dev */
uint64_t rdevice_index; /* Replicator-dev */
int delta_disks; /* raid reshape number of disks */
int data_offset; /* raid reshape data offset on disk to set */
uint64_t rebuilds[RAID_BITMAP_SIZE]; /* raid */
uint64_t writemostly[RAID_BITMAP_SIZE]; /* raid */
uint64_t rebuilds; /* raid */
uint64_t writemostly; /* raid */
uint32_t writebehind; /* raid */
uint32_t max_recovery_rate; /* raid kB/sec/disk */
uint32_t min_recovery_rate; /* raid kB/sec/disk */
uint32_t data_copies; /* raid10 data_copies */
struct dm_tree_node *metadata; /* Thin_pool + Cache */
struct dm_tree_node *pool; /* Thin_pool, Thin */
@@ -2356,21 +2353,16 @@ static int _mirror_emit_segment_line(struct dm_task *dmt, struct load_segment *s
return 1;
}
static int _2_if_value(unsigned p)
{
return p ? 2 : 0;
}
/* Is parameter non-zero? */
#define PARAM_IS_SET(p) ((p) ? 1 : 0)
/* Return number of bits passed in @bits assuming 2 * 64 bit size */
static int _get_params_count(uint64_t *bits)
/* Return number of bits assuming 4 * 64 bit size */
static int _get_params_count(uint64_t bits)
{
int r = 0;
int i = RAID_BITMAP_SIZE;
while (i--) {
r += 2 * hweight32(bits[i] & 0xFFFFFFFF);
r += 2 * hweight32(bits[i] >> 32);
}
r += 2 * hweight32(bits & 0xFFFFFFFF);
r += 2 * hweight32(bits >> 32);
return r;
}
@@ -2381,60 +2373,32 @@ static int _raid_emit_segment_line(struct dm_task *dmt, uint32_t major,
size_t paramsize)
{
uint32_t i;
uint32_t area_count = seg->area_count / 2;
int param_count = 1; /* mandatory 'chunk size'/'stripe size' arg */
int pos = 0;
unsigned type;
if (seg->area_count % 2)
return 0;
unsigned type = seg->type;
if ((seg->flags & DM_NOSYNC) || (seg->flags & DM_FORCESYNC))
param_count++;
param_count += _2_if_value(seg->data_offset) +
_2_if_value(seg->delta_disks) +
_2_if_value(seg->region_size) +
_2_if_value(seg->writebehind) +
_2_if_value(seg->min_recovery_rate) +
_2_if_value(seg->max_recovery_rate) +
_2_if_value(seg->data_copies > 1);
param_count += 2 * (PARAM_IS_SET(seg->region_size) +
PARAM_IS_SET(seg->writebehind) +
PARAM_IS_SET(seg->min_recovery_rate) +
PARAM_IS_SET(seg->max_recovery_rate));
/* rebuilds and writemostly are BITMAP_SIZE * 64 bits */
/* rebuilds and writemostly are 64 bits */
param_count += _get_params_count(seg->rebuilds);
param_count += _get_params_count(seg->writemostly);
if ((seg->type == SEG_RAID1) && seg->stripe_size)
log_info("WARNING: Ignoring RAID1 stripe size");
if ((type == SEG_RAID1) && seg->stripe_size)
log_error("WARNING: Ignoring RAID1 stripe size");
/* Kernel only expects "raid0", not "raid0_meta" */
type = seg->type;
if (type == SEG_RAID0_META)
type = SEG_RAID0;
#if 0
/* Kernel only expects "raid10", not "raid10_{far,offset}" */
else if (type == SEG_RAID10_FAR ||
type == SEG_RAID10_OFFSET) {
param_count += 2;
type = SEG_RAID10_NEAR;
}
#endif
EMIT_PARAMS(pos, "%s %d %u",
// type == SEG_RAID10_NEAR ? "raid10" : _dm_segtypes[type].target,
type == SEG_RAID10 ? "raid10" : _dm_segtypes[type].target,
EMIT_PARAMS(pos, "%s %d %u", _dm_segtypes[type].target,
param_count, seg->stripe_size);
#if 0
if (seg->type == SEG_RAID10_FAR)
EMIT_PARAMS(pos, " raid10_format far");
else if (seg->type == SEG_RAID10_OFFSET)
EMIT_PARAMS(pos, " raid10_format offset");
#endif
if (seg->data_copies > 1 && type == SEG_RAID10)
EMIT_PARAMS(pos, " raid10_copies %u", seg->data_copies);
if (seg->flags & DM_NOSYNC)
EMIT_PARAMS(pos, " nosync");
else if (seg->flags & DM_FORCESYNC)
@@ -2443,38 +2407,27 @@ static int _raid_emit_segment_line(struct dm_task *dmt, uint32_t major,
if (seg->region_size)
EMIT_PARAMS(pos, " region_size %u", seg->region_size);
/* If seg-data_offset == 1, kernel needs a zero offset to adjust to it */
if (seg->data_offset)
EMIT_PARAMS(pos, " data_offset %d", seg->data_offset == 1 ? 0 : seg->data_offset);
if (seg->delta_disks)
EMIT_PARAMS(pos, " delta_disks %d", seg->delta_disks);
for (i = 0; i < area_count; i++)
if (seg->rebuilds[i/64] & (1ULL << (i%64)))
for (i = 0; i < (seg->area_count / 2); i++)
if (seg->rebuilds & (1ULL << i))
EMIT_PARAMS(pos, " rebuild %u", i);
for (i = 0; i < area_count; i++)
if (seg->writemostly[i/64] & (1ULL << (i%64)))
EMIT_PARAMS(pos, " write_mostly %u", i);
if (seg->writebehind)
EMIT_PARAMS(pos, " max_write_behind %u", seg->writebehind);
/*
* Has to be before "min_recovery_rate" or the kernels
* check will fail when both set and min > previous max
*/
if (seg->max_recovery_rate)
EMIT_PARAMS(pos, " max_recovery_rate %u",
seg->max_recovery_rate);
if (seg->min_recovery_rate)
EMIT_PARAMS(pos, " min_recovery_rate %u",
seg->min_recovery_rate);
if (seg->max_recovery_rate)
EMIT_PARAMS(pos, " max_recovery_rate %u",
seg->max_recovery_rate);
for (i = 0; i < (seg->area_count / 2); i++)
if (seg->writemostly & (1ULL << i))
EMIT_PARAMS(pos, " write_mostly %u", i);
if (seg->writebehind)
EMIT_PARAMS(pos, " max_write_behind %u", seg->writebehind);
/* Print number of metadata/data device pairs */
EMIT_PARAMS(pos, " %u", area_count);
EMIT_PARAMS(pos, " %u", seg->area_count/2);
if (_emit_areas_line(dmt, seg, params, paramsize, &pos) <= 0)
return_0;
@@ -2514,17 +2467,12 @@ static int _cache_emit_segment_line(struct dm_task *dmt,
/* Features */
/* feature_count = hweight32(seg->flags); */
/* EMIT_PARAMS(pos, " %u", feature_count); */
if (seg->flags & DM_CACHE_FEATURE_METADATA2)
EMIT_PARAMS(pos, " 2 metadata2 ");
else
EMIT_PARAMS(pos, " 1 ");
if (seg->flags & DM_CACHE_FEATURE_PASSTHROUGH)
EMIT_PARAMS(pos, "passthrough");
else if (seg->flags & DM_CACHE_FEATURE_WRITEBACK)
EMIT_PARAMS(pos, "writeback");
else
EMIT_PARAMS(pos, "writethrough");
EMIT_PARAMS(pos, " 1 passthrough");
else if (seg->flags & DM_CACHE_FEATURE_WRITETHROUGH)
EMIT_PARAMS(pos, " 1 writethrough");
else if (seg->flags & DM_CACHE_FEATURE_WRITEBACK)
EMIT_PARAMS(pos, " 1 writeback");
/* Cache Policy */
name = seg->policy_name ? : "default";
@@ -3319,10 +3267,8 @@ int dm_tree_node_add_raid_target_with_params(struct dm_tree_node *node,
seg->region_size = p->region_size;
seg->stripe_size = p->stripe_size;
seg->area_count = 0;
memset(seg->rebuilds, 0, sizeof(seg->rebuilds));
seg->rebuilds[0] = p->rebuilds;
memset(seg->writemostly, 0, sizeof(seg->writemostly));
seg->writemostly[0] = p->writemostly;
seg->rebuilds = p->rebuilds;
seg->writemostly = p->writemostly;
seg->writebehind = p->writebehind;
seg->min_recovery_rate = p->min_recovery_rate;
seg->max_recovery_rate = p->max_recovery_rate;
@@ -3350,47 +3296,6 @@ int dm_tree_node_add_raid_target(struct dm_tree_node *node,
return dm_tree_node_add_raid_target_with_params(node, size, &params);
}
/*
* Version 2 of dm_tree_node_add_raid_target() allowing for:
*
* - maximum 253 legs in a raid set (MD kernel limitation)
* - delta_disks for disk add/remove reshaping
* - data_offset for out-of-place reshaping
* - data_copies to cope witth odd numbers of raid10 disks
*/
int dm_tree_node_add_raid_target_with_params_v2(struct dm_tree_node *node,
uint64_t size,
const struct dm_tree_node_raid_params_v2 *p)
{
unsigned i;
struct load_segment *seg = NULL;
for (i = 0; i < DM_ARRAY_SIZE(_dm_segtypes) && !seg; ++i)
if (!strcmp(p->raid_type, _dm_segtypes[i].target))
if (!(seg = _add_segment(node,
_dm_segtypes[i].type, size)))
return_0;
if (!seg) {
log_error("Unsupported raid type %s.", p->raid_type);
return 0;
}
seg->region_size = p->region_size;
seg->stripe_size = p->stripe_size;
seg->area_count = 0;
seg->delta_disks = p->delta_disks;
seg->data_offset = p->data_offset;
memcpy(seg->rebuilds, p->rebuilds, sizeof(seg->rebuilds));
memcpy(seg->writemostly, p->writemostly, sizeof(seg->writemostly));
seg->writebehind = p->writebehind;
seg->data_copies = p->data_copies;
seg->min_recovery_rate = p->min_recovery_rate;
seg->max_recovery_rate = p->max_recovery_rate;
seg->flags = p->flags;
return 1;
}
int dm_tree_node_add_cache_target(struct dm_tree_node *node,
uint64_t size,
uint64_t feature_flags, /* DM_CACHE_FEATURE_* */
@@ -3403,33 +3308,19 @@ int dm_tree_node_add_cache_target(struct dm_tree_node *node,
{
struct dm_config_node *cn;
struct load_segment *seg;
static const uint64_t _modemask =
DM_CACHE_FEATURE_PASSTHROUGH |
DM_CACHE_FEATURE_WRITETHROUGH |
DM_CACHE_FEATURE_WRITEBACK;
/* Detect unknown (bigger) feature bit */
if (feature_flags >= (DM_CACHE_FEATURE_METADATA2 * 2)) {
log_error("Unsupported cache's feature flags set " FMTu64 ".",
feature_flags);
return 0;
}
switch (feature_flags & _modemask) {
case DM_CACHE_FEATURE_PASSTHROUGH:
case DM_CACHE_FEATURE_WRITEBACK:
if (strcmp(policy_name, "cleaner") == 0) {
/* Enforce writethrough mode for cleaner policy */
feature_flags = ~_modemask;
feature_flags |= DM_CACHE_FEATURE_WRITETHROUGH;
}
/* Fall through */
case DM_CACHE_FEATURE_WRITETHROUGH:
break;
default:
log_error("Invalid cache's feature flag " FMTu64 ".",
feature_flags);
return 0;
switch (feature_flags &
(DM_CACHE_FEATURE_PASSTHROUGH |
DM_CACHE_FEATURE_WRITETHROUGH |
DM_CACHE_FEATURE_WRITEBACK)) {
case DM_CACHE_FEATURE_PASSTHROUGH:
case DM_CACHE_FEATURE_WRITETHROUGH:
case DM_CACHE_FEATURE_WRITEBACK:
break;
default:
log_error("Invalid cache's feature flag " FMTu64 ".",
feature_flags);
return 0;
}
if (data_block_size < DM_CACHE_MIN_DATA_BLOCK_SIZE) {
@@ -3475,7 +3366,8 @@ int dm_tree_node_add_cache_target(struct dm_tree_node *node,
return_0;
seg->data_block_size = data_block_size;
seg->flags = feature_flags;
/* Enforce WriteThough mode for cleaner policy */
seg->flags = (strcmp(policy_name, "cleaner") == 0) ? DM_CACHE_FEATURE_WRITETHROUGH : feature_flags;
seg->policy_name = policy_name;
/* FIXME: better validation missing */
@@ -4034,15 +3926,13 @@ void dm_tree_node_set_callback(struct dm_tree_node *dnode,
dnode->callback_data = data;
}
#if defined(__GNUC__)
/*
* Backward compatible implementations.
* Backward compatible dm_tree_node_size_changed() implementations.
*
* Keep these at the end of the file to make sure that
* no code in this file accidentally calls it.
* Keep these at the end of the file to avoid adding clutter around the
* current dm_tree_node_size_changed() version.
*/
/* Backward compatible dm_tree_node_size_changed() implementations. */
#if defined(__GNUC__)
int dm_tree_node_size_changed_base(const struct dm_tree_node *dnode);
DM_EXPORT_SYMBOL_BASE(dm_tree_node_size_changed);
int dm_tree_node_size_changed_base(const struct dm_tree_node *dnode)
@@ -4050,43 +3940,4 @@ int dm_tree_node_size_changed_base(const struct dm_tree_node *dnode)
/* Base does not make difference between smaller and bigger */
return dm_tree_node_size_changed(dnode) ? 1 : 0;
}
/*
* Retain ABI compatibility after adding the DM_CACHE_FEATURE_METADATA2
* in version 1.02.138.
*
* Binaries compiled against version 1.02.138 onwards will use
* the new function dm_tree_node_add_cache_target which detects unknown
* feature flags and returns error for them.
*/
int dm_tree_node_add_cache_target_base(struct dm_tree_node *node,
uint64_t size,
uint64_t feature_flags, /* DM_CACHE_FEATURE_* */
const char *metadata_uuid,
const char *data_uuid,
const char *origin_uuid,
const char *policy_name,
const struct dm_config_node *policy_settings,
uint32_t data_block_size);
DM_EXPORT_SYMBOL_BASE(dm_tree_node_add_cache_target);
int dm_tree_node_add_cache_target_base(struct dm_tree_node *node,
uint64_t size,
uint64_t feature_flags,
const char *metadata_uuid,
const char *data_uuid,
const char *origin_uuid,
const char *policy_name,
const struct dm_config_node *policy_settings,
uint32_t data_block_size)
{
/* Old version supported only these FEATURE bits, others were ignored so masked them */
static const uint64_t _mask =
DM_CACHE_FEATURE_WRITEBACK |
DM_CACHE_FEATURE_WRITETHROUGH |
DM_CACHE_FEATURE_PASSTHROUGH;
return dm_tree_node_add_cache_target(node, size, feature_flags & _mask,
metadata_uuid, data_uuid, origin_uuid,
policy_name, policy_settings, data_block_size);
}
#endif

View File

@@ -264,12 +264,9 @@ static int _stats_group_id_present(const struct dm_stats *dms, uint64_t id)
if (id == DM_STATS_GROUP_NOT_PRESENT)
return 0;
if (!dms)
if (!dms || !dms->regions)
return_0;
if (!dms->regions)
return 0;
if (id > dms->max_region)
return 0;
@@ -678,7 +675,7 @@ static void _check_group_regions_present(struct dm_stats *dms,
group_id = i = dm_bit_get_first(regions);
for (; i > 0; i = dm_bit_get_next(regions, i))
for (; i > 0; dm_bit_get_next(regions, i))
if (!_stats_region_present(&dms->regions[i])) {
log_warn("Group descriptor " FMTi64 " contains "
"non-existent region_id " FMTi64 ".",
@@ -2387,9 +2384,6 @@ bad:
*/
void dm_stats_destroy(struct dm_stats *dms)
{
if (!dms)
return;
_stats_regions_destroy(dms);
_stats_groups_destroy(dms);
_stats_clear_binding(dms);
@@ -3318,8 +3312,8 @@ static struct dm_histogram *_aggregate_histogram(const struct dm_stats *dms,
uint64_t area_id)
{
struct dm_histogram *dmh_aggr, *dmh_cur, **dmh_cachep;
uint64_t group_id = DM_STATS_GROUP_NOT_PRESENT;
int bin, nr_bins, group = 1;
uint64_t group_id;
size_t hist_size;
if (area_id == DM_STATS_WALK_REGION) {
@@ -3874,6 +3868,37 @@ static int _extent_start_compare(const void *p1, const void *p2)
return 1;
}
/*
* Resize the group bitmap corresponding to group_id so that it can
* contain at least num_regions members.
*/
static int _stats_resize_group(struct dm_stats_group *group, int num_regions)
{
int last_bit = dm_bit_get_last(group->regions);
dm_bitset_t new, old;
if (last_bit >= num_regions) {
log_error("Cannot resize group bitmap to %d with bit %d set.",
num_regions, last_bit);
return 0;
}
log_very_verbose("Resizing group bitmap from %d to %d (last_bit: %d).",
group->regions[0], num_regions, last_bit);
new = dm_bitset_create(NULL, num_regions);
if (!new) {
log_error("Could not allocate memory for new group bitmap.");
return 0;
}
old = group->regions;
dm_bit_copy(new, old);
group->regions = new;
dm_bitset_destroy(old);
return 1;
}
static int _stats_create_group(struct dm_stats *dms, dm_bitset_t regions,
const char *alias, uint64_t *group_id)
{
@@ -4177,37 +4202,6 @@ int dm_stats_get_group_descriptor(const struct dm_stats *dms,
}
#ifdef HAVE_LINUX_FIEMAP_H
/*
* Resize the group bitmap corresponding to group_id so that it can
* contain at least num_regions members.
*/
static int _stats_resize_group(struct dm_stats_group *group, int num_regions)
{
int last_bit = dm_bit_get_last(group->regions);
dm_bitset_t new, old;
if (last_bit >= num_regions) {
log_error("Cannot resize group bitmap to %d with bit %d set.",
num_regions, last_bit);
return 0;
}
log_very_verbose("Resizing group bitmap from %d to %d (last_bit: %d).",
group->regions[0], num_regions, last_bit);
new = dm_bitset_create(NULL, num_regions);
if (!new) {
log_error("Could not allocate memory for new group bitmap.");
return 0;
}
old = group->regions;
dm_bit_copy(new, old);
group->regions = new;
dm_bitset_destroy(old);
return 1;
}
/*
* Group a table of region_ids corresponding to the extents of a file.
*/
@@ -4880,7 +4874,9 @@ out:
dm_free((char *) alias);
return NULL;
}
#else /* !HAVE_LINUX_FIEMAP */
#else /* HAVE_LINUX_FIEMAP */
uint64_t *dm_stats_create_regions_from_fd(struct dm_stats *dms, int fd,
int group, int precise,
struct dm_histogram *bounds,
@@ -4898,158 +4894,6 @@ uint64_t *dm_stats_update_regions_from_fd(struct dm_stats *dms, int fd,
}
#endif /* HAVE_LINUX_FIEMAP */
#ifdef DMFILEMAPD
static const char *_filemapd_mode_names[] = {
"inode",
"path",
NULL
};
dm_filemapd_mode_t dm_filemapd_mode_from_string(const char *mode_str)
{
dm_filemapd_mode_t mode = DM_FILEMAPD_FOLLOW_INODE;
const char **mode_name;
if (mode_str) {
for (mode_name = _filemapd_mode_names; *mode_name; mode_name++)
if (!strcmp(*mode_name, mode_str))
break;
if (*mode_name)
mode = DM_FILEMAPD_FOLLOW_INODE
+ (mode_name - _filemapd_mode_names);
else {
log_error("Could not parse dmfilemapd mode: %s",
mode_str);
return DM_FILEMAPD_FOLLOW_NONE;
}
}
return mode;
}
#define DM_FILEMAPD "dmfilemapd"
#define NR_FILEMAPD_ARGS 7 /* includes argv[0] */
/*
* Start dmfilemapd to monitor the specified file descriptor, and to
* update the group given by 'group_id' when the file's allocation
* changes.
*
* usage: dmfilemapd <fd> <group_id> <mode> [<foreground>[<log_level>]]
*/
int dm_stats_start_filemapd(int fd, uint64_t group_id, const char *path,
dm_filemapd_mode_t mode, unsigned foreground,
unsigned verbose)
{
char fd_str[8], group_str[8], fg_str[2], verb_str[2];
const char *mode_str = _filemapd_mode_names[mode];
char *args[NR_FILEMAPD_ARGS + 1];
pid_t pid = 0;
int argc = 0;
if (fd < 0) {
log_error("dmfilemapd file descriptor must be "
"non-negative: %d", fd);
return 0;
}
if (path[0] != '/') {
log_error("Path argument must specify an absolute path.");
return 0;
}
if (mode > DM_FILEMAPD_FOLLOW_PATH) {
log_error("Invalid dmfilemapd mode argument: "
"Must be DM_FILEMAPD_FOLLOW_INODE or "
"DM_FILEMAPD_FOLLOW_PATH");
return 0;
}
if (foreground > 1) {
log_error("Invalid dmfilemapd foreground argument. "
"Must be 0 or 1: %d.", foreground);
return 0;
}
if (verbose > 3) {
log_error("Invalid dmfilemapd verbose argument. "
"Must be 0..3: %d.", verbose);
return 0;
}
/* set argv[0] */
args[argc++] = (char *) DM_FILEMAPD;
/* set <fd> */
if ((dm_snprintf(fd_str, sizeof(fd_str), "%d", fd)) < 0) {
log_error("Could not format fd argument.");
return 0;
}
args[argc++] = fd_str;
/* set <group_id> */
if ((dm_snprintf(group_str, sizeof(group_str), FMTu64, group_id)) < 0) {
log_error("Could not format group_id argument.");
return 0;
}
args[argc++] = group_str;
/* set <path> */
args[argc++] = (char *) path;
/* set <mode> */
args[argc++] = (char *) mode_str;
/* set <foreground> */
if ((dm_snprintf(fg_str, sizeof(fg_str), "%u", foreground)) < 0) {
log_error("Could not format foreground argument.");
return 0;
}
args[argc++] = fg_str;
/* set <verbose> */
if ((dm_snprintf(verb_str, sizeof(verb_str), "%u", verbose)) < 0) {
log_error("Could not format verbose argument.");
return 0;
}
args[argc++] = verb_str;
/* terminate args[argc] */
args[argc] = NULL;
log_very_verbose("Spawning daemon as '%s %d " FMTu64 " %s %s %u %u'",
*args, fd, group_id, path, mode_str,
foreground, verbose);
if (!foreground && ((pid = fork()) < 0)) {
log_error("Failed to fork dmfilemapd process.");
return 0;
}
if (pid > 0) {
log_very_verbose("Forked dmfilemapd process as pid %d", pid);
return 1;
}
execvp(args[0], args);
log_error("execvp() failed.");
if (!foreground)
_exit(127);
return 0;
}
# else /* !DMFILEMAPD */
dm_filemapd_mode_t dm_filemapd_mode_from_string(const char *mode_str)
{
return 0;
};
int dm_stats_start_filemapd(int fd, uint64_t group_id, const char *path,
dm_filemapd_mode_t mode, unsigned foreground,
unsigned verbose)
{
log_error("dmfilemapd support disabled.");
return 0;
}
#endif /* DMFILEMAPD */
/*
* Backward compatible dm_stats_create_region() implementations.
*

View File

@@ -89,8 +89,6 @@ static unsigned _count_fields(const char *p)
* <raid_type> <#devs> <health_str> <sync_ratio>
* Versions 1.5.0+ (6 fields):
* <raid_type> <#devs> <health_str> <sync_ratio> <sync_action> <mismatch_cnt>
* Versions 1.9.0+ (7 fields):
* <raid_type> <#devs> <health_str> <sync_ratio> <sync_action> <mismatch_cnt> <data_offset>
*/
int dm_get_status_raid(struct dm_pool *mem, const char *params,
struct dm_status_raid **status)
@@ -119,7 +117,7 @@ int dm_get_status_raid(struct dm_pool *mem, const char *params,
goto_bad;
msg_fields = "<raid_type> <#devices> <health_chars> and <sync_ratio> ";
if (sscanf(params, "%s %u %s " FMTu64 "/" FMTu64,
if (sscanf(params, "%s %u %s %" PRIu64 "/%" PRIu64,
s->raid_type,
&s->dev_count,
s->dev_health,
@@ -146,25 +144,9 @@ int dm_get_status_raid(struct dm_pool *mem, const char *params,
if (!(s->sync_action = dm_pool_zalloc(mem, pp - p)))
goto_bad;
if (sscanf(p, "%s " FMTu64, s->sync_action, &s->mismatch_count) != 2)
if (sscanf(p, "%s %" PRIu64, s->sync_action, &s->mismatch_count) != 2)
goto_bad;
if (num_fields < 7)
goto out;
/*
* All pre-1.9.0 version parameters are read. Now we check
* for additional 1.9.0+ parameters (i.e. nr_fields at least 7).
*
* Note that data_offset will be 0 if the
* kernel returns a pre-1.9.0 status.
*/
msg_fields = "<data_offset>";
if (!(p = _skip_fields(params, 6))) /* skip pre-1.9.0 params */
goto bad;
if (sscanf(p, FMTu64, &s->data_offset) != 1)
goto bad;
out:
*status = s;
@@ -244,14 +226,14 @@ int dm_get_status_cache(struct dm_pool *mem, const char *params,
/* Read in args that have definitive placement */
if (sscanf(params,
" " FMTu32
" " FMTu64 "/" FMTu64
" " FMTu32
" " FMTu64 "/" FMTu64
" " FMTu64 " " FMTu64
" " FMTu64 " " FMTu64
" " FMTu64 " " FMTu64
" " FMTu64
" %" PRIu32
" %" PRIu64 "/%" PRIu64
" %" PRIu32
" %" PRIu64 "/%" PRIu64
" %" PRIu64 " %" PRIu64
" %" PRIu64 " %" PRIu64
" %" PRIu64 " %" PRIu64
" %" PRIu64
" %d",
&s->metadata_block_size,
&s->metadata_used_blocks, &s->metadata_total_blocks,
@@ -274,10 +256,8 @@ int dm_get_status_cache(struct dm_pool *mem, const char *params,
s->feature_flags |= DM_CACHE_FEATURE_WRITETHROUGH;
else if (!strncmp(p, "writeback ", 10))
s->feature_flags |= DM_CACHE_FEATURE_WRITEBACK;
else if (!strncmp(p, "passthrough ", 12))
else if (!strncmp(p, "passthrough ", 11))
s->feature_flags |= DM_CACHE_FEATURE_PASSTHROUGH;
else if (!strncmp(p, "metadata2 ", 10))
s->feature_flags |= DM_CACHE_FEATURE_METADATA2;
else
log_error("Unknown feature in status: %s", params);

View File

@@ -40,13 +40,6 @@ SED = @SED@
CFLOW_CMD = @CFLOW_CMD@
AWK = @AWK@
CHMOD = @CHMOD@
EGREP = @EGREP@
GREP = @GREP@
SORT = @SORT@
WC = @WC@
AR = ar
RM = rm -f
PYTHON2 = @PYTHON2@
PYTHON3 = @PYTHON3@
PYCOMPILE = $(top_srcdir)/autoconf/py-compile
@@ -158,7 +151,6 @@ INSTALL_ROOT_DIR = $(INSTALL) -m 700 -d
INSTALL_ROOT_DATA = $(INSTALL) -m 600
INSTALL_SCRIPT = $(INSTALL) -p $(M_INSTALL_PROGRAM)
.SUFFIXES:
.SUFFIXES: .c .cpp .d .o .so .a .po .pot .mo .dylib
WFLAGS +=\
@@ -413,8 +405,6 @@ cflow: $(CFLOW_TARGET).cflow $(CFLOW_TARGET).tree $(CFLOW_TARGET).rxref $(CFLOW_
endif
endif
.LIBPATTERNS = lib%.so lib%.a
%.o: %.c
$(CC) -c $(INCLUDES) $(DEFS) $(WFLAGS) $(WCFLAGS) $(CFLAGS) $(CFLAGS_$@) $< -o $@
@@ -466,7 +456,7 @@ endif
$(LIB_STATIC): $(OBJECTS)
$(RM) $@
$(AR) rsv $@ $(OBJECTS)
$(AR) rs $@ $(OBJECTS)
%.d: %.c $(INC_LNS)
$(MKDIR_P) $(dir $@); \
@@ -522,9 +512,9 @@ ifeq (,$(firstword $(EXPORTED_SYMBOLS)))
) > $@
else
set -e;\
R=$$($(SORT) $^ | uniq -u);\
R=$$(sort $^ | uniq -u);\
test -z "$$R" || { echo "Mismatch between symbols in shared library and lists in .exported_symbols.* files: $$R"; false; } ;\
( for i in $$(echo $(EXPORTED_SYMBOLS) | tr ' ' '\n' | $(SORT) -rnt_ -k5 ); do\
( for i in $$(echo $(EXPORTED_SYMBOLS) | tr ' ' '\n' | sort -rnt_ -k5 ); do\
echo "$${i##*.} {"; echo " global:";\
$(SED) "s/^/ /;s/$$/;/" $$i;\
echo "};";\

2
man/.gitignore vendored
View File

@@ -1,2 +0,0 @@
*.gen
man-generator

View File

@@ -1,6 +1,6 @@
#
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
# Copyright (C) 2004-2017 Red Hat, Inc. All rights reserved.
# Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
#
# This file is part of LVM2.
#
@@ -19,7 +19,6 @@ top_builddir = @top_builddir@
FSADMMAN = fsadm.8
BLKDEACTIVATEMAN = blkdeactivate.8
DMEVENTDMAN = dmeventd.8
DMFILEMAPDMAN = dmfilemapd.8
LVMETADMAN = lvmetad.8
LVMPOLLDMAN = lvmpolld.8
LVMLOCKDMAN = lvmlockd.8 lvmlockctl.8
@@ -32,19 +31,20 @@ LVMRAIDMAN = lvmraid.7
MAN5=lvm.conf.5
MAN7=lvmsystemid.7 lvmreport.7
MAN8=lvm.8 lvmconf.8 lvmdump.8 lvm-config.8 lvm-dumpconfig.8 lvm-fullreport.8 \
lvm-lvpoll.8 lvcreate.8 lvchange.8 lvmconfig.8 lvconvert.8 lvdisplay.8 \
lvextend.8 lvreduce.8 lvremove.8 lvrename.8 lvresize.8 lvs.8 \
lvscan.8 pvchange.8 pvck.8 pvcreate.8 pvdisplay.8 pvmove.8 pvremove.8 \
pvresize.8 pvs.8 pvscan.8 vgcfgbackup.8 vgcfgrestore.8 vgchange.8 \
vgck.8 vgcreate.8 vgconvert.8 vgdisplay.8 vgexport.8 vgextend.8 \
vgimport.8 vgimportclone.8 vgmerge.8 vgmknodes.8 vgreduce.8 vgremove.8 \
vgrename.8 vgs.8 vgscan.8 vgsplit.8 \
lvmsar.8 lvmsadc.8 lvmdiskscan.8
MAN8=lvm.8 lvmconf.8 lvmdump.8
MAN8DM=dmsetup.8 dmstats.8
MAN8CLUSTER=
MAN8SYSTEMD_GENERATORS=lvm2-activation-generator.8
MAN8GEN=lvm-config.8 lvm-dumpconfig.8 lvm-fullreport.8 lvm-lvpoll.8 \
lvcreate.8 lvchange.8 lvmconfig.8 lvconvert.8 lvdisplay.8 lvextend.8 \
lvreduce.8 lvremove.8 lvrename.8 lvresize.8 lvs.8 \
lvscan.8 pvchange.8 pvck.8 pvcreate.8 pvdisplay.8 pvmove.8 pvremove.8 \
pvresize.8 pvs.8 pvscan.8 vgcfgbackup.8 vgcfgrestore.8 vgchange.8 \
vgck.8 vgcreate.8 vgconvert.8 vgdisplay.8 vgexport.8 vgextend.8 \
vgimport.8 vgimportclone.8 vgmerge.8 vgmknodes.8 vgreduce.8 vgremove.8 \
vgrename.8 vgs.8 vgscan.8 vgsplit.8 \
lvmsar.8 lvmsadc.8 lvmdiskscan.8 lvmchange.8
ifeq ($(MAKECMDGOALS),all_man)
MAN_ALL="yes"
@@ -56,7 +56,7 @@ endif
ifeq ($(MAN_ALL),"yes")
MAN8+=$(FSADMMAN) $(LVMETADMAN) $(LVMPOLLDMAN) $(LVMLOCKDMAN) $(LVMDBUSDMAN)
MAN8DM+=$(BLKDEACTIVATEMAN) $(DMEVENTDMAN) $(DMFILEMAPDMAN)
MAN8DM+=$(BLKDEACTIVATEMAN) $(DMEVENTDMAN)
MAN8CLUSTER+=$(CLVMDMAN) $(CMIRRORDMAN)
MAN7+=$(LVMCACHEMAN) $(LVMTHINMAN) $(LVMRAIDMAN)
else
@@ -88,10 +88,6 @@ else
MAN8DM+=$(DMEVENTDMAN)
endif
ifeq ("@DMFILEMAPD@", "yes")
MAN8DM+=$(DMFILEMAPDMAN)
endif
ifneq ("@CLVMD@", "none")
MAN8CLUSTER+=$(CLVMDMAN)
endif
@@ -117,74 +113,46 @@ MAN5DIR=$(mandir)/man5
MAN7DIR=$(mandir)/man7
MAN8DIR=$(mandir)/man8
MANGENERATOR=./man-generator
TESTMAN=test.gen
include $(top_builddir)/make.tmpl
CLEAN_TARGETS+=$(MAN5) $(MAN7) $(MAN8) $(MAN8:%.8_gen=%.8) $(MAN8CLUSTER) \
$(MAN8SYSTEMD_GENERATORS) $(MAN8DM) $(MANGENERATOR) $(TESTMAN)
CLEAN_TARGETS+=$(MAN5) $(MAN7) $(MAN8) $(MAN8GEN) $(MAN8CLUSTER) \
$(MAN8SYSTEMD_GENERATORS) $(MAN8DM) *.gen man-generator
DISTCLEAN_TARGETS+=$(FSADMMAN) $(BLKDEACTIVATEMAN) $(DMEVENTDMAN) \
$(LVMETADMAN) $(LVMPOLLDMAN) $(LVMLOCKDMAN) $(CLVMDMAN) $(CMIRRORDMAN) \
$(LVMCACHEMAN) $(LVMTHINMAN) $(LVMDBUSDMAN) $(LVMRAIDMAN) \
$(DMFILEMAPDMAN)
$(LVMCACHEMAN) $(LVMTHINMAN) $(LVMDBUSDMAN) $(LVMRAIDMAN)
all: man device-mapper
.PHONY: man install_man5 install_man7 install_man8 pregenerated_man
.PHONY: man install_man5 install_man7 install_man8
device-mapper: $(MAN8DM)
man: $(MAN5) $(MAN7) $(MAN8) $(MAN8CLUSTER) $(MAN8SYSTEMD_GENERATORS)
man: $(MAN5) $(MAN7) $(MAN8) $(MAN8GEN) $(MAN8CLUSTER) $(MAN8SYSTEMD_GENERATORS)
all_man: man
$(MAN5) $(MAN7) $(MAN8) $(MAN8DM) $(MAN8CLUSTER) $(MAN8SYSTEMD_GENERATORS): Makefile
$(MAN5) $(MAN7) $(MAN8) $(MAN8GEN) $(MAN8DM) $(MAN8CLUSTER): Makefile
$(MANGENERATOR): Makefile
Makefile: Makefile.in
@:
%: %.in
@case "$@" in \
*/*) ;; \
*) echo "Creating $@" ; $(SED) -e "s+#VERSION#+$(LVM_VERSION)+;s+#DEFAULT_SYS_DIR#+$(DEFAULT_SYS_DIR)+;s+#DEFAULT_ARCHIVE_DIR#+$(DEFAULT_ARCHIVE_DIR)+;s+#DEFAULT_BACKUP_DIR#+$(DEFAULT_BACKUP_DIR)+;s+#DEFAULT_PROFILE_DIR#+$(DEFAULT_PROFILE_DIR)+;s+#DEFAULT_CACHE_DIR#+$(DEFAULT_CACHE_DIR)+;s+#DEFAULT_LOCK_DIR#+$(DEFAULT_LOCK_DIR)+;s+#CLVMD_PATH#+@CLVMD_PATH@+;s+#LVM_PATH#+@LVM_PATH@+;s+#DEFAULT_RUN_DIR#+@DEFAULT_RUN_DIR@+;s+#DEFAULT_PID_DIR#+@DEFAULT_PID_DIR@+;s+#SYSTEMD_GENERATOR_DIR#+$(SYSTEMD_GENERATOR_DIR)+;s+#DEFAULT_MANGLING#+$(DEFAULT_MANGLING)+;" $< > $@ ;; \
esac
man-generator:
$(CC) -DMAN_PAGE_GENERATOR -I$(top_builddir)/tools $(CFLAGS) $(top_srcdir)/tools/command.c -o $@
- ./man-generator lvmconfig > test.gen
if [ ! -s test.gen ] ; then cp genfiles/*.gen $(top_builddir)/man; fi;
# Test whether or not the man page generator works
$(TESTMAN): $(MANGENERATOR)
- $(MANGENERATOR) --primary lvmconfig > $@
SEE_ALSO=$(srcdir)/see_also.end
%.8_gen: $(srcdir)/%.8_des $(srcdir)/%.8_end $(MANGENERATOR) $(TESTMAN)
( \
if [ ! -s $(TESTMAN) ] ; then \
echo "Copying pre-generated $@" ; \
else \
echo "Generating $@" ; \
fi \
)
( \
if [ ! -s $(TESTMAN) ] ; then \
cat $(srcdir)/$(@:%.8_gen=%.8_pregen) ; \
else \
MANCMD=$(basename $@) && \
$(MANGENERATOR) --primary $$MANCMD $< && \
$(MANGENERATOR) --secondary $$MANCMD && \
cat $(srcdir)/$(basename $@).8_end && \
cat $(SEE_ALSO) ; \
fi \
) > $@
define SUBSTVARS
echo "Generating $@" ; $(SED) -e "s+#VERSION#+$(LVM_VERSION)+;s+#DEFAULT_SYS_DIR#+$(DEFAULT_SYS_DIR)+;s+#DEFAULT_ARCHIVE_DIR#+$(DEFAULT_ARCHIVE_DIR)+;s+#DEFAULT_BACKUP_DIR#+$(DEFAULT_BACKUP_DIR)+;s+#DEFAULT_PROFILE_DIR#+$(DEFAULT_PROFILE_DIR)+;s+#DEFAULT_CACHE_DIR#+$(DEFAULT_CACHE_DIR)+;s+#DEFAULT_LOCK_DIR#+$(DEFAULT_LOCK_DIR)+;s+#CLVMD_PATH#+/data/lvmtest/usr/sbin/clvmd+;s+#LVM_PATH#+/data/lvmtest/sbin/lvm+;s+#DEFAULT_RUN_DIR#+/var/run/lvm+;s+#DEFAULT_PID_DIR#+/var/run+;s+#SYSTEMD_GENERATOR_DIR#+$(SYSTEMD_GENERATOR_DIR)+;s+#DEFAULT_MANGLING#+$(DEFAULT_MANGLING)+;" $< > $@
endef
%.5: $(srcdir)/%.5_main
$(SUBSTVARS)
%.7: $(srcdir)/%.7_main
$(SUBSTVARS)
%.8: $(srcdir)/%.8_main
$(SUBSTVARS)
%.8: %.8_gen
$(SUBSTVARS)
$(MAN8GEN): man-generator
echo "Generating $@" ;
if [ ! -e $@.gen ]; then ./man-generator $(basename $@) $(top_srcdir)/man/$@.des > $@.gen; fi
if [ -f $(top_srcdir)/man/$@.end ]; then cat $(top_srcdir)/man/$@.end >> $@.gen; fi;
cat $(top_srcdir)/man/see_also.end >> $@.gen
$(SED) -e "s+#VERSION#+$(LVM_VERSION)+;s+#DEFAULT_SYS_DIR#+$(DEFAULT_SYS_DIR)+;s+#DEFAULT_ARCHIVE_DIR#+$(DEFAULT_ARCHIVE_DIR)+;s+#DEFAULT_BACKUP_DIR#+$(DEFAULT_BACKUP_DIR)+;s+#DEFAULT_PROFILE_DIR#+$(DEFAULT_PROFILE_DIR)+;s+#DEFAULT_CACHE_DIR#+$(DEFAULT_CACHE_DIR)+;s+#DEFAULT_LOCK_DIR#+$(DEFAULT_LOCK_DIR)+;s+#CLVMD_PATH#+@CLVMD_PATH@+;s+#LVM_PATH#+@LVM_PATH@+;s+#DEFAULT_RUN_DIR#+@DEFAULT_RUN_DIR@+;s+#DEFAULT_PID_DIR#+@DEFAULT_PID_DIR@+;s+#SYSTEMD_GENERATOR_DIR#+$(SYSTEMD_GENERATOR_DIR)+;s+#DEFAULT_MANGLING#+$(DEFAULT_MANGLING)+;" $@.gen > $@
install_man5: $(MAN5)
$(INSTALL) -d $(MAN5DIR)
@@ -194,9 +162,10 @@ install_man7: $(MAN7)
$(INSTALL) -d $(MAN7DIR)
$(INSTALL_DATA) $(MAN7) $(MAN7DIR)/
install_man8: $(MAN8) $(MAN8GENERATED)
install_man8: $(MAN8) $(MAN8GEN)
$(INSTALL) -d $(MAN8DIR)
$(INSTALL_DATA) $(MAN8) $(MAN8GENERATED) $(MAN8DIR)/
$(INSTALL_DATA) $(MAN8) $(MAN8DIR)/
$(INSTALL_DATA) $(MAN8GEN) $(MAN8DIR)/
install_lvm2: install_man5 install_man7 install_man8
@@ -217,12 +186,3 @@ install_systemd_generators: $(MAN8SYSTEMD_GENERATORS)
install: install_lvm2 install_device-mapper install_cluster
install_all_man: install install_systemd_generators
# Copy generated man pages back to source tree as fallback for machines where generator doesn't work
pregenerated_man: all
for i in $(srcdir)/*.8_des; do \
CMD=`basename $$i .8_des`; \
cat $${CMD}.8 > $(srcdir)/$$CMD.8_pregen ; \
done
generate: pregenerated_man

View File

@@ -12,8 +12,8 @@ blkdeactivate \(em utility to deactivate block devices
.RB [ \-v ]
.RI [ device ]
.SH DESCRIPTION
The blkdeactivate utility deactivates block devices. For mounted
block devices, it attempts to unmount it automatically before
blkdeactivate utility deactivates block devices. If a device
is mounted, the utility can unmount it automatically before
trying to deactivate. The utility currently supports
device-mapper devices (DM), including LVM volumes and
software RAID MD devices. LVM volumes are handled directly
@@ -35,30 +35,30 @@ Force device removal.
.BR \-e ", " \-\-errors
Show errors reported from tools called by \fBblkdeactivate\fP. Without this
option, any error messages from these external tools are suppressed and the
\fBblkdeactivate\fP itself provides only a summary message to indicate
the device was skipped.
\fBblkdeactivate\fP itself provides only a summary message about device being
skipped or not.
.TP
.BR \-h ", " \-\-help
Display the help text.
.TP
.BR \-l ", " \-\-lvmoption \ \fIlvm_options\fP
Comma-separated list of LVM specific options:
Comma separated list of LVM specific options:
.RS
.IP \fIretry\fP
Retry removal several times in case of failure.
.IP \fIwholevg\fP
Deactivate the whole LVM Volume Group when processing a Logical Volume.
Deactivating the Volume Group as a whole is quicker than deactivating
each Logical Volume separately.
Deactivating Volume Group as a whole takes less time than deactivating each
Logical Volume separately.
.RE
.TP
.BR \-m ", " \-\-mpathoption \ \fImpath_options\fP
Comma-separated list of device-mapper multipath specific options:
Comma separated list of device-mapper multipath specific options:
.RS
.IP \fIdisablequeueing\fP
Disable queueing on all multipath devices before deactivation.
Disable queueing on all multipath devices first before deactivation.
This avoids a situation where blkdeactivate may end up waiting if
all the paths are unavailable for any underlying device-mapper multipath
all paths are unavailable for any underlying device-mapper multipath
device.
.RE
.TP
@@ -69,42 +69,33 @@ Without this option used, a device that is mounted is not deactivated.
.BR \-v ", " \-\-verbose
Run in verbose mode. Use \-\-vv for even more verbose mode.
.SH EXAMPLES
.
Deactivate all supported block devices found in the system, skipping mounted
devices.
.BR
#
.sp
Deactivate all supported block devices found in the system. If a device
is mounted, skip its deactivation.
.sp
.B blkdeactivate
.BR
.P
Deactivate all supported block devices found in the system, unmounting any
mounted devices first, if possible.
.BR
#
Deactivate all supported block devices found in the system. If a device
is mounted, unmount it first if possible.
.sp
.B blkdeactivate \-u
.BR
.P
Deactivate the device /dev/vg/lvol0 together with all its holders, unmounting
any mounted devices first, if possible.
.BR
#
Deactivate supplied device together with all its holders. If any of the
devices processed is mounted, unmount it first if possible.
.sp
.B blkdeactivate \-u /dev/vg/lvol0
.BR
.P
Deactivate all supported block devices found in the system. If the deactivation
of a device-mapper device fails, retry it. Deactivate the whole
Deactivate all supported block devices found in the system. Retry deactivation
of device-mapper devices in case the deactivation fails. Deactivate the whole
Volume Group at once when processing an LVM Logical Volume.
.BR
#
.sp
.B blkdeactivate \-u \-d retry \-l wholevg
.BR
.P
Deactivate all supported block devices found in the system. If the deactivation
of a device-mapper device fails, retry it and force removal.
.BR
#
Deactivate all supported block devices found in the system. Retry deactivation
of device-mapper devices in case the deactivation fails and force removal.
.sp
.B blkdeactivate \-d force,retry
.
.SH SEE ALSO
.BR dmsetup (8),
.BR lsblk (8),

View File

@@ -176,9 +176,9 @@ clvmd attempts to activate the LV only on the local node.
If the LV type allows concurrent access, then shared mode is used,
otherwise exclusive.
.IP \fBn\fP
clvmd attempts to deactivate the LV on all nodes.
clvmd deactivates the LV on all nodes.
.IP \fBln\fP
clvmd attempts to deactivate the LV on the local node.
clvmd deactivates the LV on the local node.
.
.SH ENVIRONMENT VARIABLES
.TP

110
man/dmeventd.8.in Normal file
View File

@@ -0,0 +1,110 @@
.TH DMEVENTD 8 "DM TOOLS #VERSION#" "Red Hat Inc" \" -*- nroff -*-
.
.SH NAME
.
dmeventd \(em Device-mapper event daemon
.
.SH SYNOPSIS
.
.B dmeventd
.RB [ \-d
.RB [ \-d
.RB [ \-d ]]]
.RB [ \-f ]
.RB [ \-h ]
.RB [ \-l ]
.RB [ \-R ]
.RB [ \-V ]
.RB [ \-? ]
.
.SH DESCRIPTION
.
dmeventd is the event monitoring daemon for device-mapper devices.
Library plugins can register and carry out actions triggered when
particular events occur.
.
.SH LVM PLUGINS
.
.HP
.IR Mirror
.br
Attempts to handle device failure automatically. See
.BR lvm.conf (5).
.
.HP
.IR Raid
.br
Attempts to handle device failure automatically. See
.BR lvm.conf (5).
.
.HP
.IR Snapshot
.br
Monitors how full a snapshot is becoming and emits a warning to
syslog when it exceeds 80% full.
The warning is repeated when 85%, 90% and 95% of the snapshot is filled.
See
.BR lvm.conf (5).
Snapshot which runs out of space gets invalid and when it is mounted,
it gets umounted if possible.
.
.HP
.IR Thin
.br
Monitors how full a thin pool data and metadata is becoming and emits
a warning to syslog when it exceeds 80% full.
The warning is repeated when 85%, 90% and 95% of the thin pool is filled.
See
.BR lvm.conf (5).
If the thin-pool runs out of space, thin volumes are umounted if possible.
.
.SH OPTIONS
.
.HP
.BR \-d
.br
Repeat from 1 to 3 times (
.BR \-d ,
.BR \-dd ,
.BR \-ddd
) to increase the detail of
debug messages sent to syslog.
Each extra d adds more debugging information.
.
.HP
.BR \-f
.br
Don't fork, run in the foreground.
.
.HP
.BR \-h
.br
Show help information.
.
.HP
.BR \-l
.br
Log through stdout and stderr instead of syslog.
This option works only with option \-f, otherwise it is ignored.
.
.HP
.BR \-?
.br
Show help information on stderr.
.
.HP
.BR \-R
.br
Replace a running dmeventd instance. The running dmeventd must be version
2.02.77 or newer. The new dmeventd instance will obtain a list of devices and
events to monitor from the currently running daemon.
.
.HP
.BR \-V
.br
Show version of dmeventd.
.
.SH SEE ALSO
.
.BR lvm (8),
.BR lvm.conf (5)

View File

@@ -1,150 +0,0 @@
.TH DMEVENTD 8 "DM TOOLS #VERSION#" "Red Hat Inc" \" -*- nroff -*-
.
.SH NAME
.
dmeventd \(em Device-mapper event daemon
.
.SH SYNOPSIS
.
.B dmeventd
.RB [ \-d
.RB [ \-d
.RB [ \-d ]]]
.RB [ \-f ]
.RB [ \-h ]
.RB [ \-l ]
.RB [ \-R ]
.RB [ \-V ]
.RB [ \-? ]
.
.SH DESCRIPTION
.
dmeventd is the event monitoring daemon for device-mapper devices.
Library plugins can register and carry out actions triggered when
particular events occur.
.
.
.SH OPTIONS
.
.HP
.BR \-d
.br
Repeat from 1 to 3 times (
.BR \-d ,
.BR \-dd ,
.BR \-ddd
) to increase the detail of
debug messages sent to syslog.
Each extra d adds more debugging information.
.
.HP
.BR \-f
.br
Don't fork, run in the foreground.
.
.HP
.BR \-h
.br
Show help information.
.
.HP
.BR \-l
.br
Log through stdout and stderr instead of syslog.
This option works only with option \-f, otherwise it is ignored.
.
.HP
.BR \-?
.br
Show help information on stderr.
.
.HP
.BR \-R
.br
Replace a running dmeventd instance. The running dmeventd must be version
2.02.77 or newer. The new dmeventd instance will obtain a list of devices and
events to monitor from the currently running daemon.
.
.HP
.BR \-V
.br
Show version of dmeventd.
.
.SH LVM PLUGINS
.
.HP
.BR Mirror
.br
Attempts to handle device failure automatically. See
.BR lvm.conf (5).
.
.HP
.BR Raid
.br
Attempts to handle device failure automatically. See
.BR lvm.conf (5).
.
.HP
.BR Snapshot
.br
Monitors how full a snapshot is becoming and emits a warning to
syslog when it exceeds 80% full.
The warning is repeated when 85%, 90% and 95% of the snapshot is filled.
See
.BR lvm.conf (5).
Snapshot which runs out of space gets invalid and when it is mounted,
it gets umounted if possible.
.
.HP
.BR Thin
.br
Monitors how full a thin pool data and metadata is becoming and emits
a warning to syslog when it exceeds 80% full.
The warning is repeated when more then 85%, 90% and 95%
of the thin pool is filled. See
.BR lvm.conf (5).
When a thin pool fills over 50% (data or metadata) thin plugin calls
configured \fIdmeventd/thin_command\fP with every 5% increase.
With default setting it calls internal
\fBlvm lvextend --use-policies\fP to resize thin pool
when it's been filled above configured threshold
\fIactivation/thin_pool_autoextend_threshold\fP.
If the command fails, dmeventd thin plugin will keep
retrying execution with increasing time delay between
retries upto 42 minutes.
User may also configure external command to support more advanced
maintenance operations of a thin pool.
Such external command can e.g. remove some unneeded snapshots,
use \fBfstrim\fP(8) to free recover space in a thin pool,
but also can use \fBlvextend --use-policies\fP if other actions
have not released enough space.
Command is executed with environmental variable
\fBLVM_RUN_BY_DMEVENTD=1\fP so any lvm2 command executed
in this environment will not try to interact with dmeventd.
To see the fullness of a thin pool command may check these
two environmental variables
\fBDMEVENTD_THIN_POOL_DATA\fP and \fBDMEVENTD_THIN_POOL_DATA\fP.
Command can also read status with tools like \fBlvs\fP(8).
.
.SH ENVIRONMENT VARIABLES
.
.TP
.B DMEVENTD_THIN_POOL_DATA
Variable is set by thin plugin and is available to executed program. Value present
actual usage of thin pool data volume. Variable is not set when error event
is processed.
.TP
.B DMEVENTD_THIN_POOL_DATA
Variable is set by thin plugin and is available to executed program. Value present
actual usage of thin pool metadata volume. Variable is not set when error event
is processed.
.TP
.B LVM_RUN_BY_DMEVENTD
Variable is set by thin plugin to prohibit recursive interation
with dmeventd by any executed lvm2 command from
a thin_command environment.
.
.SH SEE ALSO
.
.BR lvm (8),
.BR lvm.conf (5)

View File

@@ -1,212 +0,0 @@
.TH DMFILEMAPD 8 "Dec 17 2016" "Linux" "MAINTENANCE COMMANDS"
.de OPT_FD
. RB [ file_descriptor ]
..
.
.de OPT_GROUP
. RB [ group_id ]
..
.de OPT_PATH
. RB [ abs_path ]
..
.
.de OPT_MODE
. RB [ mode ]
..
.
.de OPT_DEBUG
. RB [ foreground [ verbose ] ]
..
.
.SH NAME
.
dmfilemapd \(em device-mapper filemap monitoring daemon
.
.SH SYNOPSIS
.
.de CMD_DMFILEMAPD
. ad l
. IR dmfilemapd
. OPT_FD
. OPT_GROUP
. OPT_PATH
. OPT_MODE
. OPT_DEBUG
. ad b
..
.CMD_DMFILEMAPD
.
.PD
.ad b
.
.SH DESCRIPTION
.
The dmfilemapd daemon monitors groups of \fIdmstats\fP regions that
correspond to the extents of a file, adding and removing regions to
reflect the changing state of the file on-disk.
The daemon is normally launched automatically by the \fPdmstats
create\fP command, but can be run manually, either to create a new
daemon where one did not previously exist, or to change the options
previously used, by killing the existing daemon and starting a new
one.
.
.SH OPTIONS
.
.HP
.BR file_descriptor
.br
Specify the file descriptor number for the file to be monitored.
The file descriptor must reference a regular file, open for reading,
in a local file system that supports the FIEMAP ioctl, and that
returns data describing the physical location of extents.
The process that executes \fBdmfilemapd\fP is responsible for
opening the file descriptor that is handed to the daemon.
.
.HP
.BR group_id
.br
The \fBdmstats\fP group identifier of the group that \fBdmfilemapd\fP
should update. The group must exist and it should correspond to
a set of regions created by a previous filemap operation.
.
.HP
.BR abs_path
.br
The absolute path to the file being monitored, at the time that
it was opened. The use of \fBpath\fP by the daemon differs,
depending on the filemap following mode in use; see \fBMODES\fP
and the \fBmode\fP option for more information.
.br
.HP
.BR mode
.br
The filemap monitoring mode the daemon should use: either "inode"
(\fBDM_FILEMAP_FOLLOW_INODE\fP), or "path"
(\fBDM_FILEMAP_FOLLOW_PATH\fP), to enable follow-inode or
follow-path mode respectively.
.
.HP
.BR [foreground]
.br
If set to 1, disable forking and allow the daemon to run in the
foreground.
.
.HP
.BR [verbose]
Control daemon logging. If set to zero, the daemon will close all
stdio streams and run silently. If \fBverbose\fP is a number
between 1 and 3, stdio will be retained and the daemon will log
messages to stdout and stderr that match the specified verbosity
level.
.
.
.SH MODES
.
The file map monitoring daemon can monitor files in two distinct
ways: the mode affects the behaviour of the daemon when a file
under monitoring is renamed or unlinked, and the conditions which
cause the daemon to terminate.
In both modes, the daemon will always shut down when the group
being monitored is deleted.
.P
.B Follow inode
.P
The daemon follows the inode of the file, as it was at the time the
daemon started. The file descriptor referencing the file is kept
open at all times, and the daemon will exit when it detects that
the file has been unlinked and it is the last holder of a reference
to the file.
This mode is useful if the file is expected to be renamed, or moved
within the file system, while it is being monitored.
.P
.B Follow path
.P
The daemon follows the path that was given on the daemon command
line. The file descriptor referencing the file is re-opened on each
iteration of the daemon, and the daemon will exit if no file exists
at this location (a tolerance is allowed so that a brief delay
between removal and replacement is permitted).
This mode is useful if the file is updated by unlinking the original
and placing a new file at the same path.
.
.SH LIMITATIONS
.
The daemon attempts to maintain good synchronisation between the file
extents and the regions contained in the group, however, since the
daemon can only react to new allocations once they have been written,
there are inevitably some IO events that cannot be counted when a
file is growing, particularly if the file is being extended by a
single thread writing beyond EOF (for example, the \fBdd\fP program).
There is a further loss of events in that there is currently no way
to atomically resize a \fBdmstats\fP region and preserve its current
counter values. This affects files when they grow by extending the
final extent, rather than allocating a new extent: any events that
had accumulated in the region between any prior operation and the
resize are lost.
File mapping is currently most effective in cases where the majority
of IO does not trigger extent allocation. Future updates may address
these limitations when kernel support is available.
.
.SH EXAMPLES
.
Normally the daemon is started automatically by the \fBdmstats\fP
\fBcreate\fP or \fBupdate_filemap\fP commands but it can be run
manually for debugging or testing purposes.
.P
Start the daemon in the background, in follow-path mode
.br
#
.B dmfilemapd 3 0 /srv/images/vm.img path 0 0 3< /srv/images/vm.img
.br
.P
Start the daemon in follow-inode mode, disable forking and enable
verbose logging
.br
#
.B dmfilemapd 3 0 /var/tmp/data inode 1 3 3< /var/tmp/data
.br
Starting dmfilemapd with fd=3, group_id=0 mode=inode, path=/var/tmp/data
.br
dm version [ opencount flush ] [16384] (*1)
.br
dm info (253:0) [ opencount flush ] [16384] (*1)
.br
dm message (253:0) [ opencount flush ] @stats_list dmstats [16384] (*1)
.br
Read alias 'data' from aux_data
.br
Found group_id 0: alias="data"
.br
dm_stats_walk_init: initialised flags to 4000000000000
.br
starting stats walk with GROUP
.br
exiting _filemap_monitor_get_events() with deleted=0, check=0
.br
Waiting for check interval
.br
.P
.
.SH AUTHORS
.
Bryn M. Reeves <bmr@redhat.com>
.
.SH SEE ALSO
.
.BR dmstats (8)
LVM2 resource page: https://www.sourceware.org/lvm2/
.br
Device-mapper resource page: http://sources.redhat.com/dm/
.br

View File

@@ -27,9 +27,9 @@ dmsetup \(em low level logical volume management
. IR uuid ]
. RB \%[ \-\-addnodeoncreate | \-\-addnodeonresume ]
. RB \%[ \-n | \-\-notable | \-\-table
. IR \%table | table_file ]
. RI \%{ table | table_file }]
. RB [ \-\-readahead
. RB \%[ + ] \fIsectors | auto | none ]
. RB \%{[ + ] \fIsectors | auto | none }]
. ad b
..
.CMD_CREATE
@@ -41,7 +41,7 @@ dmsetup \(em low level logical volume management
. BR deps
. RB [ \-o
. IR options ]
. RI [ device_name ...]
. RI [ device_name ]
. ad b
..
.CMD_DEPS
@@ -58,7 +58,7 @@ dmsetup \(em low level logical volume management
.B dmsetup
.de CMD_INFO
. BR info
. RI [ device_name ...]
. RI [ device_name ]
..
.CMD_INFO
.
@@ -92,7 +92,7 @@ dmsetup \(em low level logical volume management
. BR load
. IR device_name
. RB [ \-\-table
. IR table | table_file ]
. RI { table | table_file }]
. ad b
..
.CMD_LOAD
@@ -117,7 +117,7 @@ dmsetup \(em low level logical volume management
.B dmsetup
.de CMD_MANGLE
. BR mangle
. RI [ device_name ...]
. RI [ device_name ]
..
.CMD_MANGLE
.
@@ -135,7 +135,7 @@ dmsetup \(em low level logical volume management
.B dmsetup
.de CMD_MKNODES
. BR mknodes
. RI [ device_name ...]
. RI [ device_name ]
..
.CMD_MKNODES
.
@@ -146,7 +146,7 @@ dmsetup \(em low level logical volume management
. BR reload
. IR device_name
. RB [ \-\-table
. IR table | table_file ]
. RI { table | table_file }]
. ad b
..
.CMD_RELOAD
@@ -159,7 +159,7 @@ dmsetup \(em low level logical volume management
. RB [ \-f | \-\-force ]
. RB [ \-\-retry ]
. RB [ \-\-deferred ]
. IR device_name ...
. IR device_name
. ad b
..
.CMD_REMOVE
@@ -197,12 +197,12 @@ dmsetup \(em low level logical volume management
.de CMD_RESUME
. ad l
. BR resume
. IR device_name ...
. IR device_name
. RB [ \-\-addnodeoncreate | \-\-addnodeonresume ]
. RB [ \-\-noflush ]
. RB [ \-\-nolockfs ]
. RB \%[ \-\-readahead
. RB \%[ + ] \fIsectors | auto | none ]
. RB \%{[ + ] \fIsectors | auto | none }]
. ad b
..
.CMD_RESUME
@@ -247,7 +247,7 @@ dmsetup \(em low level logical volume management
. RB [ \-\-target
. IR target_type ]
. RB [ \-\-noflush ]
. RI [ device_name ...]
. RI [ device_name ]
. ad b
..
.CMD_STATUS
@@ -259,7 +259,7 @@ dmsetup \(em low level logical volume management
. BR suspend
. RB [ \-\-nolockfs ]
. RB [ \-\-noflush ]
. IR device_name ...
. IR device_name
. ad b
..
.CMD_SUSPEND
@@ -272,7 +272,7 @@ dmsetup \(em low level logical volume management
. RB [ \-\-target
. IR target_type ]
. RB [ \-\-showkeys ]
. RI [ device_name ...]
. RI [ device_name ]
. ad b
..
.CMD_TABLE
@@ -354,7 +354,7 @@ dmsetup \(em low level logical volume management
.de CMD_WIPE_TABLE
. ad l
. BR wipe_table
. IR device_name ...
. IR device_name
. RB [ \-f | \-\-force ]
. RB [ \-\-noflush ]
. RB [ \-\-nolockfs ]
@@ -447,7 +447,7 @@ The default interval is one second.
.
.HP
.BR \-\-manglename
.BR auto | hex | none
.RB { auto | hex | none }
.br
Mangle any character not on a whitelist using mangling_mode when
processing device-mapper device names and UUIDs. The names and UUIDs
@@ -529,7 +529,7 @@ Specify which fields to display.
.
.HP
.BR \-\-readahead
.RB [ + ] \fIsectors | auto | none
.RB {[ + ] \fIsectors | auto | none }
.br
Specify read ahead size in units of sectors.
The default value is \fBauto\fP which allows the kernel to choose

View File

@@ -14,9 +14,6 @@
. RB [ \-\-region ]
. RB [ \-\-group ]
..
.de OPT_FOREGROUND
. RB [ \-\-foreground ]
..
.
.\" Print units suffix, use with arg to print human
.\" man2html can't handle too many changes per command
@@ -47,7 +44,7 @@ dmstats \(em device-mapper statistics management
.B dmsetup
.B stats
.I command
[OPTIONS]
.RB [ options ]
.sp
.
.PD 0
@@ -56,13 +53,13 @@ dmstats \(em device-mapper statistics management
.de CMD_COMMAND
. ad l
. IR command
. IR device_name " |"
. BR \-\-major
. RI [ device_name |
. RB [ \-u | \-\-uuid
. IR uuid ]
. RB | [ \-\-major
. IR major
. BR \-\-minor
. IR minor " |"
. BR \-u | \-\-uuid
. IR uuid
. IR minor ]
. RB \%[ \-v | \-\-verbose]
. ad b
..
@@ -85,17 +82,15 @@ dmstats \(em device-mapper statistics management
.de CMD_CREATE
. ad l
. BR create
. IR device_name... | file_path... | \fB\-\-alldevices
. RB [ device_name...
. RB | file_path...
. RB | [ \-\-alldevices ]]
. RB [ \-\-areas
. IR nr_areas | \fB\-\-areasize
. IR area_size ]
. RB [ \-\-bounds
. IR \%histogram_boundaries ]
. RB [ \-\-filemap ]
. RB [ \-\-follow
. IR follow_mode ]
. OPT_FOREGROUND
. RB [ \-\-nomonitor ]
. RB [ \-\-nogroup ]
. RB [ \-\-precise ]
. RB [ \-\-start
@@ -115,7 +110,8 @@ dmstats \(em device-mapper statistics management
.de CMD_DELETE
. ad l
. BR delete
. IR device_name | \fB\-\-alldevices
. RI [ device_name ]
. RB [ \-\-alldevices ]
. OPT_PROGRAMS
. OPT_REGIONS
. ad b
@@ -127,9 +123,10 @@ dmstats \(em device-mapper statistics management
.de CMD_GROUP
. ad l
. BR group
. RI [ device_name | \fB\-\-alldevices ]
. RI [ device_name ]
. RB [ \-\-alias
. IR name ]
. RB [ \-\-alldevices ]
. RB [ \-\-regions
. IR regions ]
. ad b
@@ -208,7 +205,8 @@ dmstats \(em device-mapper statistics management
.de CMD_UNGROUP
. ad l
. BR ungroup
. RI [ device_name | \fB\-\-alldevices ]
. RI [ device_name ]
. RB [ \-\-alldevices ]
. RB [ \-\-groupid
. IR id ]
. ad b
@@ -219,12 +217,9 @@ dmstats \(em device-mapper statistics management
.de CMD_UPDATE_FILEMAP
. ad l
. BR update_filemap
. IR file_path
. RI file_path
. RB [ \-\-groupid
. IR id ]
. RB [ \-\-follow
. IR follow_mode ]
. OPT_FOREGROUND
. ad b
..
.CMD_UPDATE_FILEMAP
@@ -324,60 +319,6 @@ create regions corresponding to the locations of the on-disk extents
allocated to the file(s).
.
.HP
.BR \-\-nomonitor
.br
Disable the \fBdmfilemapd\fP daemon when creating new file mapped
groups. Normally the device-mapper filemap monitoring daemon,
\fBdmfilemapd\fP, is started for each file mapped group to update the
set of regions as the file changes on-disk: use of this option
disables this behaviour.
Regions in the group may still be updated with the
\fBupdate_filemap\fP command, or by starting the daemon manually.
.
.HP
.BR \-\-follow
.IR follow_mode
.br
Specify the \fBdmfilemapd\fP file following mode. The file map
monitoring daemon can monitor files in two distinct ways: the mode
affects the behaviour of the daemon when a file under monitoring is
renamed or unlinked, and the conditions which cause the daemon to
terminate.
The \fBfollow_mode\fP argument is either "inode", for follow-inode
mode, or "path", for follow-path.
If follow-inode mode is used, the daemon will hold the file open, and
continue to update regions from the same file descriptor. This means
that the mapping will follow rename, move (within the same file
system), and unlink operations. This mode is useful if the file is
expected to be moved, renamed, or unlinked while it is being
monitored.
In follow-inode mode, the daemon will exit once it detects that the
file has been unlinked and it is the last holder of a reference to it.
If follow-path is used, the daemon will re-open the provided path on
each monitoring iteration. This means that the group will be updated
to reflect a new file being moved to the same path as the original
file. This mode is useful for files that are expected to be updated
via unlink and rename.
In follow-path mode, the daemon will exit if the file is removed and
not replaced within a brief tolerance interval.
In either mode, the daemon exits automatically if the monitored group
is removed.
.
.HP
.BR \-\-foreground
.br
Specify that the \fBdmfilemapd\fP daemon should run in the foreground.
The daemon will not fork into the background, and will replace the
\fBdmstats\fP command that started it.
.
.HP
.BR \-\-groupid
.IR id
.br
@@ -632,11 +573,6 @@ By default regions that map a file are placed into a group and the
group alias is set to the basename of the file. This behaviour can be
overridden with the \fB\-\-alias\fP and \fB\-\-nogroup\fP options.
Creating a group that maps a file automatically starts a daemon,
\fBdmfilemapd\fP to monitor the file and update the mapping as the
extents allocated to the file change. This behaviour can be disabled
using the \fB\-\-nomonitor\fP option.
Use the \fB\-\-group\fP option to only display information for groups
when listing and reporting.
.
@@ -747,23 +683,17 @@ The group to be removed is specified using \fB\-\-groupid\fP.
.CMD_UPDATE_FILEMAP
.br
Update a group of \fBdmstats\fP regions specified by \fBgroup_id\fP,
that were previously created with \fB\-\-filemap\fP, either directly,
or by starting the monitoring daemon, \fBdmfilemapd\fP.
This will add and remove regions to reflect changes in the allocated
extents of the file on-disk, since the time that it was crated or last
updated.
that were previously created with \fB\-\-filemap\fP. This will add
and remove regions to reflect changes in the allocated extents of
the file on-disk, since the time that it was crated or last updated.
Use of this command is not normally needed since the \fBdmfilemapd\fP
daemon will automatically monitor filemap groups and perform these
updates when required.
If a filemapped group was created with \fB\-\-nomonitor\fP, or the
If a filemapped group was created with \fB\-\-nominitor\fP, or the
daemon has been killed, the \fBupdate_filemap\fP can be used to
manually force an update or start a new daemon.
Use \fB\-\-nomonitor\fP to force a direct update and disable starting
the monitoring daemon.
manually force an update.
.
.SH REGIONS, AREAS, AND GROUPS
.
@@ -825,93 +755,6 @@ containing device.
The \fBgroup_id\fP should be treated as an opaque identifier used to
reference the group.
.
.SH FILE MAPPING
.
Using \fB\-\-filemap\fP, it is possible to create regions that
correspond to the extents of a file in the file system. This allows
IO statistics to be monitored on a per-file basis, for example to
observe large database files, virtual machine images, or other files
of interest.
To be able to use file mapping, the file must be backed by a
device-mapper device, and in a file system that supports the FIEMAP
ioctl (and which returns data describing the physical location of
extents). This currently includes \fBxfs(5)\fP and \fBext4(5)\fP.
By default the regions making up a file are placed together in a
group, and the group alias is set to the \fBbasename(3)\fP of the
file. This allows statistics to be reported for the file as a whole,
aggregating values for the regions making up the group. To see only
the whole file (group) when using the \fBlist\fP and \fBreport\fP
commands, use \fB\-\-group\fP.
Since it is possible for the file to change after the initial
group of regions is created, the \fBupdate_filemap\fP command, and
\fBdmfilemapd\fP daemon are provided to update file mapped groups
either manually or automatically.
.
.P
.B File follow modes
.P
The file map monitoring daemon can monitor files in two distinct ways:
follow-inode mode, and follow-path mode.
The mode affects the behaviour of the daemon when a file under
monitoring is renamed or unlinked, and the conditions which cause the
daemon to terminate.
If follow-inode mode is used, the daemon will hold the file open, and
continue to update regions from the same file descriptor. This means
that the mapping will follow rename, move (within the same file
system), and unlink operations. This mode is useful if the file is
expected to be moved, renamed, or unlinked while it is being
monitored.
In follow-inode mode, the daemon will exit once it detects that the
file has been unlinked and it is the last holder of a reference to it.
If follow-path is used, the daemon will re-open the provided path on
each monitoring iteration. This means that the group will be updated
to reflect a new file being moved to the same path as the original
file. This mode is useful for files that are expected to be updated
via unlink and rename.
In follow-path mode, the daemon will exit if the file is removed and
not replaced within a brief tolerance interval (one second).
To stop the daemon, delete the group containing the mapped regions:
the daemon will automatically shut down.
The daemon can also be safely killed at any time and the group kept:
if the file is still being allocated the mapping will become
progressively out-of-date as extents are added and removed (in this
case the daemon can be re-started or the group updated manually with
the \fBupdate_filemap\fP command).
See the \fBcreate\fP command and \fB\-\-filemap\fP, \fB\-\-follow\fP,
and \fB\-\-nomonitor\fP options for further information.
.
.P
.B Limitations
.P
The daemon attempts to maintain good synchronisation between the file
extents and the regions contained in the group, however, since it can
only react to new allocations once they have been written, there are
inevitably some IO events that cannot be counted when a file is
growing, particularly if the file is being extended by a single thread
writing beyond end-of-file (for example, the \fBdd\fP program).
There is a further loss of events in that there is currently no way
to atomically resize a \fBdmstats\fP region and preserve its current
counter values. This affects files when they grow by extending the
final extent, rather than allocating a new extent: any events that
had accumulated in the region between any prior operation and the
resize are lost.
File mapping is currently most effective in cases where the majority
of IO does not trigger extent allocation. Future updates may address
these limitations when kernel support is available.
.
.SH REPORT FIELDS
.
The dmstats report provides several types of field that may be added to

View File

@@ -1,4 +1,6 @@
.SH EXAMPLES
Change LV permission to read-only:
.sp
.B lvchange \-pr vg00/lvol1

File diff suppressed because it is too large Load Diff

38
man/lvconvert.8.des Normal file
View File

@@ -0,0 +1,38 @@
lvconvert changes the LV type and includes utilities for LV data
maintenance. The LV type controls data layout and redundancy.
The LV type is also called the segment type or segtype.
To display the current LV type, run the command:
.B lvs \-o name,segtype
.I LV
The
.B linear
type is equivalent to the
.B striped
type when one stripe exists.
In that case, the types can sometimes be used interchangably.
In most cases, the
.B mirror
type is deprecated and the
.B raid1
type should be used. They are both implementations of mirroring.
The
.B raid*
type refers to one of many raid levels, e.g.
.B raid1,
.B raid5.
In some cases, an LV is a single device mapper (dm) layer above physical
devices. In other cases, hidden LVs (dm devices) are layered between the
visible LV and physical devices. LVs in the middle layers are called sub LVs.
A command run on a visible LV sometimes operates on a sub LV rather than
the specified LV. In other cases, a sub LV must be specified directly on
the command line.
Sub LVs can be displayed with the command
.B lvs -a

View File

@@ -1,23 +1,5 @@
.SH NOTES
This previous command syntax would perform two different operations:
.br
\fBlvconvert --thinpool\fP \fILV1\fP \fB--poolmetadata\fP \fILV2\fP
.br
If LV1 was not a thin pool, the command would convert LV1 to
a thin pool, optionally using a specified LV for metadata.
But, if LV1 was already a thin pool, the command would swap
the current metadata LV with LV2 (for repair purposes.)
In the same way, this previous command syntax would perform two different
operations:
.br
\fBlvconvert --cachepool\fP \fILV1\fP \fB--poolmetadata\fP \fILV2\fP
.br
If LV1 was not a cache pool, the command would convert LV1 to
a cache pool, optionally using a specified LV for metadata.
But, if LV1 was already a cache pool, the command would swap
the current metadata LV with LV2 (for repair purposes.)
.SH EXAMPLES
Convert a linear LV to a two-way mirror LV.
.br
.B lvconvert \-\-type mirror \-\-mirrors 1 vg/lvol1
@@ -110,3 +92,4 @@ Detach and keep the cache pool from a cache LV.
Detach and remove the cache pool from a cache LV.
.br
.B lvconvert \-\-uncache vg/lvol1

View File

@@ -1,64 +0,0 @@
lvconvert changes the LV type and includes utilities for LV data
maintenance. The LV type controls data layout and redundancy.
The LV type is also called the segment type or segtype.
To display the current LV type, run the command:
.B lvs \-o name,segtype
.I LV
The
.B linear
type is equivalent to the
.B striped
type when one stripe exists.
In that case, the types can sometimes be used interchangably.
In most cases, the
.B mirror
type is deprecated and the
.B raid1
type should be used. They are both implementations of mirroring.
In some cases, an LV is a single device mapper (dm) layer above physical
devices. In other cases, hidden LVs (dm devices) are layered between the
visible LV and physical devices. LVs in the middle layers are called sub LVs.
A command run on a visible LV sometimes operates on a sub LV rather than
the specified LV. In other cases, a sub LV must be specified directly on
the command line.
Striped raid types are
.B raid0/raid0_meta
,
.B raid5
(an alias for raid5_ls),
.B raid6
(an alias for raid6_zr) and
.B raid10
(an alias for raid10_near).
As opposed to mirroring, raid5 and raid6 stripe data and calculate parity
blocks. The parity blocks can be used for data block recovery in case devices
fail. A maximum number of one device in a raid5 LV may fail and two in case
of raid6. Striped raid types typically rotate the parity blocks for performance
reasons thus avoiding contention on a single device. Layouts of raid5 rotating
parity blocks can be one of left-asymmetric (raid5_la), left-symmetric (raid5_ls
with alias raid5), right-asymmetric (raid5_ra), right-symmetric (raid5_rs) and raid5_n,
which doesn't rotate parity blocks. Any \"_n\" layouts allow for conversion between
raid levels (raid5_n -> raid6 or raid5_n -> striped/raid0/raid0_meta).
raid6 layouts are zero-restart (raid6_zr with alias raid6), next-restart (raid6_nr),
next-continue (raid6_nc). Additionally, special raid6 layouts for raid level conversions
between raid5 and raid6 are raid6_ls_6, raid6_rs_6, raid6_la_6 and raid6_ra_6. Those
correspond to their raid5 counterparts (e.g. raid5_rs can be directly converted to raid6_rs_6
and vice-versa).
raid10 (an alias for raid10_near) is currently limited to one data copy and even number of
sub LVs. This is a mirror group layout thus a single sub LV may fail per mirror group
without data loss.
Striped raid types support converting the layout, their stripesize
and their number of stripes.
The striped raid types combined with raid1 allow for conversion from linear -> striped/raid0/raid0_meta
and vice-versa by e.g. linear <-> raid1 <-> raid5_n (then adding stripes) <-> striped/raid0/raid0_meta.
Sub LVs can be displayed with the command
.B lvs -a

File diff suppressed because it is too large Load Diff

View File

@@ -25,12 +25,4 @@ Thin LVs are thinly provisioned from a thin pool, and are created with a
virtual size rather than a physical size. A cache LV is the combination of
a standard LV with a cache pool, used to cache active portions of the LV
to improve performance.
.SS Usage notes
In the usage section below, \fB--size\fP \fISize\fP can be replaced
with \fB--extents\fP \fINumber\fP. See both descriptions
the options section.
In the usage section below, \fB--name\fP is omitted from the required
options, even though it is typically used. When the name is not
specified, a new LV name is generated with the "lvol" prefix and a unique
numeric suffix. Also see the description in the options section.

View File

@@ -95,3 +95,4 @@ then combining the new origin LV with an existing cache pool.
.RS
.B \-L 100G \-n mylv vg00 /dev/slow1
.RE

File diff suppressed because it is too large Load Diff

View File

View File

@@ -1,579 +0,0 @@
.TH LVDISPLAY 8 "LVM TOOLS 2.02.169(2)-git (2016-11-30)" "Red Hat, Inc."
.SH NAME
lvdisplay \- Display information about a logical volume
.
.SH SYNOPSIS
\fBlvdisplay\fP
.br
[ \fIoption_args\fP ]
.br
[ \fIposition_args\fP ]
.br
.SH DESCRIPTION
lvdisplay shows the attributes of LVs, like size, read/write status,
snapshot information, etc.
\fBlvs\fP(8) is a preferred alternative that shows the same information
and more, using a more compact and configurable output format.
.SH USAGE
\fBlvdisplay\fP
.br
.RS 4
.ad l
[ \fB-a\fP|\fB--all\fP ]
.ad b
.br
.ad l
[ \fB-c\fP|\fB--colon\fP ]
.ad b
.br
.ad l
[ \fB-C\fP|\fB--columns\fP ]
.ad b
.br
.ad l
[ \fB-H\fP|\fB--history\fP ]
.ad b
.br
.ad l
[ \fB-m\fP|\fB--maps\fP ]
.ad b
.br
.ad l
[ \fB-o\fP|\fB--options\fP \fIString\fP ]
.ad b
.br
.ad l
[ \fB-O\fP|\fB--sort\fP \fIString\fP ]
.ad b
.br
.ad l
[ \fB-P\fP|\fB--partial\fP ]
.ad b
.br
.ad l
[ \fB-S\fP|\fB--select\fP \fIString\fP ]
.ad b
.br
.ad l
[ \fB--aligned\fP ]
.ad b
.br
.ad l
[ \fB--binary\fP ]
.ad b
.br
.ad l
[ \fB--configreport\fP \fBlog\fP|\fBvg\fP|\fBlv\fP|\fBpv\fP|\fBpvseg\fP|\fBseg\fP ]
.ad b
.br
.ad l
[ \fB--foreign\fP ]
.ad b
.br
.ad l
[ \fB--ignorelockingfailure\fP ]
.ad b
.br
.ad l
[ \fB--ignoreskippedcluster\fP ]
.ad b
.br
.ad l
[ \fB--logonly\fP ]
.ad b
.br
.ad l
[ \fB--noheadings\fP ]
.ad b
.br
.ad l
[ \fB--nosuffix\fP ]
.ad b
.br
.ad l
[ \fB--readonly\fP ]
.ad b
.br
.ad l
[ \fB--reportformat\fP \fBbasic\fP|\fBjson\fP ]
.ad b
.br
.ad l
[ \fB--segments\fP ]
.ad b
.br
.ad l
[ \fB--separator\fP \fIString\fP ]
.ad b
.br
.ad l
[ \fB--shared\fP ]
.ad b
.br
.ad l
[ \fB--unbuffered\fP ]
.ad b
.br
.ad l
[ \fB--units\fP \fBr\fP|\fBR\fP|\fBh\fP|\fBH\fP|\fBb\fP|\fBB\fP|\fBs\fP|\fBS\fP|\fBk\fP|\fBK\fP|\fBm\fP|\fBM\fP|\fBg\fP|\fBG\fP|\fBt\fP|\fBT\fP|\fBp\fP|\fBP\fP|\fBe\fP|\fBE\fP ]
.ad b
.br
[ COMMON_OPTIONS ]
.RE
.br
.RS 4
[ \fIVG\fP|\fILV\fP|\fITag\fP ... ]
.RE
Common options for lvm:
.
.RS 4
.ad l
[ \fB-d\fP|\fB--debug\fP ]
.ad b
.br
.ad l
[ \fB-h\fP|\fB--help\fP ]
.ad b
.br
.ad l
[ \fB-q\fP|\fB--quiet\fP ]
.ad b
.br
.ad l
[ \fB-t\fP|\fB--test\fP ]
.ad b
.br
.ad l
[ \fB-v\fP|\fB--verbose\fP ]
.ad b
.br
.ad l
[ \fB-y\fP|\fB--yes\fP ]
.ad b
.br
.ad l
[ \fB--commandprofile\fP \fIString\fP ]
.ad b
.br
.ad l
[ \fB--config\fP \fIString\fP ]
.ad b
.br
.ad l
[ \fB--driverloaded\fP \fBy\fP|\fBn\fP ]
.ad b
.br
.ad l
[ \fB--longhelp\fP ]
.ad b
.br
.ad l
[ \fB--profile\fP \fIString\fP ]
.ad b
.br
.ad l
[ \fB--version\fP ]
.ad b
.RE
.SH OPTIONS
.HP
.ad l
\fB--aligned\fP
.br
Use with --separator to align the output columns
.ad b
.HP
.ad l
\fB-a\fP|\fB--all\fP
.br
Show information about internal LVs.
These are components of normal LVs, such as mirrors,
which are not independently accessible, e.g. not mountable.
.ad b
.HP
.ad l
\fB--binary\fP
.br
Use binary values "0" or "1" instead of descriptive literal values
for columns that have exactly two valid values to report (not counting
the "unknown" value which denotes that the value could not be determined).
.ad b
.HP
.ad l
\fB-c\fP|\fB--colon\fP
.br
Generate colon separated output for easier parsing in scripts or programs.
Also see vgs(8) which provides considerably more control over the output.
.ad b
.HP
.ad l
\fB-C\fP|\fB--columns\fP
.br
Display output in columns, the equivalent of vgs(8).
Options listed are the same as options given in vgs(8).
.ad b
.HP
.ad l
\fB--commandprofile\fP \fIString\fP
.br
The command profile to use for command configuration.
See \fBlvm.conf\fP(5) for more information about profiles.
.ad b
.HP
.ad l
\fB--config\fP \fIString\fP
.br
Config settings for the command. These override lvm.conf settings.
The String arg uses the same format as lvm.conf,
or may use section/field syntax.
See \fBlvm.conf\fP(5) for more information about config.
.ad b
.HP
.ad l
\fB--configreport\fP \fBlog\fP|\fBvg\fP|\fBlv\fP|\fBpv\fP|\fBpvseg\fP|\fBseg\fP
.br
See lvmreport(7).
.ad b
.HP
.ad l
\fB-d\fP|\fB--debug\fP ...
.br
Set debug level. Repeat from 1 to 6 times to increase the detail of
messages sent to the log file and/or syslog (if configured).
.ad b
.HP
.ad l
\fB--driverloaded\fP \fBy\fP|\fBn\fP
.br
If set to no, the command will not attempt to use device-mapper.
For testing and debugging.
.ad b
.HP
.ad l
\fB--foreign\fP
.br
Report/display foreign VGs that would otherwise be skipped.
See lvmsystemid(7) for more information about foreign VGs.
.ad b
.HP
.ad l
\fB-h\fP|\fB--help\fP
.br
Display help text.
.ad b
.HP
.ad l
\fB-H\fP|\fB--history\fP
.br
Include historical LVs in the output.
(This has no effect unless LVs were removed while
lvm.conf metadata/record_lvs_history was enabled.
.ad b
.HP
.ad l
\fB--ignorelockingfailure\fP
.br
Allows a command to continue with read-only metadata
operations after locking failures.
.ad b
.HP
.ad l
\fB--ignoreskippedcluster\fP
.br
Use to avoid exiting with an non-zero status code if the command is run
without clustered locking and clustered VGs are skipped.
.ad b
.HP
.ad l
\fB--logonly\fP
.br
Suppress command report and display only log report.
.ad b
.HP
.ad l
\fB--longhelp\fP
.br
Display long help text.
.ad b
.HP
.ad l
\fB-m\fP|\fB--maps\fP
.br
Display the mapping of logical extents to PVs and physical extents.
To map physical extents to logical extents use:
pvs --segments -o+lv_name,seg_start_pe,segtype
.ad b
.HP
.ad l
\fB--noheadings\fP
.br
Suppress the headings line that is normally the first line of output.
Useful if grepping the output.
.ad b
.HP
.ad l
\fB--nosuffix\fP
.br
Suppress the suffix on output sizes. Use with --units
(except h and H) if processing the output.
.ad b
.HP
.ad l
\fB-o\fP|\fB--options\fP \fIString\fP
.br
Comma-separated, ordered list of fields to display in columns.
String arg syntax is: [+|-|#]Field1[,Field2 ...]
The prefix \fB+\fP will append the specified fields to the default fields,
\fB-\fP will remove the specified fields from the default fields, and
\fB#\fP will compact specified fields (removing them when empty for all rows.)
Use \fB-o help\fP to view the list of all available fields.
Use separate lists of fields to add, remove or compact by repeating the -o option:
-o+field1,field2 -o-field3,field4 -o#field5.
These lists are evaluated from left to right.
Use field name \fBlv_all\fP to view all LV fields,
\fBvg_all\fP all VG fields,
\fBpv_all\fP all PV fields,
\fBpvseg_all\fP all PV segment fields,
\fBseg_all\fP all LV segment fields, and
\fBpvseg_all\fP all PV segment columns.
See the lvm.conf report section for more config options.
See lvmreport(7) for more information about reporting.
.ad b
.HP
.ad l
\fB-P\fP|\fB--partial\fP
.br
When set, the tools will do their best to provide access to VGs
that are only partially available (one or more PVs belonging
to the VG are missing from the system). Metadata may not be
changed with this option.
.ad b
.HP
.ad l
\fB--profile\fP \fIString\fP
.br
An alias for --commandprofile or --metadataprofile, depending
on the command.
.ad b
.HP
.ad l
\fB-q\fP|\fB--quiet\fP ...
.br
Suppress output and log messages. Overrides --debug and --verbose.
Repeat once to also suppress any prompts with answer no.
.ad b
.HP
.ad l
\fB--readonly\fP
.br
Run the command in a special read-only mode which will read on-disk
metadata without needing to take any locks. This can be used to peek
inside metadata used by a virtual machine image while the virtual
machine is running.
It can also be used to peek inside the metadata of clustered VGs
when clustered locking is not configured or running. No attempt
will be made to communicate with the device-mapper kernel driver, so
this option is unable to report whether or not LVs are
actually in use.
.ad b
.HP
.ad l
\fB--reportformat\fP \fBbasic\fP|\fBjson\fP
.br
Overrides current output format for reports which is defined globally by
the report/output_format setting in lvm.conf.
\fBbasic\fP is the original format with columns and rows.
If there is more than one report per command, each report is prefixed
with the report name for identification. \fBjson\fP produces report
output in JSON format. See \fBlvmreport\fP(7) for more information.
.ad b
.HP
.ad l
\fB--segments\fP
.br
.ad b
.HP
.ad l
\fB-S\fP|\fB--select\fP \fIString\fP
.br
Select objects for processing and reporting based on specified criteria.
The criteria syntax is described by \fB--select help\fP and \fBlvmreport\fP(7).
For reporting commands, one row is displayed for each object matching the criteria.
See \fB--options help\fP for selectable object fields.
Rows can be displayed with an additional "selected" field (-o selected)
showing 1 if the row matches the selection and 0 otherwise.
For non-reporting commands which process LVM entities, the selection is
used to choose items to process.
.ad b
.HP
.ad l
\fB--separator\fP \fIString\fP
.br
String to use to separate each column. Useful if grepping the output.
.ad b
.HP
.ad l
\fB--shared\fP
.br
Report/display shared VGs that would otherwise be skipped when
lvmlockd is not being used on the host.
See lvmlockd(8) for more information about shared VGs.
.ad b
.HP
.ad l
\fB-O\fP|\fB--sort\fP \fIString\fP
.br
Comma-separated ordered list of columns to sort by. Replaces the default
selection. Precede any column with \fB-\fP for a reverse sort on that column.
.ad b
.HP
.ad l
\fB-t\fP|\fB--test\fP
.br
Run in test mode. Commands will not update metadata.
This is implemented by disabling all metadata writing but nevertheless
returning success to the calling function. This may lead to unusual
error messages in multi-stage operations if a tool relies on reading
back metadata it believes has changed but hasn't.
.ad b
.HP
.ad l
\fB--unbuffered\fP
.br
Produce output immediately without sorting or aligning the columns properly.
.ad b
.HP
.ad l
\fB--units\fP \fBr\fP|\fBR\fP|\fBh\fP|\fBH\fP|\fBb\fP|\fBB\fP|\fBs\fP|\fBS\fP|\fBk\fP|\fBK\fP|\fBm\fP|\fBM\fP|\fBg\fP|\fBG\fP|\fBt\fP|\fBT\fP|\fBp\fP|\fBP\fP|\fBe\fP|\fBE\fP
.br
All sizes are output in these units:
human-(r)eadable with '<' rounding indicator,
(h)uman-readable, (b)ytes, (s)ectors, (k)ilobytes, (m)egabytes,
(g)igabytes, (t)erabytes, (p)etabytes, (e)xabytes.
Capitalise to use multiples of 1000 (S.I.) instead of 1024.
Custom units can be specified, e.g. --units 3M.
.ad b
.HP
.ad l
\fB-v\fP|\fB--verbose\fP ...
.br
Set verbose level. Repeat from 1 to 4 times to increase the detail
of messages sent to stdout and stderr.
.ad b
.HP
.ad l
\fB--version\fP
.br
Display version information.
.ad b
.HP
.ad l
\fB-y\fP|\fB--yes\fP
.br
Do not prompt for confirmation interactively but always assume the
answer yes. Use with extreme caution.
(For automatic no, see -qq.)
.ad b
.SH VARIABLES
.HP
\fIVG\fP
.br
Volume Group name. See \fBlvm\fP(8) for valid names.
.HP
\fILV\fP
.br
Logical Volume name. See \fBlvm\fP(8) for valid names.
An LV positional arg generally includes the VG name and LV name, e.g. VG/LV.
.HP
\fITag\fP
.br
Tag name. See \fBlvm\fP(8) for information about tag names and using tags
in place of a VG, LV or PV.
.HP
\fIString\fP
.br
See the option description for information about the string content.
.HP
\fISize\fP[UNIT]
.br
Size is an input number that accepts an optional unit.
Input units are always treated as base two values, regardless of
capitalization, e.g. 'k' and 'K' both refer to 1024.
The default input unit is specified by letter, followed by |UNIT.
UNIT represents other possible input units: \fBbBsSkKmMgGtTpPeE\fP.
b|B is bytes, s|S is sectors of 512 bytes, k|K is kilobytes,
m|M is megabytes, g|G is gigabytes, t|T is terabytes,
p|P is petabytes, e|E is exabytes.
(This should not be confused with the output control --units, where
capital letters mean multiple of 1000.)
.SH ENVIRONMENT VARIABLES
See \fBlvm\fP(8) for information about environment variables used by lvm.
For example, LVM_VG_NAME can generally be substituted for a required VG parameter.
.SH SEE ALSO
.BR lvm (8)
.BR lvm.conf (5)
.BR lvmconfig (8)
.BR pvchange (8)
.BR pvck (8)
.BR pvcreate (8)
.BR pvdisplay (8)
.BR pvmove (8)
.BR pvremove (8)
.BR pvresize (8)
.BR pvs (8)
.BR pvscan (8)
.BR vgcfgbackup (8)
.BR vgcfgrestore (8)
.BR vgchange (8)
.BR vgck (8)
.BR vgcreate (8)
.BR vgconvert (8)
.BR vgdisplay (8)
.BR vgexport (8)
.BR vgextend (8)
.BR vgimport (8)
.BR vgimportclone (8)
.BR vgmerge (8)
.BR vgmknodes (8)
.BR vgreduce (8)
.BR vgremove (8)
.BR vgrename (8)
.BR vgs (8)
.BR vgscan (8)
.BR vgsplit (8)
.BR lvcreate (8)
.BR lvchange (8)
.BR lvconvert (8)
.BR lvdisplay (8)
.BR lvextend (8)
.BR lvreduce (8)
.BR lvremove (8)
.BR lvrename (8)
.BR lvresize (8)
.BR lvs (8)
.BR lvscan (8)
.BR lvm2-activation-generator (8)
.BR blkdeactivate (8)
.BR lvmdump (8)
.BR dmeventd (8)
.BR lvmetad (8)
.BR lvmpolld (8)
.BR lvmlockd (8)
.BR lvmlockctl (8)
.BR clvmd (8)
.BR cmirrord (8)
.BR lvmdbusd (8)
.BR lvmsystemid (7)
.BR lvmreport (7)
.BR lvmraid (7)
.BR lvmthin (7)
.BR lvmcache (7)

5
man/lvextend.8.des Normal file
View File

@@ -0,0 +1,5 @@
lvextend extends the size of an LV. This requires allocating logical
extents from the VG's free physical extents. A copy\-on\-write snapshot LV
can also be extended to provide more space to hold COW blocks. Use
\fBlvconvert\fP(8) to change the number of data images in a RAID or
mirrored LV.

View File

@@ -1,4 +1,5 @@
.SH EXAMPLES
Extend the size of an LV by 54MiB, using a specific PV.
.br
.B lvextend \-L +54 vg01/lvol10 /dev/sdk3
@@ -12,3 +13,4 @@ space on PV /dev/sdk3. This is equivalent to specifying
Extend an LV by 16MiB using specific physical extents.
.br
.B lvextend \-L+16m vg01/lvol01 /dev/sda:8\-9 /dev/sdb:8\-9

View File

@@ -1,12 +0,0 @@
lvextend extends the size of an LV. This requires allocating logical
extents from the VG's free physical extents. If the extension adds a new
LV segment, the new segment will use the existing segment type of the LV.
Extending a copy\-on\-write snapshot LV adds space for COW blocks.
Use \fBlvconvert\fP(8) to change the number of data images in a RAID or
mirrored LV.
In the usage section below, \fB--size\fP \fISize\fP can be replaced
with \fB--extents\fP \fINumber\fP. See both descriptions
the options section.

View File

@@ -1,712 +0,0 @@
.TH LVEXTEND 8 "LVM TOOLS 2.02.169(2)-git (2016-11-30)" "Red Hat, Inc."
.SH NAME
lvextend \- Add space to a logical volume
.
.SH SYNOPSIS
\fBlvextend\fP \fIoption_args\fP \fIposition_args\fP
.br
[ \fIoption_args\fP ]
.br
[ \fIposition_args\fP ]
.br
.P
.ad l
\fB--alloc\fP \fBcontiguous\fP|\fBcling\fP|\fBcling_by_tags\fP|\fBnormal\fP|\fBanywhere\fP|\fBinherit\fP
.ad b
.br
.ad l
\fB-A\fP|\fB--autobackup\fP \fBy\fP|\fBn\fP
.ad b
.br
.ad l
\fB--commandprofile\fP \fIString\fP
.ad b
.br
.ad l
\fB--config\fP \fIString\fP
.ad b
.br
.ad l
\fB-d\fP|\fB--debug\fP
.ad b
.br
.ad l
\fB--driverloaded\fP \fBy\fP|\fBn\fP
.ad b
.br
.ad l
\fB-l\fP|\fB--extents\fP [\fB+\fP]\fINumber\fP[PERCENT]
.ad b
.br
.ad l
\fB-f\fP|\fB--force\fP
.ad b
.br
.ad l
\fB-h\fP|\fB--help\fP
.ad b
.br
.ad l
\fB--longhelp\fP
.ad b
.br
.ad l
\fB-m\fP|\fB--mirrors\fP \fINumber\fP
.ad b
.br
.ad l
\fB-n\fP|\fB--nofsck\fP
.ad b
.br
.ad l
\fB--nosync\fP
.ad b
.br
.ad l
\fB--noudevsync\fP
.ad b
.br
.ad l
\fB--poolmetadatasize\fP [\fB+\fP]\fISize\fP[m|UNIT]
.ad b
.br
.ad l
\fB--profile\fP \fIString\fP
.ad b
.br
.ad l
\fB-q\fP|\fB--quiet\fP
.ad b
.br
.ad l
\fB--reportformat\fP \fBbasic\fP|\fBjson\fP
.ad b
.br
.ad l
\fB-r\fP|\fB--resizefs\fP
.ad b
.br
.ad l
\fB-L\fP|\fB--size\fP [\fB+\fP]\fISize\fP[m|UNIT]
.ad b
.br
.ad l
\fB-i\fP|\fB--stripes\fP \fINumber\fP
.ad b
.br
.ad l
\fB-I\fP|\fB--stripesize\fP \fISize\fP[k|UNIT]
.ad b
.br
.ad l
\fB-t\fP|\fB--test\fP
.ad b
.br
.ad l
\fB--type\fP \fBlinear\fP|\fBstriped\fP|\fBsnapshot\fP|\fBmirror\fP|\fBraid\fP|\fBthin\fP|\fBcache\fP|\fBthin-pool\fP|\fBcache-pool\fP
.ad b
.br
.ad l
\fB--usepolicies\fP
.ad b
.br
.ad l
\fB-v\fP|\fB--verbose\fP
.ad b
.br
.ad l
\fB--version\fP
.ad b
.br
.ad l
\fB-y\fP|\fB--yes\fP
.ad b
.SH DESCRIPTION
lvextend extends the size of an LV. This requires allocating logical
extents from the VG's free physical extents. If the extension adds a new
LV segment, the new segment will use the existing segment type of the LV.
Extending a copy\-on\-write snapshot LV adds space for COW blocks.
Use \fBlvconvert\fP(8) to change the number of data images in a RAID or
mirrored LV.
In the usage section below, \fB--size\fP \fISize\fP can be replaced
with \fB--extents\fP \fINumber\fP. See both descriptions
the options section.
.SH USAGE
Extend an LV by a specified size.
.br
.P
\fBlvextend\fP \fB-L\fP|\fB--size\fP [\fB+\fP]\fISize\fP[m|UNIT] \fILV\fP
.br
.RS 4
.ad l
[ \fB-l\fP|\fB--extents\fP [\fB+\fP]\fINumber\fP[PERCENT] ]
.ad b
.br
.ad l
[ \fB-r\fP|\fB--resizefs\fP ]
.ad b
.br
.ad l
[ \fB-i\fP|\fB--stripes\fP \fINumber\fP ]
.ad b
.br
.ad l
[ \fB-I\fP|\fB--stripesize\fP \fISize\fP[k|UNIT] ]
.ad b
.br
.ad l
[ \fB--poolmetadatasize\fP [\fB+\fP]\fISize\fP[m|UNIT] ]
.ad b
.br
[ COMMON_OPTIONS ]
.RE
.br
.RS 4
[ \fIPV\fP ... ]
.RE
-
Extend an LV by specified PV extents.
.br
.P
\fBlvextend\fP \fILV\fP \fIPV\fP ...
.br
.RS 4
.ad l
[ \fB-r\fP|\fB--resizefs\fP ]
.ad b
.br
.ad l
[ \fB-i\fP|\fB--stripes\fP \fINumber\fP ]
.ad b
.br
.ad l
[ \fB-I\fP|\fB--stripesize\fP \fISize\fP[k|UNIT] ]
.ad b
.br
[ COMMON_OPTIONS ]
.RE
.br
-
Extend a pool metadata SubLV by a specified size.
.br
.P
\fBlvextend\fP \fB--poolmetadatasize\fP [\fB+\fP]\fISize\fP[m|UNIT] \fILV\fP\fI_thinpool\fP
.br
.RS 4
.ad l
[ \fB-i\fP|\fB--stripes\fP \fINumber\fP ]
.ad b
.br
.ad l
[ \fB-I\fP|\fB--stripesize\fP \fISize\fP[k|UNIT] ]
.ad b
.br
[ COMMON_OPTIONS ]
.RE
.br
.RS 4
[ \fIPV\fP ... ]
.RE
-
Extend an LV according to a predefined policy.
.br
.P
\fBlvextend\fP \fB--usepolicies\fP \fILV\fP\fI_snapshot_thinpool\fP
.br
.RS 4
.ad l
[ \fB-r\fP|\fB--resizefs\fP ]
.ad b
.br
[ COMMON_OPTIONS ]
.RE
.br
.RS 4
[ \fIPV\fP ... ]
.RE
-
Common options for command:
.
.RS 4
.ad l
[ \fB-A\fP|\fB--autobackup\fP \fBy\fP|\fBn\fP ]
.ad b
.br
.ad l
[ \fB-f\fP|\fB--force\fP ]
.ad b
.br
.ad l
[ \fB-m\fP|\fB--mirrors\fP \fINumber\fP ]
.ad b
.br
.ad l
[ \fB-n\fP|\fB--nofsck\fP ]
.ad b
.br
.ad l
[ \fB--alloc\fP \fBcontiguous\fP|\fBcling\fP|\fBcling_by_tags\fP|\fBnormal\fP|\fBanywhere\fP|\fBinherit\fP ]
.ad b
.br
.ad l
[ \fB--nosync\fP ]
.ad b
.br
.ad l
[ \fB--noudevsync\fP ]
.ad b
.br
.ad l
[ \fB--reportformat\fP \fBbasic\fP|\fBjson\fP ]
.ad b
.br
.ad l
[ \fB--type\fP \fBlinear\fP|\fBstriped\fP|\fBsnapshot\fP|\fBmirror\fP|\fBraid\fP|\fBthin\fP|\fBcache\fP|\fBthin-pool\fP|\fBcache-pool\fP ]
.ad b
.RE
Common options for lvm:
.
.RS 4
.ad l
[ \fB-d\fP|\fB--debug\fP ]
.ad b
.br
.ad l
[ \fB-h\fP|\fB--help\fP ]
.ad b
.br
.ad l
[ \fB-q\fP|\fB--quiet\fP ]
.ad b
.br
.ad l
[ \fB-t\fP|\fB--test\fP ]
.ad b
.br
.ad l
[ \fB-v\fP|\fB--verbose\fP ]
.ad b
.br
.ad l
[ \fB-y\fP|\fB--yes\fP ]
.ad b
.br
.ad l
[ \fB--commandprofile\fP \fIString\fP ]
.ad b
.br
.ad l
[ \fB--config\fP \fIString\fP ]
.ad b
.br
.ad l
[ \fB--driverloaded\fP \fBy\fP|\fBn\fP ]
.ad b
.br
.ad l
[ \fB--longhelp\fP ]
.ad b
.br
.ad l
[ \fB--profile\fP \fIString\fP ]
.ad b
.br
.ad l
[ \fB--version\fP ]
.ad b
.RE
.SH OPTIONS
.HP
.ad l
\fB--alloc\fP \fBcontiguous\fP|\fBcling\fP|\fBcling_by_tags\fP|\fBnormal\fP|\fBanywhere\fP|\fBinherit\fP
.br
Determines the allocation policy when a command needs to allocate
Physical Extents (PEs) from the VG. Each VG and LV has an allocation policy
which can be changed with vgchange/lvchange, or overriden on the
command line.
\fBnormal\fP applies common sense rules such as not placing parallel stripes
on the same PV.
\fBinherit\fP applies the VG policy to an LV.
\fBcontiguous\fP requires new PEs be placed adjacent to existing PEs.
\fBcling\fP places new PEs on the same PV as existing PEs in the same
stripe of the LV.
If there are sufficient PEs for an allocation, but normal does not
use them, \fBanywhere\fP will use them even if it reduces performance,
e.g. by placing two stripes on the same PV.
Optional positional PV args on the command line can also be used to limit
which PVs the command will use for allocation.
See \fBlvm\fP(8) for more information about allocation.
.ad b
.HP
.ad l
\fB-A\fP|\fB--autobackup\fP \fBy\fP|\fBn\fP
.br
Specifies if metadata should be backed up automatically after a change.
Enabling this is strongly advised! See vgcfgbackup(8) for more information.
.ad b
.HP
.ad l
\fB--commandprofile\fP \fIString\fP
.br
The command profile to use for command configuration.
See \fBlvm.conf\fP(5) for more information about profiles.
.ad b
.HP
.ad l
\fB--config\fP \fIString\fP
.br
Config settings for the command. These override lvm.conf settings.
The String arg uses the same format as lvm.conf,
or may use section/field syntax.
See \fBlvm.conf\fP(5) for more information about config.
.ad b
.HP
.ad l
\fB-d\fP|\fB--debug\fP ...
.br
Set debug level. Repeat from 1 to 6 times to increase the detail of
messages sent to the log file and/or syslog (if configured).
.ad b
.HP
.ad l
\fB--driverloaded\fP \fBy\fP|\fBn\fP
.br
If set to no, the command will not attempt to use device-mapper.
For testing and debugging.
.ad b
.HP
.ad l
\fB-l\fP|\fB--extents\fP [\fB+\fP]\fINumber\fP[PERCENT]
.br
Specifies the new size of the LV in logical extents.
The --size and --extents options are alternate methods of specifying size.
The total number of physical extents used will be
greater when redundant data is needed for RAID levels.
An alternate syntax allows the size to be determined indirectly
as a percentage of the size of a related VG, LV, or set of PVs. The
suffix \fB%VG\fP denotes the total size of the VG, the suffix \fB%FREE\fP
the remaining free space in the VG, and the suffix \fB%PVS\fP the free
space in the specified PVs. For a snapshot, the size
can be expressed as a percentage of the total size of the origin LV
with the suffix \fB%ORIGIN\fP (\fB100%ORIGIN\fP provides space for
the whole origin).
When expressed as a percentage, the size defines an upper limit for the
number of logical extents in the new LV. The precise number of logical
extents in the new LV is not determined until the command has completed.
When the plus \fB+\fP or minus \fB-\fP prefix is used,
the value is not an absolute size, but is relative and added or subtracted
from the current size.
.ad b
.HP
.ad l
\fB-f\fP|\fB--force\fP ...
.br
Override various checks, confirmations and protections.
Use with extreme caution.
.ad b
.HP
.ad l
\fB-h\fP|\fB--help\fP
.br
Display help text.
.ad b
.HP
.ad l
\fB--longhelp\fP
.br
Display long help text.
.ad b
.HP
.ad l
\fB-m\fP|\fB--mirrors\fP \fINumber\fP
.br
Not used.
.ad b
.HP
.ad l
\fB-n\fP|\fB--nofsck\fP
.br
Do not perform fsck before resizing filesystem when filesystem
requires it. You may need to use --force to proceed with
this option.
.ad b
.HP
.ad l
\fB--nosync\fP
.br
Causes the creation of mirror, raid1, raid4, raid5 and raid10 to skip the
initial synchronization. In case of mirror, raid1 and raid10, any data
written afterwards will be mirrored, but the original contents will not be
copied. In case of raid4 and raid5, no parity blocks will be written,
though any data written afterwards will cause parity blocks to be stored.
This is useful for skipping a potentially long and resource intensive initial
sync of an empty mirror/raid1/raid4/raid5 and raid10 LV.
This option is not valid for raid6, because raid6 relies on proper parity
(P and Q Syndromes) being created during initial synchronization in order
to reconstruct proper user date in case of device failures.
raid0 and raid0_meta do not provide any data copies or parity support
and thus do not support initial synchronization.
.ad b
.HP
.ad l
\fB--noudevsync\fP
.br
Disables udev synchronisation. The process will not wait for notification
from udev. It will continue irrespective of any possible udev processing
in the background. Only use this if udev is not running or has rules that
ignore the devices LVM creates.
.ad b
.HP
.ad l
\fB--poolmetadatasize\fP [\fB+\fP]\fISize\fP[m|UNIT]
.br
Specifies the new size of the pool metadata LV.
The plus prefix \fB+\fP can be used, in which case
the value is added to the current size.
.ad b
.HP
.ad l
\fB--profile\fP \fIString\fP
.br
An alias for --commandprofile or --metadataprofile, depending
on the command.
.ad b
.HP
.ad l
\fB-q\fP|\fB--quiet\fP ...
.br
Suppress output and log messages. Overrides --debug and --verbose.
Repeat once to also suppress any prompts with answer no.
.ad b
.HP
.ad l
\fB--reportformat\fP \fBbasic\fP|\fBjson\fP
.br
Overrides current output format for reports which is defined globally by
the report/output_format setting in lvm.conf.
\fBbasic\fP is the original format with columns and rows.
If there is more than one report per command, each report is prefixed
with the report name for identification. \fBjson\fP produces report
output in JSON format. See \fBlvmreport\fP(7) for more information.
.ad b
.HP
.ad l
\fB-r\fP|\fB--resizefs\fP
.br
Resize underlying filesystem together with the LV using fsadm(8).
.ad b
.HP
.ad l
\fB-L\fP|\fB--size\fP [\fB+\fP]\fISize\fP[m|UNIT]
.br
Specifies the new size of the LV.
The --size and --extents options are alternate methods of specifying size.
The total number of physical extents used will be
greater when redundant data is needed for RAID levels.
When the plus \fB+\fP or minus \fB-\fP prefix is used,
the value is not an absolute size, but is relative and added or subtracted
from the current size.
.ad b
.HP
.ad l
\fB-i\fP|\fB--stripes\fP \fINumber\fP
.br
Specifies the number of stripes in a striped LV. This is the number of
PVs (devices) that a striped LV is spread across. Data that
appears sequential in the LV is spread across multiple devices in units of
the stripe size (see --stripesize). This does not change existing
allocated space, but only applies to space being allocated by the command.
When creating a RAID 4/5/6 LV, this number does not include the extra
devices that are required for parity. The largest number depends on
the RAID type (raid0: 64, raid10: 32, raid4/5: 63, raid6: 62), and
when unspecified, the default depends on the RAID type
(raid0: 2, raid10: 4, raid4/5: 3, raid6: 5.)
To stripe a new raid LV across all PVs by default,
see lvm.conf allocation/raid_stripe_all_devices.
.ad b
.HP
.ad l
\fB-I\fP|\fB--stripesize\fP \fISize\fP[k|UNIT]
.br
The amount of data that is written to one device before
moving to the next in a striped LV.
.ad b
.HP
.ad l
\fB-t\fP|\fB--test\fP
.br
Run in test mode. Commands will not update metadata.
This is implemented by disabling all metadata writing but nevertheless
returning success to the calling function. This may lead to unusual
error messages in multi-stage operations if a tool relies on reading
back metadata it believes has changed but hasn't.
.ad b
.HP
.ad l
\fB--type\fP \fBlinear\fP|\fBstriped\fP|\fBsnapshot\fP|\fBmirror\fP|\fBraid\fP|\fBthin\fP|\fBcache\fP|\fBthin-pool\fP|\fBcache-pool\fP
.br
The LV type, also known as "segment type" or "segtype".
See usage descriptions for the specific ways to use these types.
For more information about redundancy and performance (\fBraid\fP<N>, \fBmirror\fP, \fBstriped\fP, \fBlinear\fP) see \fBlvmraid\fP(7).
For thin provisioning (\fBthin\fP, \fBthin-pool\fP) see \fBlvmthin\fP(7).
For performance caching (\fBcache\fP, \fBcache-pool\fP) see \fBlvmcache\fP(7).
For copy-on-write snapshots (\fBsnapshot\fP) see usage definitions.
Several commands omit an explicit type option because the type
is inferred from other options or shortcuts
(e.g. --stripes, --mirrors, --snapshot, --virtualsize, --thin, --cache).
Use inferred types with care because it can lead to unexpected results.
.ad b
.HP
.ad l
\fB--usepolicies\fP
.br
Perform an operation according to the policy configured in lvm.conf
or a profile.
.ad b
.HP
.ad l
\fB-v\fP|\fB--verbose\fP ...
.br
Set verbose level. Repeat from 1 to 4 times to increase the detail
of messages sent to stdout and stderr.
.ad b
.HP
.ad l
\fB--version\fP
.br
Display version information.
.ad b
.HP
.ad l
\fB-y\fP|\fB--yes\fP
.br
Do not prompt for confirmation interactively but always assume the
answer yes. Use with extreme caution.
(For automatic no, see -qq.)
.ad b
.SH VARIABLES
.HP
\fILV\fP
.br
Logical Volume name. See \fBlvm\fP(8) for valid names.
An LV positional arg generally includes the VG name and LV name, e.g. VG/LV.
LV followed by _<type> indicates that an LV of the
given type is required. (raid represents raid<N> type)
.HP
\fIPV\fP
.br
Physical Volume name, a device path under /dev.
For commands managing physical extents, a PV positional arg
generally accepts a suffix indicating a range (or multiple ranges)
of physical extents (PEs). When the first PE is omitted, it defaults
to the start of the device, and when the last PE is omitted it defaults to end.
Start and end range (inclusive): \fIPV\fP[\fB:\fP\fIPE\fP\fB-\fP\fIPE\fP]...
Start and length range (counting from 0): \fIPV\fP[\fB:\fP\fIPE\fP\fB+\fP\fIPE\fP]...
.HP
\fIString\fP
.br
See the option description for information about the string content.
.HP
\fISize\fP[UNIT]
.br
Size is an input number that accepts an optional unit.
Input units are always treated as base two values, regardless of
capitalization, e.g. 'k' and 'K' both refer to 1024.
The default input unit is specified by letter, followed by |UNIT.
UNIT represents other possible input units: \fBbBsSkKmMgGtTpPeE\fP.
b|B is bytes, s|S is sectors of 512 bytes, k|K is kilobytes,
m|M is megabytes, g|G is gigabytes, t|T is terabytes,
p|P is petabytes, e|E is exabytes.
(This should not be confused with the output control --units, where
capital letters mean multiple of 1000.)
.SH ENVIRONMENT VARIABLES
See \fBlvm\fP(8) for information about environment variables used by lvm.
For example, LVM_VG_NAME can generally be substituted for a required VG parameter.
.SH EXAMPLES
Extend the size of an LV by 54MiB, using a specific PV.
.br
.B lvextend \-L +54 vg01/lvol10 /dev/sdk3
Extend the size of an LV by the amount of free
space on PV /dev/sdk3. This is equivalent to specifying
"\-l +100%PVS" on the command line.
.br
.B lvextend vg01/lvol01 /dev/sdk3
Extend an LV by 16MiB using specific physical extents.
.br
.B lvextend \-L+16m vg01/lvol01 /dev/sda:8\-9 /dev/sdb:8\-9
.SH SEE ALSO
.BR lvm (8)
.BR lvm.conf (5)
.BR lvmconfig (8)
.BR pvchange (8)
.BR pvck (8)
.BR pvcreate (8)
.BR pvdisplay (8)
.BR pvmove (8)
.BR pvremove (8)
.BR pvresize (8)
.BR pvs (8)
.BR pvscan (8)
.BR vgcfgbackup (8)
.BR vgcfgrestore (8)
.BR vgchange (8)
.BR vgck (8)
.BR vgcreate (8)
.BR vgconvert (8)
.BR vgdisplay (8)
.BR vgexport (8)
.BR vgextend (8)
.BR vgimport (8)
.BR vgimportclone (8)
.BR vgmerge (8)
.BR vgmknodes (8)
.BR vgreduce (8)
.BR vgremove (8)
.BR vgrename (8)
.BR vgs (8)
.BR vgscan (8)
.BR vgsplit (8)
.BR lvcreate (8)
.BR lvchange (8)
.BR lvconvert (8)
.BR lvdisplay (8)
.BR lvextend (8)
.BR lvreduce (8)
.BR lvremove (8)
.BR lvrename (8)
.BR lvresize (8)
.BR lvs (8)
.BR lvscan (8)
.BR lvm2-activation-generator (8)
.BR blkdeactivate (8)
.BR lvmdump (8)
.BR dmeventd (8)
.BR lvmetad (8)
.BR lvmpolld (8)
.BR lvmlockd (8)
.BR lvmlockctl (8)
.BR clvmd (8)
.BR cmirrord (8)
.BR lvmdbusd (8)
.BR lvmsystemid (7)
.BR lvmreport (7)
.BR lvmraid (7)
.BR lvmthin (7)
.BR lvmcache (7)

View File

@@ -1,5 +0,0 @@
This command is the same as \fBlvmconfig\fP(8).
lvm config produces formatted output from the LVM configuration tree. The
sources of the configuration data include \fBlvm.conf\fP(5) and command
line settings from \-\-config.

View File

View File

@@ -1,471 +0,0 @@
.TH LVM CONFIG 8 "LVM TOOLS 2.02.169(2)-git (2016-11-30)" "Red Hat, Inc."
.SH NAME
lvm config \- Display and manipulate configuration information
.
.SH SYNOPSIS
\fBlvm config\fP
.br
[ \fIoption_args\fP ]
.br
[ \fIposition_args\fP ]
.br
.SH DESCRIPTION
This command is the same as \fBlvmconfig\fP(8).
lvm config produces formatted output from the LVM configuration tree. The
sources of the configuration data include \fBlvm.conf\fP(5) and command
line settings from \-\-config.
.SH USAGE
\fBlvm config\fP
.br
.RS 4
.ad l
[ \fB-f\fP|\fB--file\fP \fIString\fP ]
.ad b
.br
.ad l
[ \fB-l\fP|\fB--list\fP ]
.ad b
.br
.ad l
[ \fB--atversion\fP \fIString\fP ]
.ad b
.br
.ad l
[ \fB--typeconfig\fP \fBcurrent\fP|\fBdefault\fP|\fBdiff\fP|\fBfull\fP|\fBlist\fP|\fBmissing\fP|\fBnew\fP|\fBprofilable\fP|\fBprofilable-command\fP|\fBprofilable-metadata\fP ]
.ad b
.br
.ad l
[ \fB--ignoreadvanced\fP ]
.ad b
.br
.ad l
[ \fB--ignoreunsupported\fP ]
.ad b
.br
.ad l
[ \fB--ignorelocal\fP ]
.ad b
.br
.ad l
[ \fB--mergedconfig\fP ]
.ad b
.br
.ad l
[ \fB--metadataprofile\fP \fIString\fP ]
.ad b
.br
.ad l
[ \fB--sinceversion\fP \fIString\fP ]
.ad b
.br
.ad l
[ \fB--showdeprecated\fP ]
.ad b
.br
.ad l
[ \fB--showunsupported\fP ]
.ad b
.br
.ad l
[ \fB--validate\fP ]
.ad b
.br
.ad l
[ \fB--withsummary\fP ]
.ad b
.br
.ad l
[ \fB--withcomments\fP ]
.ad b
.br
.ad l
[ \fB--withspaces\fP ]
.ad b
.br
.ad l
[ \fB--unconfigured\fP ]
.ad b
.br
.ad l
[ \fB--withversions\fP ]
.ad b
.br
[ COMMON_OPTIONS ]
.RE
.br
.RS 4
[ \fIString\fP ... ]
.RE
Common options for lvm:
.
.RS 4
.ad l
[ \fB-d\fP|\fB--debug\fP ]
.ad b
.br
.ad l
[ \fB-h\fP|\fB--help\fP ]
.ad b
.br
.ad l
[ \fB-q\fP|\fB--quiet\fP ]
.ad b
.br
.ad l
[ \fB-t\fP|\fB--test\fP ]
.ad b
.br
.ad l
[ \fB-v\fP|\fB--verbose\fP ]
.ad b
.br
.ad l
[ \fB-y\fP|\fB--yes\fP ]
.ad b
.br
.ad l
[ \fB--commandprofile\fP \fIString\fP ]
.ad b
.br
.ad l
[ \fB--config\fP \fIString\fP ]
.ad b
.br
.ad l
[ \fB--driverloaded\fP \fBy\fP|\fBn\fP ]
.ad b
.br
.ad l
[ \fB--longhelp\fP ]
.ad b
.br
.ad l
[ \fB--profile\fP \fIString\fP ]
.ad b
.br
.ad l
[ \fB--version\fP ]
.ad b
.RE
.SH OPTIONS
.HP
.ad l
\fB--atversion\fP \fIString\fP
.br
Specify an LVM version in x.y.z format where x is the major version,
the y is the minor version and z is the patchlevel (e.g. 2.2.106).
When configuration is displayed, the configuration settings recognized
at this LVM version will be considered only. This can be used
to display a configuration that a certain LVM version understands and
which does not contain any newer settings for which LVM would
issue a warning message when checking the configuration.
.ad b
.HP
.ad l
\fB--commandprofile\fP \fIString\fP
.br
The command profile to use for command configuration.
See \fBlvm.conf\fP(5) for more information about profiles.
.ad b
.HP
.ad l
\fB--config\fP \fIString\fP
.br
Config settings for the command. These override lvm.conf settings.
The String arg uses the same format as lvm.conf,
or may use section/field syntax.
See \fBlvm.conf\fP(5) for more information about config.
.ad b
.HP
.ad l
\fB-d\fP|\fB--debug\fP ...
.br
Set debug level. Repeat from 1 to 6 times to increase the detail of
messages sent to the log file and/or syslog (if configured).
.ad b
.HP
.ad l
\fB--driverloaded\fP \fBy\fP|\fBn\fP
.br
If set to no, the command will not attempt to use device-mapper.
For testing and debugging.
.ad b
.HP
.ad l
\fB-f\fP|\fB--file\fP \fIString\fP
.br
Write output to the named file.
.ad b
.HP
.ad l
\fB-h\fP|\fB--help\fP
.br
Display help text.
.ad b
.HP
.ad l
\fB--ignoreadvanced\fP
.br
Exclude advanced configuration settings from the output.
.ad b
.HP
.ad l
\fB--ignorelocal\fP
.br
Ignore local section.
.ad b
.HP
.ad l
\fB--ignoreunsupported\fP
.br
Exclude unsupported configuration settings from the output. These settings are
either used for debugging and development purposes only or their support is not
yet complete and they are not meant to be used in production. The \fBcurrent\fP
and \fBdiff\fP types include unsupported settings in their output by default,
all the other types ignore unsupported settings.
.ad b
.HP
.ad l
\fB-l\fP|\fB--list\fP
.br
List config settings with summarizing comment. This is the same as using
options --typeconfig list --withsummary.
.ad b
.HP
.ad l
\fB--longhelp\fP
.br
Display long help text.
.ad b
.HP
.ad l
\fB--mergedconfig\fP
.br
When the command is run with --config
and/or --commandprofile (or using LVM_COMMAND_PROFILE
environment variable), --profile, or --metadataprofile,
merge all the contents of the "config cascade" before displaying it.
Without merging, only the configuration at the front of the
cascade is displayed.
See \fBlvm.conf\fP(5) for more information about config.
.ad b
.HP
.ad l
\fB--metadataprofile\fP \fIString\fP
.br
The metadata profile to use for command configuration.
See \fBlvm.conf\fP(5) for more information about profiles.
.ad b
.HP
.ad l
\fB--profile\fP \fIString\fP
.br
An alias for --commandprofile or --metadataprofile, depending
on the command.
.ad b
.HP
.ad l
\fB-q\fP|\fB--quiet\fP ...
.br
Suppress output and log messages. Overrides --debug and --verbose.
Repeat once to also suppress any prompts with answer no.
.ad b
.HP
.ad l
\fB--showdeprecated\fP
.br
Include deprecated configuration settings in the output. These settings
are deprecated after a certain version. If a concrete version is specified
with --atversion, deprecated settings are automatically included
if the specified version is lower than the version in which the settings were
deprecated. The current and diff types include deprecated settings
in their output by default, all the other types ignore deprecated settings.
.ad b
.HP
.ad l
\fB--showunsupported\fP
.br
Include unsupported configuration settings in the output. These settings
are either used for debugging or development purposes only, or their support
is not yet complete and they are not meant to be used in production. The
current and diff types include unsupported settings in their
output by default, all the other types ignore unsupported settings.
.ad b
.HP
.ad l
\fB--sinceversion\fP \fIString\fP
.br
Specify an LVM version in x.y.z format where x is the major version,
the y is the minor version and z is the patchlevel (e.g. 2.2.106).
This option is currently applicable only with --typeconfig new
to display all configuration settings introduced since given version.
.ad b
.HP
.ad l
\fB-t\fP|\fB--test\fP
.br
Run in test mode. Commands will not update metadata.
This is implemented by disabling all metadata writing but nevertheless
returning success to the calling function. This may lead to unusual
error messages in multi-stage operations if a tool relies on reading
back metadata it believes has changed but hasn't.
.ad b
.HP
.ad l
\fB--typeconfig\fP \fBcurrent\fP|\fBdefault\fP|\fBdiff\fP|\fBfull\fP|\fBlist\fP|\fBmissing\fP|\fBnew\fP|\fBprofilable\fP|\fBprofilable-command\fP|\fBprofilable-metadata\fP
.br
See lvmreport(7).
.ad b
.HP
.ad l
\fB--unconfigured\fP
.br
Internal option used for generating config file during build.
.ad b
.HP
.ad l
\fB--validate\fP
.br
Validate current configuration used and exit with appropriate
return code. The validation is done only for the configuration
at the front of the "config cascade". To validate the whole
merged configuration tree, also use --mergedconfig.
The validation is done even if lvm.conf config/checks is disabled.
.ad b
.HP
.ad l
\fB-v\fP|\fB--verbose\fP ...
.br
Set verbose level. Repeat from 1 to 4 times to increase the detail
of messages sent to stdout and stderr.
.ad b
.HP
.ad l
\fB--version\fP
.br
Display version information.
.ad b
.HP
.ad l
\fB--withcomments\fP
.br
Display a full comment for each configuration node. For deprecated
settings, also display comments about deprecation.
.ad b
.HP
.ad l
\fB--withspaces\fP
.br
Where appropriate, add more spaces in output for better readability.
.ad b
.HP
.ad l
\fB--withsummary\fP
.br
Display a one line comment for each configuration node.
.ad b
.HP
.ad l
\fB--withversions\fP
.br
Also display a comment containing the version of introduction for
each configuration node. If the setting is deprecated, also display
the version since which it is deprecated.
.ad b
.HP
.ad l
\fB-y\fP|\fB--yes\fP
.br
Do not prompt for confirmation interactively but always assume the
answer yes. Use with extreme caution.
(For automatic no, see -qq.)
.ad b
.SH VARIABLES
.HP
\fIString\fP
.br
See the option description for information about the string content.
.HP
\fISize\fP[UNIT]
.br
Size is an input number that accepts an optional unit.
Input units are always treated as base two values, regardless of
capitalization, e.g. 'k' and 'K' both refer to 1024.
The default input unit is specified by letter, followed by |UNIT.
UNIT represents other possible input units: \fBbBsSkKmMgGtTpPeE\fP.
b|B is bytes, s|S is sectors of 512 bytes, k|K is kilobytes,
m|M is megabytes, g|G is gigabytes, t|T is terabytes,
p|P is petabytes, e|E is exabytes.
(This should not be confused with the output control --units, where
capital letters mean multiple of 1000.)
.SH ENVIRONMENT VARIABLES
See \fBlvm\fP(8) for information about environment variables used by lvm.
For example, LVM_VG_NAME can generally be substituted for a required VG parameter.
.SH SEE ALSO
.BR lvm (8)
.BR lvm.conf (5)
.BR lvmconfig (8)
.BR pvchange (8)
.BR pvck (8)
.BR pvcreate (8)
.BR pvdisplay (8)
.BR pvmove (8)
.BR pvremove (8)
.BR pvresize (8)
.BR pvs (8)
.BR pvscan (8)
.BR vgcfgbackup (8)
.BR vgcfgrestore (8)
.BR vgchange (8)
.BR vgck (8)
.BR vgcreate (8)
.BR vgconvert (8)
.BR vgdisplay (8)
.BR vgexport (8)
.BR vgextend (8)
.BR vgimport (8)
.BR vgimportclone (8)
.BR vgmerge (8)
.BR vgmknodes (8)
.BR vgreduce (8)
.BR vgremove (8)
.BR vgrename (8)
.BR vgs (8)
.BR vgscan (8)
.BR vgsplit (8)
.BR lvcreate (8)
.BR lvchange (8)
.BR lvconvert (8)
.BR lvdisplay (8)
.BR lvextend (8)
.BR lvreduce (8)
.BR lvremove (8)
.BR lvrename (8)
.BR lvresize (8)
.BR lvs (8)
.BR lvscan (8)
.BR lvm2-activation-generator (8)
.BR blkdeactivate (8)
.BR lvmdump (8)
.BR dmeventd (8)
.BR lvmetad (8)
.BR lvmpolld (8)
.BR lvmlockd (8)
.BR lvmlockctl (8)
.BR clvmd (8)
.BR cmirrord (8)
.BR lvmdbusd (8)
.BR lvmsystemid (7)
.BR lvmreport (7)
.BR lvmraid (7)
.BR lvmthin (7)
.BR lvmcache (7)

View File

@@ -1,5 +0,0 @@
This command is the same as \fBlvmconfig\fP(8).
lvm dumpconfig produces formatted output from the LVM configuration tree. The
sources of the configuration data include \fBlvm.conf\fP(5) and command
line settings from \-\-config.

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