r385 - in lvm2/upstream/current: . daemons/clvmd dmeventd/mirror
doc include lib lib/activate lib/cache lib/commands
lib/config lib/device lib/display lib/error lib/filters
lib/format1 lib/format_text lib/locking lib/log lib/metadata
lib/mirror lib/misc lib/mm lib/report lib/snapshot lib/zero
man scripts tools
Bastian Blank
waldi at costa.debian.org
Mon Oct 23 08:49:11 UTC 2006
Author: waldi
Date: Mon Oct 23 08:49:10 2006
New Revision: 385
Added:
lvm2/upstream/current/daemons/clvmd/refresh_clvmd.c
lvm2/upstream/current/daemons/clvmd/refresh_clvmd.h
lvm2/upstream/current/lib/misc/lvm-wrappers.c
lvm2/upstream/current/lib/misc/lvm-wrappers.h
lvm2/upstream/current/lib/misc/timestamp.c
lvm2/upstream/current/lib/misc/timestamp.h
lvm2/upstream/current/man/lvconvert.8
lvm2/upstream/current/scripts/lvm_dump.sh (contents, props changed)
lvm2/upstream/current/tools/lvm2cmd-static.c
lvm2/upstream/current/tools/lvm2cmd.c
lvm2/upstream/current/tools/lvmcmdlib.c
Modified:
lvm2/upstream/current/VERSION
lvm2/upstream/current/WHATS_NEW
lvm2/upstream/current/configure
lvm2/upstream/current/configure.in
lvm2/upstream/current/daemons/clvmd/Makefile.in
lvm2/upstream/current/daemons/clvmd/clvm.h
lvm2/upstream/current/daemons/clvmd/clvmd-cman.c
lvm2/upstream/current/daemons/clvmd/clvmd-command.c
lvm2/upstream/current/daemons/clvmd/clvmd-comms.h
lvm2/upstream/current/daemons/clvmd/clvmd-gulm.c
lvm2/upstream/current/daemons/clvmd/clvmd.c
lvm2/upstream/current/daemons/clvmd/lvm-functions.c
lvm2/upstream/current/daemons/clvmd/lvm-functions.h
lvm2/upstream/current/dmeventd/mirror/dmeventd_mirror.c
lvm2/upstream/current/doc/example.conf
lvm2/upstream/current/include/.symlinks
lvm2/upstream/current/lib/Makefile.in
lvm2/upstream/current/lib/activate/activate.c
lvm2/upstream/current/lib/activate/activate.h
lvm2/upstream/current/lib/activate/dev_manager.c
lvm2/upstream/current/lib/activate/dev_manager.h
lvm2/upstream/current/lib/activate/fs.c
lvm2/upstream/current/lib/cache/lvmcache.c
lvm2/upstream/current/lib/commands/toolcontext.c
lvm2/upstream/current/lib/commands/toolcontext.h
lvm2/upstream/current/lib/config/config.c
lvm2/upstream/current/lib/config/defaults.h
lvm2/upstream/current/lib/device/dev-cache.c
lvm2/upstream/current/lib/device/dev-io.c
lvm2/upstream/current/lib/display/display.c
lvm2/upstream/current/lib/error/errseg.c
lvm2/upstream/current/lib/filters/filter-md.c
lvm2/upstream/current/lib/filters/filter-sysfs.c
lvm2/upstream/current/lib/filters/filter.c
lvm2/upstream/current/lib/format1/disk-rep.c
lvm2/upstream/current/lib/format1/disk-rep.h
lvm2/upstream/current/lib/format1/format1.c
lvm2/upstream/current/lib/format1/import-export.c
lvm2/upstream/current/lib/format1/layout.c
lvm2/upstream/current/lib/format_text/archive.c
lvm2/upstream/current/lib/format_text/archiver.c
lvm2/upstream/current/lib/format_text/export.c
lvm2/upstream/current/lib/format_text/format-text.c
lvm2/upstream/current/lib/format_text/import_vsn1.c
lvm2/upstream/current/lib/format_text/layout.h
lvm2/upstream/current/lib/locking/cluster_locking.c
lvm2/upstream/current/lib/locking/file_locking.c
lvm2/upstream/current/lib/locking/locking.c
lvm2/upstream/current/lib/log/log.c
lvm2/upstream/current/lib/log/log.h
lvm2/upstream/current/lib/metadata/lv_manip.c
lvm2/upstream/current/lib/metadata/metadata.c
lvm2/upstream/current/lib/metadata/metadata.h
lvm2/upstream/current/lib/metadata/mirror.c
lvm2/upstream/current/lib/metadata/segtype.h
lvm2/upstream/current/lib/mirror/mirrored.c
lvm2/upstream/current/lib/misc/configure.h.in
lvm2/upstream/current/lib/misc/lib.h
lvm2/upstream/current/lib/misc/lvm-file.c
lvm2/upstream/current/lib/misc/lvm-string.c
lvm2/upstream/current/lib/misc/lvm-string.h
lvm2/upstream/current/lib/misc/sharedlib.c
lvm2/upstream/current/lib/mm/memlock.c
lvm2/upstream/current/lib/report/columns.h
lvm2/upstream/current/lib/report/report.c
lvm2/upstream/current/lib/snapshot/snapshot.c
lvm2/upstream/current/lib/zero/zero.c
lvm2/upstream/current/man/Makefile.in
lvm2/upstream/current/man/clvmd.8
lvm2/upstream/current/man/lvchange.8
lvm2/upstream/current/man/lvcreate.8
lvm2/upstream/current/man/lvextend.8
lvm2/upstream/current/man/lvm.8
lvm2/upstream/current/man/lvm.conf.5
lvm2/upstream/current/man/lvreduce.8
lvm2/upstream/current/man/lvresize.8
lvm2/upstream/current/man/vgchange.8
lvm2/upstream/current/man/vgscan.8
lvm2/upstream/current/scripts/clvmd_init_rhel4
lvm2/upstream/current/scripts/lvmconf.sh
lvm2/upstream/current/tools/Makefile.in
lvm2/upstream/current/tools/args.h
lvm2/upstream/current/tools/commands.h
lvm2/upstream/current/tools/lvchange.c
lvm2/upstream/current/tools/lvconvert.c
lvm2/upstream/current/tools/lvcreate.c
lvm2/upstream/current/tools/lvm2cmdline.h
lvm2/upstream/current/tools/lvmcmdline.c
lvm2/upstream/current/tools/lvrename.c
lvm2/upstream/current/tools/lvresize.c
lvm2/upstream/current/tools/pvchange.c
lvm2/upstream/current/tools/pvdisplay.c
lvm2/upstream/current/tools/pvmove.c
lvm2/upstream/current/tools/pvresize.c
lvm2/upstream/current/tools/reporter.c
lvm2/upstream/current/tools/toollib.c
lvm2/upstream/current/tools/toollib.h
lvm2/upstream/current/tools/tools.h
lvm2/upstream/current/tools/vgcfgrestore.c
lvm2/upstream/current/tools/vgchange.c
lvm2/upstream/current/tools/vgcreate.c
lvm2/upstream/current/tools/vgextend.c
lvm2/upstream/current/tools/vgmerge.c
lvm2/upstream/current/tools/vgreduce.c
lvm2/upstream/current/tools/vgrename.c
lvm2/upstream/current/tools/vgsplit.c
Log:
Load LVM2.2.02.12 into /lvm2/upstream/current.
Modified: lvm2/upstream/current/VERSION
==============================================================================
--- lvm2/upstream/current/VERSION (original)
+++ lvm2/upstream/current/VERSION Mon Oct 23 08:49:10 2006
@@ -1 +1 @@
-2.02.07 (2006-07-17)
+2.02.12 (2006-10-16)
Modified: lvm2/upstream/current/WHATS_NEW
==============================================================================
--- lvm2/upstream/current/WHATS_NEW (original)
+++ lvm2/upstream/current/WHATS_NEW Mon Oct 23 08:49:10 2006
@@ -1,3 +1,81 @@
+Version 2.02.12 - 16th October 2006
+===================================
+ Fix pvdisplay to use vg_read() for non-orphans.
+ Fall back to internal locking if external locking lib is missing or fails.
+ Retain activation state after changing LV minor number with --force.
+ Propagate clustered flag in vgsplit and require resizeable flag.
+
+Version 2.02.11 - 12th October 2006
+===================================
+ Add clvmd function to return the cluster name. not used by LVM yet.
+ Add cling allocation policy.
+ Change _check_contiguous() to use _for_each_pv().
+ Extend _for_each_pv() to allow termination without error.
+ Abstract _is_contiguous().
+ Remove duplicated pv arg from _check_contiguous().
+ Accept regionsize with lvconvert.
+ Add report columns with underscore before field names ending 'size'.
+ Correct regionsize default on lvcreate man page (MB).
+ Fix clvmd bug that could cause it to die when a node with a long name crashed.
+ Add device size to text metadata.
+ Fix format_text mda_setup pv->size and pv_setup pe_count calculations.
+ Fix _for_each_pv() for mirror with core log.
+ Add lvm_dump.sh script to create a tarball of debugging info from a system.
+ Capture error messages in clvmd and pass them back to the user.
+ Remove unused #defines from filter-md.c.
+ Make clvmd restart init script wait until clvmd has died before starting it.
+ Add -R to clvmd which tells running clvmds to reload their device cache.
+ Add LV column to reports listing kernel modules needed for activation.
+ Show available fields if report given invalid field. (e.g. lvs -o list)
+ Add timestamp functions with --disable-realtime configure option.
+ Add %VG, %LV and %FREE suffices to lvcreate/lvresize --extents arg.
+ Fix two potential NULL pointer derefs in error cases in vg_read().
+ Separate --enable-cluster from locking lib options in lvmconf.sh.
+ Add a missing comma in lvcreate man page.
+
+Version 2.02.10 - 19th September 2006
+=====================================
+ Fix lvconvert mirror change case detection logic.
+ Fix mirror log detachment so it correctly becomes a standalone LV.
+ Extend _check_contiguous() to detect single-area LVs.
+ Include mirror log (untested) in _for_each_pv() processing.
+ Use MIRROR_LOG_SIZE constant.
+ Remove struct seg_pvs from _for_each_pv() to generalise.
+ Avoid adding duplicates to list of parallel PVs to avoid.
+ Fix several incorrect comparisons in parallel area avoidance code.
+ Fix segment lengths when flattening existing parallel areas.
+ Log existing parallel areas prior to allocation.
+ Fix mirror log creation when activation disabled.
+ Don't attempt automatic recovery without proper locking.
+ When using local file locking, skip clustered VGs.
+ Add fallback_to_clustered_locking and fallback_to_local_locking parameters.
+ lvm.static uses built-in cluster locking instead of external locking.
+ Don't attempt to load shared libraries if built statically.
+ Change default locking_lib to liblvm2clusterlock.so.
+ Add skip_dev_dir() to process command line VGs.
+ Stop clvmd complaining about nodes that have left the cluster.
+ Move lvm_snprintf(), split_words() and split_dm_name() into libdevmapper.
+ Add lvconvert man page.
+ Add mirror options to man pages.
+ Prevent mirror renames.
+ Move CMDLIB code into separate file and record whether static build.
+
+Version 2.02.09 - 17th August 2006
+==================================
+ Fix PE_ALIGN for pagesize over 32KB.
+ Separate out LVM1_PE_ALIGN and pe_align().
+ Add lvm_getpagesize wrapper.
+ Add --maxphysicalvolumes to vgchange.
+
+Version 2.02.08 - 15th August 2006
+==================================
+ Add checks for duplicate LV name, lvid and PV id before writing metadata.
+ Report all sanity check failures, not just the first.
+ Fix missing lockfs on first snapshot creation.
+ Add unreliable --trustcache option to reporting commands.
+ Fix locking for mimage removal.
+ Fix clvmd_init_rhel4 'status' exit code.
+
Version 2.02.07 - 17th July 2006
================================
Fix activation logic in lvchange --persistent.
Modified: lvm2/upstream/current/configure
==============================================================================
--- lvm2/upstream/current/configure (original)
+++ lvm2/upstream/current/configure Mon Oct 23 08:49:10 2006
@@ -310,7 +310,7 @@
#endif"
ac_default_prefix=/usr
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os AWK CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S SET_MAKE RANLIB ac_ct_RANLIB CFLOW_CMD CSCOPE_CMD CPP EGREP ALLOCA LIBOBJS POW_LIB MSGFMT MODPROBE_CMD JOBS STATIC_LINK LVM1 POOL SNAPSHOTS MIRRORS OWNER GROUP COPTIMISE_FLAG CLDFLAGS CLDWHOLEARCHIVE CLDNOWHOLEARCHIVE LDDEPS LIB_SUFFIX LVM_VERSION LVM1_FALLBACK DEBUG DEVMAPPER HAVE_LIBDL HAVE_SELINUX CMDLIB LOCALEDIR CONFDIR STATICDIR INTL_PACKAGE INTL CLVMD CLUSTER FSADM DMEVENTD LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os AWK CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S SET_MAKE RANLIB ac_ct_RANLIB CFLOW_CMD CSCOPE_CMD CPP EGREP ALLOCA LIBOBJS POW_LIB MSGFMT MODPROBE_CMD JOBS STATIC_LINK LVM1 POOL SNAPSHOTS MIRRORS OWNER GROUP COPTIMISE_FLAG CLDFLAGS CLDWHOLEARCHIVE CLDNOWHOLEARCHIVE LDDEPS LIB_SUFFIX LVM_VERSION LVM1_FALLBACK DEBUG DEVMAPPER HAVE_LIBDL HAVE_SELINUX HAVE_REALTIME CMDLIB LOCALEDIR CONFDIR STATICDIR INTL_PACKAGE INTL CLVMD CLUSTER FSADM DMEVENTD LTLIBOBJS'
ac_subst_files=''
# Initialize some variables set by options.
@@ -853,6 +853,7 @@
statically. Default is dynamic linking
--enable-readline Enable readline support
--disable-selinux Disable selinux support
+ --disable-realtime Disable realtime clock support
--enable-debug Enable debugging
--disable-devmapper Disable device-mapper interaction
--disable-o_direct Disable O_DIRECT
@@ -1459,6 +1460,7 @@
DEVMAPPER=yes
ODIRECT=yes
SELINUX=yes
+ REALTIME=yes
CLUSTER=internal
FSADM=no ;;
darwin*)
@@ -1473,6 +1475,7 @@
DEVMAPPER=yes
ODIRECT=no
SELINUX=no
+ REALTIME=no
CLUSTER=none
FSADM=no ;;
esac
@@ -7432,6 +7435,17 @@
echo "${ECHO_T}$SELINUX" >&6
################################################################################
+echo "$as_me:$LINENO: checking whether to enable realtime support" >&5
+echo $ECHO_N "checking whether to enable realtime support... $ECHO_C" >&6
+# Check whether --enable-realtime or --disable-realtime was given.
+if test "${enable_realtime+set}" = set; then
+ enableval="$enable_realtime"
+ REALTIME=$enableval
+fi;
+echo "$as_me:$LINENO: result: $REALTIME" >&5
+echo "${ECHO_T}$REALTIME" >&6
+
+################################################################################
echo "$as_me:$LINENO: checking whether to build cluster LVM daemon" >&5
echo $ECHO_N "checking whether to build cluster LVM daemon... $ECHO_C" >&6
@@ -7534,14 +7548,6 @@
echo "$as_me:$LINENO: result: $CMDLIB" >&5
echo "${ECHO_T}$CMDLIB" >&6
-if test x$CMDLIB = xyes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define CMDLIB 1
-_ACEOF
-
-fi
-
################################################################################
echo "$as_me:$LINENO: checking whether to build fsadm" >&5
echo $ECHO_N "checking whether to build fsadm... $ECHO_C" >&6
@@ -8429,6 +8435,96 @@
fi
################################################################################
+if test x$REALTIME = xyes; then
+ echo "$as_me:$LINENO: checking for clock_gettime function" >&5
+echo $ECHO_N "checking for clock_gettime function... $ECHO_C" >&6
+ echo "$as_me:$LINENO: checking for clock_gettime in -lrt" >&5
+echo $ECHO_N "checking for clock_gettime in -lrt... $ECHO_C" >&6
+if test "${ac_cv_lib_rt_clock_gettime+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lrt $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char clock_gettime ();
+int
+main ()
+{
+clock_gettime ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_rt_clock_gettime=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_rt_clock_gettime=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_rt_clock_gettime" >&5
+echo "${ECHO_T}$ac_cv_lib_rt_clock_gettime" >&6
+if test $ac_cv_lib_rt_clock_gettime = yes; then
+ HAVE_REALTIME=yes
+else
+ HAVE_REALTIME=no
+fi
+
+ echo "$as_me:$LINENO: result: $HAVE_REALTIME" >&5
+echo "${ECHO_T}$HAVE_REALTIME" >&6
+
+ if test x$HAVE_REALTIME = xyes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_REALTIME 1
+_ACEOF
+
+ LIBS="-lrt $LIBS"
+ else
+ { echo "$as_me:$LINENO: WARNING: Disabling realtime clock" >&5
+echo "$as_me: WARNING: Disabling realtime clock" >&2;}
+ fi
+fi
+
+################################################################################
for ac_header in getopt.h
do
@@ -11105,6 +11201,7 @@
+
################################################################################
ac_config_files="$ac_config_files Makefile make.tmpl daemons/Makefile daemons/clvmd/Makefile dmeventd/Makefile dmeventd/mirror/Makefile doc/Makefile include/Makefile lib/Makefile lib/format1/Makefile lib/format_pool/Makefile lib/locking/Makefile lib/mirror/Makefile lib/snapshot/Makefile man/Makefile po/Makefile tools/Makefile tools/version.h tools/fsadm/Makefile test/mm/Makefile test/device/Makefile test/format1/Makefile test/regex/Makefile test/filters/Makefile"
cat >confcache <<\_ACEOF
@@ -11797,6 +11894,7 @@
s, at DEVMAPPER@,$DEVMAPPER,;t t
s, at HAVE_LIBDL@,$HAVE_LIBDL,;t t
s, at HAVE_SELINUX@,$HAVE_SELINUX,;t t
+s, at HAVE_REALTIME@,$HAVE_REALTIME,;t t
s, at CMDLIB@,$CMDLIB,;t t
s, at LOCALEDIR@,$LOCALEDIR,;t t
s, at CONFDIR@,$CONFDIR,;t t
Modified: lvm2/upstream/current/configure.in
==============================================================================
--- lvm2/upstream/current/configure.in (original)
+++ lvm2/upstream/current/configure.in Mon Oct 23 08:49:10 2006
@@ -42,6 +42,7 @@
DEVMAPPER=yes
ODIRECT=yes
SELINUX=yes
+ REALTIME=yes
CLUSTER=internal
FSADM=no ;;
darwin*)
@@ -56,6 +57,7 @@
DEVMAPPER=yes
ODIRECT=no
SELINUX=no
+ REALTIME=no
CLUSTER=none
FSADM=no ;;
esac
@@ -283,6 +285,13 @@
AC_MSG_RESULT($SELINUX)
################################################################################
+dnl -- Disable realtime clock support
+AC_MSG_CHECKING(whether to enable realtime support)
+AC_ARG_ENABLE(realtime, [ --disable-realtime Disable realtime clock support],
+REALTIME=$enableval)
+AC_MSG_RESULT($REALTIME)
+
+################################################################################
dnl -- Build cluster LVM daemon
AC_MSG_CHECKING(whether to build cluster LVM daemon)
AC_ARG_WITH(clvmd,
@@ -351,10 +360,6 @@
CMDLIB=$enableval, CMDLIB=no)
AC_MSG_RESULT($CMDLIB)
-if test x$CMDLIB = xyes; then
- AC_DEFINE([CMDLIB], 1, [Define to 1 to build the shared command library.])
-fi
-
################################################################################
dnl -- Enable fsadm
AC_MSG_CHECKING(whether to build fsadm)
@@ -454,6 +459,21 @@
fi
################################################################################
+dnl -- Check for realtime clock support
+if test x$REALTIME = xyes; then
+ AC_MSG_CHECKING(for clock_gettime function)
+ AC_CHECK_LIB(rt, clock_gettime, HAVE_REALTIME=yes, HAVE_REALTIME=no)
+ AC_MSG_RESULT($HAVE_REALTIME)
+
+ if test x$HAVE_REALTIME = xyes; then
+ AC_DEFINE([HAVE_REALTIME], 1, [Define to 1 to include support for realtime clock.])
+ LIBS="-lrt $LIBS"
+ else
+ AC_MSG_WARN(Disabling realtime clock)
+ fi
+fi
+
+################################################################################
dnl -- Check for getopt
AC_CHECK_HEADERS(getopt.h, AC_DEFINE([HAVE_GETOPTLONG], 1, [Define to 1 to if getopt_long is available.]))
@@ -582,6 +602,7 @@
AC_SUBST(DEVMAPPER)
AC_SUBST(HAVE_LIBDL)
AC_SUBST(HAVE_SELINUX)
+AC_SUBST(HAVE_REALTIME)
AC_SUBST(CMDLIB)
AC_SUBST(MSGFMT)
AC_SUBST(LOCALEDIR)
Modified: lvm2/upstream/current/daemons/clvmd/Makefile.in
==============================================================================
--- lvm2/upstream/current/daemons/clvmd/Makefile.in (original)
+++ lvm2/upstream/current/daemons/clvmd/Makefile.in Mon Oct 23 08:49:10 2006
@@ -19,6 +19,7 @@
clvmd-command.c \
clvmd.c \
lvm-functions.c \
+ refresh_clvmd.c \
system-lv.c
ifeq ("@CLVMD@", "gulm")
Modified: lvm2/upstream/current/daemons/clvmd/clvm.h
==============================================================================
--- lvm2/upstream/current/daemons/clvmd/clvm.h (original)
+++ lvm2/upstream/current/daemons/clvmd/clvm.h Mon Oct 23 08:49:10 2006
@@ -63,4 +63,8 @@
#define CLVMD_CMD_LOCK_LV 50
#define CLVMD_CMD_LOCK_VG 51
+/* Misc functions */
+#define CLVMD_CMD_REFRESH 40
+#define CLVMD_CMD_GET_CLUSTERNAME 41
+
#endif
Modified: lvm2/upstream/current/daemons/clvmd/clvmd-cman.c
==============================================================================
--- lvm2/upstream/current/daemons/clvmd/clvmd-cman.c (original)
+++ lvm2/upstream/current/daemons/clvmd/clvmd-cman.c Mon Oct 23 08:49:10 2006
@@ -137,7 +137,7 @@
if (cman_send_data(c_handle, buf, msglen, 0, CLUSTER_PORT_CLVMD, nodeid) <= 0)
{
- log_error(errtext);
+ log_error(errtext);
}
return msglen;
}
@@ -152,16 +152,18 @@
/* Call a callback routine for each node is that known (down means not running a clvmd) */
static int _cluster_do_node_callback(struct local_client *client,
- void (*callback) (struct local_client *, char *,
- int))
+ void (*callback) (struct local_client *, char *,
+ int))
{
int i;
int somedown = 0;
for (i = 0; i < _get_num_nodes(); i++) {
- callback(client, (char *)&nodes[i].cn_nodeid, node_updown[nodes[i].cn_nodeid]);
- if (!node_updown[nodes[i].cn_nodeid])
- somedown = -1;
+ if (nodes[i].cn_member) {
+ callback(client, (char *)&nodes[i].cn_nodeid, node_updown[nodes[i].cn_nodeid]);
+ if (!node_updown[nodes[i].cn_nodeid])
+ somedown = -1;
+ }
}
return somedown;
}
@@ -170,7 +172,7 @@
this currently just means that a node has stopped listening on our port */
static void event_callback(cman_handle_t handle, void *private, int reason, int arg)
{
- char namebuf[MAX_CLUSTER_NAME_LEN];
+ char namebuf[MAX_CLUSTER_MEMBER_NAME_LEN];
switch (reason) {
case CMAN_REASON_PORTCLOSED:
@@ -205,7 +207,7 @@
static struct local_client *cman_client;
static int _cluster_fd_callback(struct local_client *fd, char *buf, int len, char *csid,
- struct local_client **new_client)
+ struct local_client **new_client)
{
/* Save this for data_callback */
@@ -243,7 +245,7 @@
max_updown_nodes);
} else {
log_error
- ("Realloc failed. Node status for clvmd will be wrong. quitting\n");
+ ("Realloc failed. Node status for clvmd will be wrong. quitting\n");
exit(999);
}
}
@@ -297,35 +299,36 @@
return;
}
- /* Not enough room for new nodes list ? */
- if (num_nodes > count_nodes && nodes) {
- free(nodes);
- nodes = NULL;
- }
+ /* Not enough room for new nodes list ? */
+ if (num_nodes > count_nodes && nodes) {
+ free(nodes);
+ nodes = NULL;
+ }
- if (nodes == NULL) {
- count_nodes = num_nodes + 10; /* Overallocate a little */
+ if (nodes == NULL) {
+ count_nodes = num_nodes + 10; /* Overallocate a little */
nodes = malloc(count_nodes * sizeof(struct cman_node));
- if (!nodes) {
- log_error("Unable to allocate nodes array\n");
- exit(5);
- }
+ if (!nodes) {
+ log_error("Unable to allocate nodes array\n");
+ exit(5);
}
+ }
status = cman_get_nodes(c_handle, count_nodes, &retnodes, nodes);
if (status < 0) {
- log_error("Unable to get node details");
- exit(6);
- }
+ log_error("Unable to get node details");
+ exit(6);
+ }
- if (node_updown == NULL) {
- node_updown =
- (int *) malloc(sizeof(int) *
- max(num_nodes, max_updown_nodes));
- memset(node_updown, 0,
- sizeof(int) * max(num_nodes, max_updown_nodes));
- }
+ if (node_updown == NULL) {
+ node_updown =
+ (int *) malloc(sizeof(int) *
+ max(num_nodes, max_updown_nodes));
+ memset(node_updown, 0,
+ sizeof(int) * max(num_nodes, max_updown_nodes));
}
+}
+
/* Convert a node name to a CSID */
static int _csid_from_name(char *csid, char *name)
@@ -468,6 +471,18 @@
}
+static int _get_cluster_name(char *buf, int buflen)
+{
+ cman_cluster_t cluster_info;
+ int status;
+
+ status = cman_get_cluster(c_handle, &cluster_info);
+ if (!status) {
+ strncpy(buf, cluster_info.ci_name, buflen);
+ }
+ return status;
+}
+
static struct cluster_ops _cluster_cman_ops = {
.cluster_init_completed = _cluster_init_completed,
.cluster_send_message = _cluster_send_message,
@@ -481,6 +496,7 @@
.get_our_csid = _get_our_csid,
.add_up_node = _add_up_node,
.cluster_closedown = _cluster_closedown,
+ .get_cluster_name = _get_cluster_name,
.sync_lock = _sync_lock,
.sync_unlock = _sync_unlock,
};
Modified: lvm2/upstream/current/daemons/clvmd/clvmd-command.c
==============================================================================
--- lvm2/upstream/current/daemons/clvmd/clvmd-command.c (original)
+++ lvm2/upstream/current/daemons/clvmd/clvmd-command.c Mon Oct 23 08:49:10 2006
@@ -75,6 +75,8 @@
#include "clvmd.h"
#include "libdlm.h"
+extern struct cluster_ops *clops;
+
/* This is where all the real work happens:
NOTE: client will be NULL when this is executed on a remote node */
int do_command(struct local_client *client, struct clvm_header *msg, int msglen,
@@ -117,11 +119,21 @@
if (status == EIO) {
*retlen =
1 + snprintf(*buf, buflen,
- "Internal lvm error, check syslog");
+ get_last_lvm_error());
return EIO;
}
break;
+ case CLVMD_CMD_REFRESH:
+ do_refresh_cache();
+ break;
+
+ case CLVMD_CMD_GET_CLUSTERNAME:
+ status = clops->get_cluster_name(*buf, buflen);
+ if (!status)
+ *retlen = strlen(*buf);
+ break;
+
default:
/* Won't get here because command is validated in pre_command */
break;
@@ -222,6 +234,10 @@
status = pre_lock_lv(lock_cmd, lock_flags, lockname);
break;
+ case CLVMD_CMD_REFRESH:
+ case CLVMD_CMD_GET_CLUSTERNAME:
+ break;
+
default:
log_error("Unknown command %d received\n", header->cmd);
status = EINVAL;
Modified: lvm2/upstream/current/daemons/clvmd/clvmd-comms.h
==============================================================================
--- lvm2/upstream/current/daemons/clvmd/clvmd-comms.h (original)
+++ lvm2/upstream/current/daemons/clvmd/clvmd-comms.h Mon Oct 23 08:49:10 2006
@@ -43,6 +43,8 @@
void (*reread_config) (void);
void (*cluster_closedown) (void);
+ int (*get_cluster_name)(char *buf, int buflen);
+
int (*sync_lock) (const char *resource, int mode, int flags, int *lockid);
int (*sync_unlock) (const char *resource, int lockid);
Modified: lvm2/upstream/current/daemons/clvmd/clvmd-gulm.c
==============================================================================
--- lvm2/upstream/current/daemons/clvmd/clvmd-gulm.c (original)
+++ lvm2/upstream/current/daemons/clvmd/clvmd-gulm.c Mon Oct 23 08:49:10 2006
@@ -973,6 +973,12 @@
return gulm_cluster_send_message(buf, msglen, csid, errtext);
}
+static int _get_cluster_name(char *buf, int buflen)
+{
+ strncpy(buf, cluster_name, buflen);
+ return 0;
+}
+
static struct cluster_ops _cluster_gulm_ops = {
.cluster_init_completed = NULL,
.cluster_send_message = _cluster_send_message,
@@ -987,6 +993,7 @@
.add_up_node = gulm_add_up_node,
.reread_config = _reread_config,
.cluster_closedown = _cluster_closedown,
+ .get_cluster_name = _get_cluster_name,
.sync_lock = _sync_lock,
.sync_unlock = _sync_unlock,
};
Modified: lvm2/upstream/current/daemons/clvmd/clvmd.c
==============================================================================
--- lvm2/upstream/current/daemons/clvmd/clvmd.c (original)
+++ lvm2/upstream/current/daemons/clvmd/clvmd.c Mon Oct 23 08:49:10 2006
@@ -42,6 +42,7 @@
#include "clvm.h"
#include "version.h"
#include "clvmd.h"
+#include "refresh_clvmd.h"
#include "libdlm.h"
#include "system-lv.h"
#include "list.h"
@@ -66,7 +67,7 @@
static unsigned short global_xid = 0; /* Last transaction ID issued */
-static struct cluster_ops *clops = NULL;
+struct cluster_ops *clops = NULL;
static char our_csid[MAX_CSID_LEN];
static unsigned max_csid_len;
@@ -143,6 +144,7 @@
fprintf(file, " -V Show version of clvmd\n");
fprintf(file, " -h Show this help information\n");
fprintf(file, " -d Don't fork, run in the foreground\n");
+ fprintf(file, " -R Tell all running clvmds in the cluster to reload their device cache\n");
fprintf(file, " -t<secs> Command timeout (default 60 seconds)\n");
fprintf(file, "\n");
}
@@ -173,7 +175,7 @@
/* Deal with command-line arguments */
opterr = 0;
optind = 0;
- while ((opt = getopt(argc, argv, "?vVhdt:")) != EOF) {
+ while ((opt = getopt(argc, argv, "?vVhdt:R")) != EOF) {
switch (opt) {
case 'h':
usage(argv[0], stdout);
@@ -183,6 +185,9 @@
usage(argv[0], stderr);
exit(0);
+ case 'R':
+ return refresh_clvmd();
+
case 'd':
debug++;
break;
@@ -1684,6 +1689,7 @@
}
pthread_mutex_unlock(&lvm_thread_mutex);
}
+ return NULL;
}
/* Pass down some work to the LVM thread */
Modified: lvm2/upstream/current/daemons/clvmd/lvm-functions.c
==============================================================================
--- lvm2/upstream/current/daemons/clvmd/lvm-functions.c (original)
+++ lvm2/upstream/current/daemons/clvmd/lvm-functions.c Mon Oct 23 08:49:10 2006
@@ -50,12 +50,18 @@
static struct cmd_context *cmd = NULL;
static struct dm_hash_table *lv_hash = NULL;
static pthread_mutex_t lv_hash_lock;
+static char last_error[1024];
struct lv_info {
int lock_id;
int lock_mode;
};
+char *get_last_lvm_error()
+{
+ return last_error;
+}
+
/* Return the mode a lock is currently held at (or -1 if not held) */
static int get_current_lock(char *resource)
{
@@ -201,8 +207,17 @@
/* Try to get the lock if it's a clustered volume group */
if (lock_flags & LCK_CLUSTER_VG) {
status = hold_lock(resource, mode, LKF_NOQUEUE);
- if (status)
+ if (status) {
+ /* Return an LVM-sensible error for this.
+ * Forcing EIO makes the upper level return this text
+ * rather than the strerror text for EAGAIN.
+ */
+ if (errno == EAGAIN) {
+ sprintf(last_error, "Volume is busy on another node");
+ errno = EIO;
+ }
return errno;
+ }
}
/* If it's suspended then resume it */
@@ -416,6 +431,13 @@
return status == 1 ? 0 : EBUSY;
}
+int do_refresh_cache()
+{
+ DEBUGLOG("Refreshing context\n");
+ log_notice("Refreshing context");
+ return refresh_toolcontext(cmd)==1?0:-1;
+}
+
/* Only called at gulm startup. Drop any leftover VG or P_orphan locks
that might be hanging around if we died for any reason
@@ -505,6 +527,20 @@
return NULL;
}
+static void lvm2_log_fn(int level, const char *file, int line,
+ const char *message)
+{
+ /*
+ * Ignore non-error messages, but store the latest one for returning
+ * to the user.
+ */
+ if (level != _LOG_ERR && level != _LOG_FATAL)
+ return;
+
+ strncpy(last_error, message, sizeof(last_error));
+ last_error[sizeof(last_error)-1] = '\0';
+}
+
/* This checks some basic cluster-LVM configuration stuff */
static void check_config()
{
@@ -539,7 +575,7 @@
/* Called to initialise the LVM context of the daemon */
int init_lvm(int using_gulm)
{
- if (!(cmd = create_toolcontext(NULL))) {
+ if (!(cmd = create_toolcontext(NULL, 0))) {
log_error("Failed to allocate command context");
return 0;
}
@@ -557,5 +593,8 @@
get_initial_state();
+ /* Trap log messages so we can pass them back to the user */
+ init_log_fn(lvm2_log_fn);
+
return 1;
}
Modified: lvm2/upstream/current/daemons/clvmd/lvm-functions.h
==============================================================================
--- lvm2/upstream/current/daemons/clvmd/lvm-functions.h (original)
+++ lvm2/upstream/current/daemons/clvmd/lvm-functions.h Mon Oct 23 08:49:10 2006
@@ -25,11 +25,13 @@
extern int post_lock_lv(unsigned char lock_cmd, unsigned char lock_flags,
char *resource);
extern int do_check_lvm1(char *vgname);
+extern int do_refresh_cache(void);
extern int init_lvm(int using_gulm);
extern void init_lvhash(void);
extern int hold_unlock(char *resource);
extern int hold_lock(char *resource, int mode, int flags);
extern void unlock_all(void);
+extern char *get_last_lvm_error(void);
#endif
Added: lvm2/upstream/current/daemons/clvmd/refresh_clvmd.c
==============================================================================
--- (empty file)
+++ lvm2/upstream/current/daemons/clvmd/refresh_clvmd.c Mon Oct 23 08:49:10 2006
@@ -0,0 +1,334 @@
+/*
+ * Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
+ * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Tell all clvmds in a cluster to refresh their toolcontext
+ *
+ */
+
+#include <stddef.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <errno.h>
+#include <unistd.h>
+#include <libdevmapper.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#include "clvm.h"
+#include "refresh_clvmd.h"
+
+typedef struct lvm_response {
+ char node[255];
+ char *response;
+ int status;
+ int len;
+} lvm_response_t;
+
+/*
+ * This gets stuck at the start of memory we allocate so we
+ * can sanity-check it at deallocation time
+ */
+#define LVM_SIGNATURE 0x434C564D
+
+static int _clvmd_sock = -1;
+
+/* Open connection to the Cluster Manager daemon */
+static int _open_local_sock(void)
+{
+ int local_socket;
+ struct sockaddr_un sockaddr;
+
+ /* Open local socket */
+ if ((local_socket = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
+ fprintf(stderr, "Local socket creation failed: %s", strerror(errno));
+ return -1;
+ }
+
+ memset(&sockaddr, 0, sizeof(sockaddr));
+ memcpy(sockaddr.sun_path, CLVMD_SOCKNAME, sizeof(CLVMD_SOCKNAME));
+
+ sockaddr.sun_family = AF_UNIX;
+
+ if (connect(local_socket,(struct sockaddr *) &sockaddr,
+ sizeof(sockaddr))) {
+ int saved_errno = errno;
+
+ fprintf(stderr, "connect() failed on local socket: %s\n",
+ strerror(errno));
+ if (close(local_socket))
+ return -1;
+
+ errno = saved_errno;
+ return -1;
+ }
+
+ return local_socket;
+}
+
+/* Send a request and return the status */
+static int _send_request(char *inbuf, int inlen, char **retbuf)
+{
+ char outbuf[PIPE_BUF];
+ struct clvm_header *outheader = (struct clvm_header *) outbuf;
+ int len;
+ int off;
+ int buflen;
+ int err;
+
+ /* Send it to CLVMD */
+ rewrite:
+ if ( (err = write(_clvmd_sock, inbuf, inlen)) != inlen) {
+ if (err == -1 && errno == EINTR)
+ goto rewrite;
+ fprintf(stderr, "Error writing data to clvmd: %s", strerror(errno));
+ return 0;
+ }
+
+ /* Get the response */
+ reread:
+ if ((len = read(_clvmd_sock, outbuf, sizeof(struct clvm_header))) < 0) {
+ if (errno == EINTR)
+ goto reread;
+ fprintf(stderr, "Error reading data from clvmd: %s", strerror(errno));
+ return 0;
+ }
+
+ if (len == 0) {
+ fprintf(stderr, "EOF reading CLVMD");
+ errno = ENOTCONN;
+ return 0;
+ }
+
+ /* Allocate buffer */
+ buflen = len + outheader->arglen;
+ *retbuf = dm_malloc(buflen);
+ if (!*retbuf) {
+ errno = ENOMEM;
+ return 0;
+ }
+
+ /* Copy the header */
+ memcpy(*retbuf, outbuf, len);
+ outheader = (struct clvm_header *) *retbuf;
+
+ /* Read the returned values */
+ off = 1; /* we've already read the first byte */
+ while (off <= outheader->arglen && len > 0) {
+ len = read(_clvmd_sock, outheader->args + off,
+ buflen - off - offsetof(struct clvm_header, args));
+ if (len > 0)
+ off += len;
+ }
+
+ /* Was it an error ? */
+ if (outheader->status != 0) {
+ errno = outheader->status;
+
+ /* Only return an error here if there are no node-specific
+ errors present in the message that might have more detail */
+ if (!(outheader->flags & CLVMD_FLAG_NODEERRS)) {
+ fprintf(stderr, "cluster request failed: %s\n", strerror(errno));
+ return 0;
+ }
+
+ }
+
+ return 1;
+}
+
+/* Build the structure header and parse-out wildcard node names */
+static void _build_header(struct clvm_header *head, int cmd, const char *node,
+ int len)
+{
+ head->cmd = cmd;
+ head->status = 0;
+ head->flags = 0;
+ head->clientid = 0;
+ head->arglen = len;
+
+ if (node) {
+ /*
+ * Allow a couple of special node names:
+ * "*" for all nodes,
+ * "." for the local node only
+ */
+ if (strcmp(node, "*") == 0) {
+ head->node[0] = '\0';
+ } else if (strcmp(node, ".") == 0) {
+ head->node[0] = '\0';
+ head->flags = CLVMD_FLAG_LOCAL;
+ } else
+ strcpy(head->node, node);
+ } else
+ head->node[0] = '\0';
+}
+
+/*
+ * Send a message to a(or all) node(s) in the cluster and wait for replies
+ */
+static int _cluster_request(char cmd, const char *node, void *data, int len,
+ lvm_response_t ** response, int *num)
+{
+ char outbuf[sizeof(struct clvm_header) + len + strlen(node) + 1];
+ int *outptr;
+ char *inptr;
+ char *retbuf = NULL;
+ int status;
+ int i;
+ int num_responses = 0;
+ struct clvm_header *head = (struct clvm_header *) outbuf;
+ lvm_response_t *rarray;
+
+ *num = 0;
+
+ if (_clvmd_sock == -1)
+ _clvmd_sock = _open_local_sock();
+
+ if (_clvmd_sock == -1)
+ return 0;
+
+ _build_header(head, cmd, node, len);
+ memcpy(head->node + strlen(head->node) + 1, data, len);
+
+ status = _send_request(outbuf, sizeof(struct clvm_header) +
+ strlen(head->node) + len, &retbuf);
+ if (!status)
+ goto out;
+
+ /* Count the number of responses we got */
+ head = (struct clvm_header *) retbuf;
+ inptr = head->args;
+ while (inptr[0]) {
+ num_responses++;
+ inptr += strlen(inptr) + 1;
+ inptr += sizeof(int);
+ inptr += strlen(inptr) + 1;
+ }
+
+ /*
+ * Allocate response array.
+ * With an extra pair of INTs on the front to sanity
+ * check the pointer when we are given it back to free
+ */
+ outptr = dm_malloc(sizeof(lvm_response_t) * num_responses +
+ sizeof(int) * 2);
+ if (!outptr) {
+ errno = ENOMEM;
+ status = 0;
+ goto out;
+ }
+
+ *response = (lvm_response_t *) (outptr + 2);
+ outptr[0] = LVM_SIGNATURE;
+ outptr[1] = num_responses;
+ rarray = *response;
+
+ /* Unpack the response into an lvm_response_t array */
+ inptr = head->args;
+ i = 0;
+ while (inptr[0]) {
+ strcpy(rarray[i].node, inptr);
+ inptr += strlen(inptr) + 1;
+
+ memcpy(&rarray[i].status, inptr, sizeof(int));
+ inptr += sizeof(int);
+
+ rarray[i].response = dm_malloc(strlen(inptr) + 1);
+ if (rarray[i].response == NULL) {
+ /* Free up everything else and return error */
+ int j;
+ for (j = 0; j < i; j++)
+ dm_free(rarray[i].response);
+ free(outptr);
+ errno = ENOMEM;
+ status = -1;
+ goto out;
+ }
+
+ strcpy(rarray[i].response, inptr);
+ rarray[i].len = strlen(inptr);
+ inptr += strlen(inptr) + 1;
+ i++;
+ }
+ *num = num_responses;
+ *response = rarray;
+
+ out:
+ if (retbuf)
+ dm_free(retbuf);
+
+ return status;
+}
+
+/* Free reply array */
+static int _cluster_free_request(lvm_response_t * response)
+{
+ int *ptr = (int *) response - 2;
+ int i;
+ int num;
+
+ /* Check it's ours to free */
+ if (response == NULL || *ptr != LVM_SIGNATURE) {
+ errno = EINVAL;
+ return 0;
+ }
+
+ num = ptr[1];
+
+ for (i = 0; i < num; i++) {
+ dm_free(response[i].response);
+ }
+
+ dm_free(ptr);
+
+ return 1;
+}
+
+int refresh_clvmd()
+{
+ int num_responses;
+ char args[1]; // No args really.
+ lvm_response_t *response;
+ int saved_errno;
+ int status;
+ int i;
+
+ status = _cluster_request(CLVMD_CMD_REFRESH, "*", args, 0, &response, &num_responses);
+
+ /* If any nodes were down then display them and return an error */
+ for (i = 0; i < num_responses; i++) {
+ if (response[i].status == EHOSTDOWN) {
+ fprintf(stderr, "clvmd not running on node %s",
+ response[i].node);
+ status = 0;
+ errno = response[i].status;
+ } else if (response[i].status) {
+ fprintf(stderr, "Error resetting node %s: %s",
+ response[i].node,
+ response[i].response[0] ?
+ response[i].response :
+ strerror(response[i].status));
+ status = 0;
+ errno = response[i].status;
+ }
+ }
+
+ saved_errno = errno;
+ _cluster_free_request(response);
+ errno = saved_errno;
+
+ return status;
+}
Added: lvm2/upstream/current/daemons/clvmd/refresh_clvmd.h
==============================================================================
--- (empty file)
+++ lvm2/upstream/current/daemons/clvmd/refresh_clvmd.h Mon Oct 23 08:49:10 2006
@@ -0,0 +1,2 @@
+int refresh_clvmd(void);
+
Modified: lvm2/upstream/current/dmeventd/mirror/dmeventd_mirror.c
==============================================================================
--- lvm2/upstream/current/dmeventd/mirror/dmeventd_mirror.c (original)
+++ lvm2/upstream/current/dmeventd/mirror/dmeventd_mirror.c Mon Oct 23 08:49:10 2006
@@ -48,7 +48,7 @@
char *p;
int log_argc, num_devs, num_failures=0;
- if (max_args <= split_words(params, max_args, args)) {
+ if (max_args <= dm_split_words(params, max_args, 0, args)) {
syslog(LOG_ERR, "Unable to split mirror parameters: Arg list too long");
return -E2BIG;
}
@@ -121,7 +121,7 @@
if (strlen(device) > 200)
return -ENAMETOOLONG;
- if (!split_dm_name(mem_pool, device, &vg, &lv, &layer)) {
+ if (!dm_split_lvm_name(mem_pool, device, &vg, &lv, &layer)) {
syslog(LOG_ERR, "Unable to determine VG name from %s",
device);
return -ENOMEM;
Modified: lvm2/upstream/current/doc/example.conf
==============================================================================
--- lvm2/upstream/current/doc/example.conf (original)
+++ lvm2/upstream/current/doc/example.conf Mon Oct 23 08:49:10 2006
@@ -207,11 +207,26 @@
# Location of proc filesystem
proc = "/proc"
- # Type of locking to use. Defaults to file-based locking (1).
+ # Type of locking to use. Defaults to local file-based locking (1).
# Turn locking off by setting to 0 (dangerous: risks metadata corruption
# if LVM2 commands get run concurrently).
+ # Type 2 uses the external shared library locking_library.
+ # Type 3 uses built-in clustered locking.
locking_type = 1
+ # If using external locking (type 2) and initialisation fails,
+ # with this set to 1 an attempt will be made to use the built-in
+ # clustered locking.
+ # If you are using a customised locking_library you should set this to 0.
+ fallback_to_clustered_locking = 1
+
+ # If an attempt to initialise type 2 or type 3 locking failed, perhaps
+ # because cluster components such as clvmd are not running, with this set
+ # to 1 an attempt will be made to use local file-based locking (type 1).
+ # If this succeeds, only commands against local volume groups will proceed.
+ # Volume Groups marked as clustered will be ignored.
+ fallback_to_local_locking = 1
+
# Local non-LV directory that holds file-based locks while commands are
# in progress. A directory like /tmp that may get wiped on reboot is OK.
locking_dir = "/var/lock/lvm"
@@ -223,6 +238,9 @@
# Search this directory first for shared libraries.
# library_dir = "/lib"
+
+ # The external locking library to load if locking_type is set to 2.
+ # locking_library = "liblvm2clusterlock.so"
}
activation {
Modified: lvm2/upstream/current/include/.symlinks
==============================================================================
--- lvm2/upstream/current/include/.symlinks (original)
+++ lvm2/upstream/current/include/.symlinks Mon Oct 23 08:49:10 2006
@@ -41,6 +41,7 @@
../lib/misc/lvm-exec.h
../lib/misc/lvm-file.h
../lib/misc/lvm-string.h
+../lib/misc/lvm-wrappers.h
../lib/misc/sharedlib.h
../lib/regex/matcher.h
../lib/report/report.h
Modified: lvm2/upstream/current/lib/Makefile.in
==============================================================================
--- lvm2/upstream/current/lib/Makefile.in (original)
+++ lvm2/upstream/current/lib/Makefile.in Mon Oct 23 08:49:10 2006
@@ -78,6 +78,8 @@
misc/lvm-exec.c \
misc/lvm-file.c \
misc/lvm-string.c \
+ misc/lvm-wrappers.c \
+ misc/timestamp.c \
mm/memlock.c \
regex/matcher.c \
regex/parse_rx.c \
Modified: lvm2/upstream/current/lib/activate/activate.c
==============================================================================
--- lvm2/upstream/current/lib/activate/activate.c (original)
+++ lvm2/upstream/current/lib/activate/activate.c Mon Oct 23 08:49:10 2006
@@ -39,7 +39,7 @@
{
char path[PATH_MAX];
- if (lvm_snprintf(path, sizeof(path), "%s/lvm/global", cmd->proc_dir)
+ if (dm_snprintf(path, sizeof(path), "%s/lvm/global", cmd->proc_dir)
< 0) {
log_error("LVM1 proc global snprintf failed");
return 0;
@@ -51,6 +51,66 @@
return 0;
}
+int list_segment_modules(struct dm_pool *mem, const struct lv_segment *seg,
+ struct list *modules)
+{
+ unsigned int s;
+ struct lv_segment *seg2, *snap_seg;
+ struct list *snh;
+
+ if (seg->segtype->ops->modules_needed &&
+ !seg->segtype->ops->modules_needed(mem, seg, modules)) {
+ log_error("module string allocation failed");
+ return 0;
+ }
+
+ if (lv_is_origin(seg->lv))
+ list_iterate(snh, &seg->lv->snapshot_segs)
+ if (!list_lv_modules(mem,
+ list_struct_base(snh,
+ struct lv_segment,
+ origin_list)->cow,
+ modules))
+ return_0;
+
+ if (lv_is_cow(seg->lv)) {
+ snap_seg = find_cow(seg->lv);
+ if (snap_seg->segtype->ops->modules_needed &&
+ !snap_seg->segtype->ops->modules_needed(mem, snap_seg,
+ modules)) {
+ log_error("snap_seg module string allocation failed");
+ return 0;
+ }
+ }
+
+ for (s = 0; s < seg->area_count; s++) {
+ switch (seg_type(seg, s)) {
+ case AREA_LV:
+ seg2 = find_seg_by_le(seg_lv(seg, s), seg_le(seg, s));
+ if (seg2 && !list_segment_modules(mem, seg2, modules))
+ return_0;
+ break;
+ case AREA_PV:
+ case AREA_UNASSIGNED:
+ ;
+ }
+ }
+
+ return 1;
+}
+
+int list_lv_modules(struct dm_pool *mem, const struct logical_volume *lv,
+ struct list *modules)
+{
+ struct lv_segment *seg;
+
+ list_iterate_items(seg, &lv->segments)
+ if (!list_segment_modules(mem, seg, modules))
+ return_0;
+
+ return 1;
+}
+
#ifndef DEVMAPPER_SUPPORT
void set_activation(int act)
{
@@ -257,9 +317,9 @@
continue;
}
/* vgname/lvname */
- if (lvm_snprintf(path, sizeof(path), "%s/%s", lv->vg->name,
+ if (dm_snprintf(path, sizeof(path), "%s/%s", lv->vg->name,
lv->name) < 0) {
- log_error("lvm_snprintf error from %s/%s", lv->vg->name,
+ log_error("dm_snprintf error from %s/%s", lv->vg->name,
lv->name);
continue;
}
@@ -342,7 +402,7 @@
if (target_version(target_name, &maj, &min, &patchlevel))
return 1;
- if (lvm_snprintf(module, sizeof(module), "dm-%s", target_name)
+ if (dm_snprintf(module, sizeof(module), "dm-%s", target_name)
< 0) {
log_error("target_present module name too long: %s",
target_name);
@@ -528,7 +588,7 @@
return r;
}
-static int _lv_suspend_lv(struct logical_volume *lv)
+static int _lv_suspend_lv(struct logical_volume *lv, int lockfs)
{
int r;
struct dev_manager *dm;
@@ -536,7 +596,7 @@
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name)))
return_0;
- if (!(r = dev_manager_suspend(dm, lv)))
+ if (!(r = dev_manager_suspend(dm, lv, lockfs)))
stack;
dev_manager_destroy(dm);
@@ -637,6 +697,7 @@
{
struct logical_volume *lv, *lv_pre;
struct lvinfo info;
+ int lockfs = 0;
if (!activation())
return 1;
@@ -672,7 +733,11 @@
stack;
memlock_inc();
- if (!_lv_suspend_lv(lv)) {
+
+ if (lv_is_origin(lv_pre) || lv_is_cow(lv_pre))
+ lockfs = 1;
+
+ if (!_lv_suspend_lv(lv, lockfs)) {
memlock_dec();
fs_unlock();
return 0;
Modified: lvm2/upstream/current/lib/activate/activate.h
==============================================================================
--- lvm2/upstream/current/lib/activate/activate.h (original)
+++ lvm2/upstream/current/lib/activate/activate.h Mon Oct 23 08:49:10 2006
@@ -39,6 +39,10 @@
int target_present(const char *target_name, int use_modprobe);
int target_version(const char *target_name, uint32_t *maj,
uint32_t *min, uint32_t *patchlevel);
+int list_segment_modules(struct dm_pool *mem, const struct lv_segment *seg,
+ struct list *modules);
+int list_lv_modules(struct dm_pool *mem, const struct logical_volume *lv,
+ struct list *modules);
void activation_release(void);
void activation_exit(void);
Modified: lvm2/upstream/current/lib/activate/dev_manager.c
==============================================================================
--- lvm2/upstream/current/lib/activate/dev_manager.c (original)
+++ lvm2/upstream/current/lib/activate/dev_manager.c Mon Oct 23 08:49:10 2006
@@ -37,6 +37,7 @@
ACTIVATE,
DEACTIVATE,
SUSPEND,
+ SUSPEND_WITH_LOCKFS,
CLEAN
} action_t;
@@ -911,7 +912,7 @@
name = dm_tree_node_get_name(child);
if (name && lvlayer->old_name && *lvlayer->old_name && strcmp(name, lvlayer->old_name)) {
- if (!split_dm_name(dm->mem, lvlayer->old_name, &vgname, &lvname, &layer)) {
+ if (!dm_split_lvm_name(dm->mem, lvlayer->old_name, &vgname, &lvname, &layer)) {
log_error("_create_lv_symlinks: Couldn't split up old device name %s", lvlayer->old_name);
return 0;
}
@@ -937,7 +938,7 @@
if (!(uuid = dm_tree_node_get_uuid(child)))
continue;
- if (!split_dm_name(dm->mem, name, &vgname, &lvname, &layer)) {
+ if (!dm_split_lvm_name(dm->mem, name, &vgname, &lvname, &layer)) {
log_error("_clean_tree: Couldn't split up device name %s.", name);
return 0;
}
@@ -984,8 +985,8 @@
goto_out;
break;
case SUSPEND:
- if (!lv_is_origin(lv) && !lv_is_cow(lv))
- dm_tree_skip_lockfs(root);
+ dm_tree_skip_lockfs(root);
+ case SUSPEND_WITH_LOCKFS:
if (!dm_tree_suspend_children(root, dlid, ID_LEN + sizeof(UUID_PREFIX) - 1))
goto_out;
break;
@@ -1049,9 +1050,10 @@
return r;
}
-int dev_manager_suspend(struct dev_manager *dm, struct logical_volume *lv)
+int dev_manager_suspend(struct dev_manager *dm, struct logical_volume *lv,
+ int lockfs)
{
- return _tree_action(dm, lv, SUSPEND);
+ return _tree_action(dm, lv, lockfs ? SUSPEND_WITH_LOCKFS : SUSPEND);
}
/*
Modified: lvm2/upstream/current/lib/activate/dev_manager.h
==============================================================================
--- lvm2/upstream/current/lib/activate/dev_manager.h (original)
+++ lvm2/upstream/current/lib/activate/dev_manager.h Mon Oct 23 08:49:10 2006
@@ -47,7 +47,8 @@
int dev_manager_mirror_percent(struct dev_manager *dm,
struct logical_volume *lv, int wait,
float *percent, uint32_t *event_nr);
-int dev_manager_suspend(struct dev_manager *dm, struct logical_volume *lv);
+int dev_manager_suspend(struct dev_manager *dm, struct logical_volume *lv,
+ int lockfs);
int dev_manager_activate(struct dev_manager *dm, struct logical_volume *lv);
int dev_manager_preload(struct dev_manager *dm, struct logical_volume *lv);
int dev_manager_deactivate(struct dev_manager *dm, struct logical_volume *lv);
Modified: lvm2/upstream/current/lib/activate/fs.c
==============================================================================
--- lvm2/upstream/current/lib/activate/fs.c (original)
+++ lvm2/upstream/current/lib/activate/fs.c Mon Oct 23 08:49:10 2006
@@ -30,7 +30,7 @@
{
char vg_path[PATH_MAX];
- if (lvm_snprintf(vg_path, sizeof(vg_path), "%s%s",
+ if (dm_snprintf(vg_path, sizeof(vg_path), "%s%s",
dev_dir, vg_name) == -1) {
log_error("Couldn't construct name of volume "
"group directory.");
@@ -53,7 +53,7 @@
{
char vg_path[PATH_MAX];
- if (lvm_snprintf(vg_path, sizeof(vg_path), "%s%s",
+ if (dm_snprintf(vg_path, sizeof(vg_path), "%s%s",
dev_dir, vg_name) == -1) {
log_error("Couldn't construct name of volume "
"group directory.");
@@ -87,7 +87,7 @@
if (!strcmp(name, ".") || !strcmp(name, ".."))
continue;
- if (lvm_snprintf(path, sizeof(path), "%s/%s", dir, name) == -1) {
+ if (dm_snprintf(path, sizeof(path), "%s/%s", dir, name) == -1) {
log_error("Couldn't create path for %s", name);
continue;
}
@@ -109,28 +109,28 @@
char vg_path[PATH_MAX];
struct stat buf;
- if (lvm_snprintf(vg_path, sizeof(vg_path), "%s%s",
+ if (dm_snprintf(vg_path, sizeof(vg_path), "%s%s",
dev_dir, vg_name) == -1) {
log_error("Couldn't create path for volume group dir %s",
vg_name);
return 0;
}
- if (lvm_snprintf(lv_path, sizeof(lv_path), "%s/%s", vg_path,
+ if (dm_snprintf(lv_path, sizeof(lv_path), "%s/%s", vg_path,
lv_name) == -1) {
log_error("Couldn't create source pathname for "
"logical volume link %s", lv_name);
return 0;
}
- if (lvm_snprintf(link_path, sizeof(link_path), "%s/%s",
+ if (dm_snprintf(link_path, sizeof(link_path), "%s/%s",
dm_dir(), dev) == -1) {
log_error("Couldn't create destination pathname for "
"logical volume link for %s", lv_name);
return 0;
}
- if (lvm_snprintf(lvm1_group_path, sizeof(lvm1_group_path), "%s/group",
+ if (dm_snprintf(lvm1_group_path, sizeof(lvm1_group_path), "%s/group",
vg_path) == -1) {
log_error("Couldn't create pathname for LVM1 group file for %s",
vg_name);
@@ -190,7 +190,7 @@
struct stat buf;
char lv_path[PATH_MAX];
- if (lvm_snprintf(lv_path, sizeof(lv_path), "%s%s/%s",
+ if (dm_snprintf(lv_path, sizeof(lv_path), "%s%s/%s",
dev_dir, vg_name, lv_name) == -1) {
log_error("Couldn't determine link pathname.");
return 0;
Modified: lvm2/upstream/current/lib/cache/lvmcache.c
==============================================================================
--- lvm2/upstream/current/lib/cache/lvmcache.c (original)
+++ lvm2/upstream/current/lib/cache/lvmcache.c Mon Oct 23 08:49:10 2006
@@ -241,7 +241,7 @@
goto out;
}
- if (!(iter = dev_iter_create(cmd->filter, (full_scan == 2) ? 1: 0))) {
+ if (!(iter = dev_iter_create(cmd->filter, (full_scan == 2) ? 1 : 0))) {
log_error("dev_iter creation failed");
goto out;
}
Modified: lvm2/upstream/current/lib/commands/toolcontext.c
==============================================================================
--- lvm2/upstream/current/lib/commands/toolcontext.c (original)
+++ lvm2/upstream/current/lib/commands/toolcontext.c Mon Oct 23 08:49:10 2006
@@ -67,7 +67,7 @@
/* Set to "" to avoid using any system directory */
if ((e = getenv("LVM_SYSTEM_DIR"))) {
- if (lvm_snprintf(cmd->sys_dir, sizeof(cmd->sys_dir),
+ if (dm_snprintf(cmd->sys_dir, sizeof(cmd->sys_dir),
"%s", e) < 0) {
log_error("LVM_SYSTEM_DIR environment variable "
"is too long.");
@@ -167,7 +167,7 @@
log_verbose("Set umask to %04o", cmd->default_settings.umask);
/* dev dir */
- if (lvm_snprintf(cmd->dev_dir, sizeof(cmd->dev_dir), "%s/",
+ if (dm_snprintf(cmd->dev_dir, sizeof(cmd->dev_dir), "%s/",
find_config_tree_str(cmd, "devices/dir",
DEFAULT_DEV_DIR)) < 0) {
log_error("Device directory given in config file too long");
@@ -178,7 +178,7 @@
#endif
/* proc dir */
- if (lvm_snprintf(cmd->proc_dir, sizeof(cmd->proc_dir), "%s",
+ if (dm_snprintf(cmd->proc_dir, sizeof(cmd->proc_dir), "%s",
find_config_tree_str(cmd, "global/proc",
DEFAULT_PROC_DIR)) < 0) {
log_error("Device directory given in config file too long");
@@ -319,7 +319,7 @@
if (*tag)
filler = "_";
- if (lvm_snprintf(config_file, sizeof(config_file), "%s/lvm%s%s.conf",
+ if (dm_snprintf(config_file, sizeof(config_file), "%s/lvm%s%s.conf",
cmd->sys_dir, filler, tag) < 0) {
log_error("LVM_SYSTEM_DIR or tag was too long");
return 0;
@@ -587,7 +587,7 @@
if (!(f3 = _init_filter_components(cmd)))
return 0;
- if (lvm_snprintf(cache_file, sizeof(cache_file),
+ if (dm_snprintf(cache_file, sizeof(cache_file),
"%s/.cache", cmd->sys_dir) < 0) {
log_error("Persistent cache filename too long ('%s/.cache').",
cmd->sys_dir);
@@ -646,8 +646,9 @@
#endif
#ifdef HAVE_LIBDL
- /* Load any formats in shared libs */
- if ((cn = find_config_tree_node(cmd, "global/format_libraries"))) {
+ /* Load any formats in shared libs if not static */
+ if (!cmd->is_static &&
+ (cn = find_config_tree_node(cmd, "global/format_libraries"))) {
struct config_value *cv;
struct format_type *(*init_format_fn) (struct cmd_context *);
@@ -740,8 +741,9 @@
#endif
#ifdef HAVE_LIBDL
- /* Load any formats in shared libs */
- if ((cn = find_config_tree_node(cmd, "global/segment_libraries"))) {
+ /* Load any formats in shared libs unless static */
+ if (!cmd->is_static &&
+ (cn = find_config_tree_node(cmd, "global/segment_libraries"))) {
struct config_value *cv;
struct segment_type *(*init_segtype_fn) (struct cmd_context *);
@@ -839,7 +841,7 @@
min = (uint32_t) find_config_tree_int(cmd, "backup/retain_min",
DEFAULT_ARCHIVE_NUMBER);
- if (lvm_snprintf
+ if (dm_snprintf
(default_dir, sizeof(default_dir), "%s/%s", cmd->sys_dir,
DEFAULT_ARCHIVE_SUBDIR) == -1) {
log_err("Couldn't create default archive path '%s/%s'.",
@@ -860,7 +862,7 @@
find_config_tree_bool(cmd, "backup/backup",
DEFAULT_BACKUP_ENABLED);
- if (lvm_snprintf
+ if (dm_snprintf
(default_dir, sizeof(default_dir), "%s/%s", cmd->sys_dir,
DEFAULT_BACKUP_SUBDIR) == -1) {
log_err("Couldn't create default backup path '%s/%s'.",
@@ -879,7 +881,7 @@
}
/* Entry point */
-struct cmd_context *create_toolcontext(struct arg *the_args)
+struct cmd_context *create_toolcontext(struct arg *the_args, unsigned is_static)
{
struct cmd_context *cmd;
@@ -902,6 +904,7 @@
}
memset(cmd, 0, sizeof(*cmd));
cmd->args = the_args;
+ cmd->is_static = is_static;
cmd->hosttags = 0;
list_init(&cmd->formats);
list_init(&cmd->segtypes);
Modified: lvm2/upstream/current/lib/commands/toolcontext.h
==============================================================================
--- lvm2/upstream/current/lib/commands/toolcontext.h (original)
+++ lvm2/upstream/current/lib/commands/toolcontext.h Mon Oct 23 08:49:10 2006
@@ -64,6 +64,7 @@
struct command *command;
struct arg *args;
char **argv;
+ unsigned is_static; /* Static binary? */
struct dev_filter *filter;
int dump_filter; /* Dump filter when exiting? */
@@ -87,7 +88,7 @@
char proc_dir[PATH_MAX];
};
-struct cmd_context *create_toolcontext(struct arg *the_args);
+struct cmd_context *create_toolcontext(struct arg *the_args, unsigned is_static);
void destroy_toolcontext(struct cmd_context *cmd);
int refresh_toolcontext(struct cmd_context *cmd);
int config_files_changed(struct cmd_context *cmd);
Modified: lvm2/upstream/current/lib/config/config.c
==============================================================================
--- lvm2/upstream/current/lib/config/config.c (original)
+++ lvm2/upstream/current/lib/config/config.c Mon Oct 23 08:49:10 2006
@@ -187,7 +187,7 @@
use_mmap = 0;
if (use_mmap) {
- mmap_offset = offset % getpagesize();
+ mmap_offset = offset % lvm_getpagesize();
/* memory map the file */
p->fb = mmap((caddr_t) 0, size + mmap_offset, PROT_READ,
MAP_PRIVATE, dev_fd(dev), offset - mmap_offset);
Modified: lvm2/upstream/current/lib/config/defaults.h
==============================================================================
--- lvm2/upstream/current/lib/config/defaults.h (original)
+++ lvm2/upstream/current/lib/config/defaults.h Mon Oct 23 08:49:10 2006
@@ -32,7 +32,9 @@
#define DEFAULT_MD_COMPONENT_DETECTION 1
#define DEFAULT_LOCK_DIR "/var/lock/lvm"
-#define DEFAULT_LOCKING_LIB "lvm2_locking.so"
+#define DEFAULT_LOCKING_LIB "liblvm2clusterlock.so"
+#define DEFAULT_FALLBACK_TO_LOCAL_LOCKING 1
+#define DEFAULT_FALLBACK_TO_CLUSTERED_LOCKING 1
#define DEFAULT_MIRROR_LOG_FAULT_POLICY "allocate"
#define DEFAULT_MIRROR_DEV_FAULT_POLICY "remove"
Modified: lvm2/upstream/current/lib/device/dev-cache.c
==============================================================================
--- lvm2/upstream/current/lib/device/dev-cache.c (original)
+++ lvm2/upstream/current/lib/device/dev-cache.c Mon Oct 23 08:49:10 2006
@@ -645,8 +645,7 @@
return NULL;
}
-
- if (dev_scan) {
+ if (dev_scan && !trust_cache()) {
/* Flag gets reset between each command */
if (!full_scan_done())
persistent_filter_wipe(f); /* Calls _full_scan(1) */
Modified: lvm2/upstream/current/lib/device/dev-io.c
==============================================================================
--- lvm2/upstream/current/lib/device/dev-io.c (original)
+++ lvm2/upstream/current/lib/device/dev-io.c Mon Oct 23 08:49:10 2006
@@ -176,7 +176,7 @@
}
if (!block_size)
- block_size = getpagesize();
+ block_size = lvm_getpagesize();
_widen_region(block_size, where, &widened);
Modified: lvm2/upstream/current/lib/display/display.c
==============================================================================
--- lvm2/upstream/current/lib/display/display.c (original)
+++ lvm2/upstream/current/lib/display/display.c Mon Oct 23 08:49:10 2006
@@ -30,6 +30,7 @@
} _policies[] = {
{
ALLOC_CONTIGUOUS, "contiguous"}, {
+ ALLOC_CLING, "cling"}, {
ALLOC_NORMAL, "normal"}, {
ALLOC_ANYWHERE, "anywhere"}, {
ALLOC_INHERIT, "inherit"}
Modified: lvm2/upstream/current/lib/error/errseg.c
==============================================================================
--- lvm2/upstream/current/lib/error/errseg.c (original)
+++ lvm2/upstream/current/lib/error/errseg.c Mon Oct 23 08:49:10 2006
@@ -23,6 +23,7 @@
#include "targets.h"
#include "lvm-string.h"
#include "activate.h"
+#include "str_list.h"
static const char *_errseg_name(const struct lv_segment *seg)
{
@@ -64,6 +65,18 @@
}
#endif
+static int _errseg_modules_needed(struct dm_pool *mem,
+ const struct lv_segment *seg,
+ struct list *modules)
+{
+ if (!str_list_add(mem, modules, "error")) {
+ log_error("error module string list allocation failed");
+ return 0;
+ }
+
+ return 1;
+}
+
static void _errseg_destroy(const struct segment_type *segtype)
{
dm_free((void *)segtype);
@@ -76,6 +89,7 @@
.add_target_line = _errseg_add_target_line,
.target_present = _errseg_target_present,
#endif
+ .modules_needed = _errseg_modules_needed,
.destroy = _errseg_destroy,
};
Modified: lvm2/upstream/current/lib/filters/filter-md.c
==============================================================================
--- lvm2/upstream/current/lib/filters/filter-md.c (original)
+++ lvm2/upstream/current/lib/filters/filter-md.c Mon Oct 23 08:49:10 2006
@@ -18,14 +18,6 @@
#ifdef linux
-/* Lifted from <linux/raid/md_p.h> because of difficulty including it */
-
-#define MD_SB_MAGIC 0xa92b4efc
-#define MD_RESERVED_BYTES (64 * 1024)
-#define MD_RESERVED_SECTORS (MD_RESERVED_BYTES / 512)
-#define MD_NEW_SIZE_SECTORS(x) ((x & ~(MD_RESERVED_SECTORS - 1)) \
- - MD_RESERVED_SECTORS)
-
static int _ignore_md(struct dev_filter *f, struct device *dev)
{
int ret;
Modified: lvm2/upstream/current/lib/filters/filter-sysfs.c
==============================================================================
--- lvm2/upstream/current/lib/filters/filter-sysfs.c (original)
+++ lvm2/upstream/current/lib/filters/filter-sysfs.c Mon Oct 23 08:49:10 2006
@@ -32,7 +32,7 @@
return 0;
}
- if (lvm_snprintf(proc_mounts, sizeof(proc_mounts),
+ if (dm_snprintf(proc_mounts, sizeof(proc_mounts),
"%s/mounts", proc) < 0) {
log_error("Failed to create /proc/mounts string");
return 0;
@@ -44,9 +44,9 @@
}
while (fgets(buffer, sizeof(buffer), fp)) {
- if (split_words(buffer, 4, split) == 4 &&
+ if (dm_split_words(buffer, 4, 0, split) == 4 &&
!strcmp(split[2], "sysfs")) {
- if (lvm_snprintf(path, len, "%s/%s", split[1],
+ if (dm_snprintf(path, len, "%s/%s", split[1],
"block") >= 0) {
r = 1;
}
@@ -183,7 +183,7 @@
if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
continue;
- if (lvm_snprintf(path, sizeof(path), "%s/%s", dir,
+ if (dm_snprintf(path, sizeof(path), "%s/%s", dir,
d->d_name) < 0) {
log_error("sysfs path name too long: %s in %s",
d->d_name, dir);
Modified: lvm2/upstream/current/lib/filters/filter.c
==============================================================================
--- lvm2/upstream/current/lib/filters/filter.c (original)
+++ lvm2/upstream/current/lib/filters/filter.c Mon Oct 23 08:49:10 2006
@@ -145,7 +145,7 @@
/* All types unrecognised initially */
memset(_max_partitions_by_major, 0, sizeof(int) * NUMBER_OF_MAJORS);
- if (lvm_snprintf(proc_devices, sizeof(proc_devices),
+ if (dm_snprintf(proc_devices, sizeof(proc_devices),
"%s/devices", proc) < 0) {
log_error("Failed to create /proc/devices string");
return 0;
Modified: lvm2/upstream/current/lib/format1/disk-rep.c
==============================================================================
--- lvm2/upstream/current/lib/format1/disk-rep.c (original)
+++ lvm2/upstream/current/lib/format1/disk-rep.c Mon Oct 23 08:49:10 2006
@@ -458,7 +458,7 @@
/*
* Build a list of pv_d's structures, allocated from mem.
- * We keep track of the first object allocated form the pool
+ * We keep track of the first object allocated from the pool
* so we can free off all the memory if something goes wrong.
*/
int read_pvs_in_vg(const struct format_type *fmt, const char *vg_name,
Modified: lvm2/upstream/current/lib/format1/disk-rep.h
==============================================================================
--- lvm2/upstream/current/lib/format1/disk-rep.h (original)
+++ lvm2/upstream/current/lib/format1/disk-rep.h Mon Oct 23 08:49:10 2006
@@ -172,6 +172,7 @@
* Layout constants.
*/
#define METADATA_ALIGN 4096UL
+#define LVM1_PE_ALIGN (65536UL >> SECTOR_SHIFT) /* PE alignment */
#define METADATA_BASE 0UL
#define PV_SIZE 1024UL
Modified: lvm2/upstream/current/lib/format1/format1.c
==============================================================================
--- lvm2/upstream/current/lib/format1/format1.c (original)
+++ lvm2/upstream/current/lib/format1/format1.c Mon Oct 23 08:49:10 2006
@@ -408,7 +408,7 @@
/* Ensure any residual PE structure is gone */
pv->pe_size = pv->pe_count = 0;
- pv->pe_start = PE_ALIGN;
+ pv->pe_start = LVM1_PE_ALIGN;
if (!(mem = dm_pool_create("lvm1 pv_write", 1024))) {
stack;
@@ -431,7 +431,7 @@
dev_write in order to make other disk tools happy */
dl->pvd.pv_on_disk.base = METADATA_BASE;
dl->pvd.pv_on_disk.size = PV_SIZE;
- dl->pvd.pe_on_disk.base = PE_ALIGN << SECTOR_SHIFT;
+ dl->pvd.pe_on_disk.base = LVM1_PE_ALIGN << SECTOR_SHIFT;
list_add(&pvs, &dl->list);
if (!write_disks(fmt, &pvs)) {
Modified: lvm2/upstream/current/lib/format1/import-export.c
==============================================================================
--- lvm2/upstream/current/lib/format1/import-export.c (original)
+++ lvm2/upstream/current/lib/format1/import-export.c Mon Oct 23 08:49:10 2006
@@ -103,7 +103,7 @@
static int _system_id(struct cmd_context *cmd, char *s, const char *prefix)
{
- if (lvm_snprintf(s, NAME_LEN, "%s%s%lu",
+ if (dm_snprintf(s, NAME_LEN, "%s%s%lu",
prefix, cmd->hostname, time(NULL)) < 0) {
log_error("Generated system_id too long");
return 0;
Modified: lvm2/upstream/current/lib/format1/layout.c
==============================================================================
--- lvm2/upstream/current/lib/format1/layout.c (original)
+++ lvm2/upstream/current/lib/format1/layout.c Mon Oct 23 08:49:10 2006
@@ -153,7 +153,7 @@
if (pe_start && end < pe_start)
end = pe_start;
- pvd->pe_start = _round_up(end, PE_ALIGN);
+ pvd->pe_start = _round_up(end, LVM1_PE_ALIGN);
} while ((pvd->pe_start + (pvd->pe_total * extent_size))
> pv->size);
Modified: lvm2/upstream/current/lib/format_text/archive.c
==============================================================================
--- lvm2/upstream/current/lib/format_text/archive.c (original)
+++ lvm2/upstream/current/lib/format_text/archive.c Mon Oct 23 08:49:10 2006
@@ -277,7 +277,7 @@
}
for (i = 0; i < 10; i++) {
- if (lvm_snprintf(archive_name, sizeof(archive_name),
+ if (dm_snprintf(archive_name, sizeof(archive_name),
"%s/%s_%05u.vg", dir, vg->name, ix) < 0) {
log_error("Archive file name too long.");
return 0;
Modified: lvm2/upstream/current/lib/format_text/archiver.c
==============================================================================
--- lvm2/upstream/current/lib/format_text/archiver.c (original)
+++ lvm2/upstream/current/lib/format_text/archiver.c Mon Oct 23 08:49:10 2006
@@ -190,7 +190,7 @@
return 0;
}
- if (lvm_snprintf(name, sizeof(name), "%s/%s",
+ if (dm_snprintf(name, sizeof(name), "%s/%s",
vg->cmd->backup_params->dir, vg->name) < 0) {
log_error("Failed to generate volume group metadata backup "
"filename.");
@@ -233,7 +233,7 @@
{
char path[PATH_MAX];
- if (lvm_snprintf(path, sizeof(path), "%s/%s",
+ if (dm_snprintf(path, sizeof(path), "%s/%s",
cmd->backup_params->dir, vg_name) < 0) {
log_err("Failed to generate backup filename (for removal).");
return 0;
@@ -342,7 +342,7 @@
{
char path[PATH_MAX];
- if (lvm_snprintf(path, sizeof(path), "%s/%s",
+ if (dm_snprintf(path, sizeof(path), "%s/%s",
cmd->backup_params->dir, vg_name) < 0) {
log_err("Failed to generate backup filename (for restore).");
return 0;
@@ -397,7 +397,7 @@
if ((vg->status & PARTIAL_VG) || (vg->status & EXPORTED_VG))
return;
- if (lvm_snprintf(path, sizeof(path), "%s/%s",
+ if (dm_snprintf(path, sizeof(path), "%s/%s",
vg->cmd->backup_params->dir, vg->name) < 0) {
log_debug("Failed to generate backup filename.");
return;
Modified: lvm2/upstream/current/lib/format_text/export.c
==============================================================================
--- lvm2/upstream/current/lib/format_text/export.c (original)
+++ lvm2/upstream/current/lib/format_text/export.c Mon Oct 23 08:49:10 2006
@@ -233,7 +233,7 @@
for (i = 0; (d > 1024.0) && _units[i]; i++)
d /= 1024.0;
- return lvm_snprintf(buffer, s, "# %g %s", d, _units[i]) > 0;
+ return dm_snprintf(buffer, s, "# %g %s", d, _units[i]) > 0;
}
/*
@@ -409,6 +409,11 @@
outf(f, "tags = %s", buffer);
}
+ if (!out_size(f, pv->size, "dev_size = %" PRIu64, pv->size)) {
+ stack;
+ return 0;
+ }
+
outf(f, "pe_start = %" PRIu64, pv->pe_start);
if (!out_size(f, vg->extent_size * (uint64_t) pv->pe_count,
"pe_count = %u", pv->pe_count)) {
@@ -623,7 +628,7 @@
pv = pvl->pv;
/* FIXME But skip if there's already an LV called pv%d ! */
- if (lvm_snprintf(buffer, sizeof(buffer), "pv%d", count++) < 0)
+ if (dm_snprintf(buffer, sizeof(buffer), "pv%d", count++) < 0)
return_0;
if (!(name = dm_pool_strdup(f->mem, buffer)))
Modified: lvm2/upstream/current/lib/format_text/format-text.c
==============================================================================
--- lvm2/upstream/current/lib/format_text/format-text.c (original)
+++ lvm2/upstream/current/lib/format_text/format-text.c Mon Oct 23 08:49:10 2006
@@ -853,7 +853,7 @@
tmp != dirent->d_name + strlen(dirent->d_name)
- 4)) {
vgname = dirent->d_name;
- if (lvm_snprintf(path, PATH_MAX, "%s/%s",
+ if (dm_snprintf(path, PATH_MAX, "%s/%s",
dl->dir, vgname) < 0) {
log_error("Name too long %s/%s",
dl->dir, vgname);
@@ -994,7 +994,7 @@
}
/* For orphan, creates new mdas according to policy.
- Always have an mda between end-of-label and PE_ALIGN boundary */
+ Always have an mda between end-of-label and pe_align() boundary */
static int _mda_setup(const struct format_type *fmt,
uint64_t pe_start, uint64_t pe_end,
int pvmetadatacopies,
@@ -1005,15 +1005,12 @@
uint64_t start1, mda_size1; /* First area - start of disk */
uint64_t start2, mda_size2; /* Second area - end of disk */
uint64_t wipe_size = 8 << SECTOR_SHIFT;
- size_t pagesize = getpagesize();
+ size_t pagesize = lvm_getpagesize();
- if (!pvmetadatacopies) {
- /* Space available for PEs */
- pv->size -= PE_ALIGN;
+ if (!pvmetadatacopies)
return 1;
- }
- alignment = PE_ALIGN << SECTOR_SHIFT;
+ alignment = pe_align() << SECTOR_SHIFT;
disk_size = pv->size << SECTOR_SHIFT;
pe_start <<= SECTOR_SHIFT;
pe_end <<= SECTOR_SHIFT;
@@ -1027,9 +1024,6 @@
/* Requested metadatasize */
mda_size1 = pvmetadatasize << SECTOR_SHIFT;
- /* Space available for PEs (before any mdas created) */
- pv->size -= LABEL_SCAN_SECTORS;
-
/* Place mda straight after label area at start of disk */
start1 = LABEL_SCAN_SIZE;
@@ -1037,11 +1031,8 @@
if ((!pe_start && !pe_end) ||
((pe_start > start1) && (pe_start - start1 >= MDA_SIZE_MIN))) {
mda_adjustment = start1 % pagesize;
- if (mda_adjustment) {
+ if (mda_adjustment)
start1 += (pagesize - mda_adjustment);
- pv->size -= ((pagesize - mda_adjustment) >>
- SECTOR_SHIFT);
- }
}
/* Ensure it's not going to be bigger than the disk! */
@@ -1055,7 +1046,7 @@
pvmetadatacopies = 1;
}
- /* Round up to PE_ALIGN boundary */
+ /* Round up to pe_align() boundary */
mda_adjustment = (mda_size1 + start1) % alignment;
if (mda_adjustment)
mda_size1 += (alignment - mda_adjustment);
@@ -1071,7 +1062,8 @@
/* FIXME If creating new mdas, wipe them! */
if (mda_size1) {
if (!add_mda(fmt, fmt->cmd->mem, mdas, pv->dev, start1,
- mda_size1)) return 0;
+ mda_size1))
+ return 0;
if (!dev_set((struct device *) pv->dev, start1,
(size_t) (mda_size1 >
@@ -1080,7 +1072,6 @@
return 0;
}
- pv->size -= mda_size1 >> SECTOR_SHIFT;
if (pvmetadatacopies == 1)
return 1;
} else
@@ -1125,7 +1116,6 @@
log_error("Failed to wipe new metadata area");
return 0;
}
- pv->size -= mda_size2 >> SECTOR_SHIFT;
} else
return 0;
@@ -1189,18 +1179,18 @@
/* Set pe_start to first aligned sector after any metadata
* areas that begin before pe_start */
- pv->pe_start = PE_ALIGN;
+ pv->pe_start = pe_align();
list_iterate_items(mda, &info->mdas) {
mdac = (struct mda_context *) mda->metadata_locn;
if (pv->dev == mdac->area.dev &&
- (mdac->area.start < (pv->pe_start << SECTOR_SHIFT)) &&
+ (mdac->area.start <= (pv->pe_start << SECTOR_SHIFT)) &&
(mdac->area.start + mdac->area.size >
(pv->pe_start << SECTOR_SHIFT))) {
pv->pe_start = (mdac->area.start + mdac->area.size)
>> SECTOR_SHIFT;
- adjustment = pv->pe_start % PE_ALIGN;
+ adjustment = pv->pe_start % pe_align();
if (adjustment)
- pv->pe_start += (PE_ALIGN - adjustment);
+ pv->pe_start += (pe_align() - adjustment);
}
}
if (!add_da
@@ -1416,8 +1406,8 @@
struct lvmcache_info *info;
int found;
uint64_t pe_end = 0;
-
- /* FIXME if vg, adjust start/end of pe area to avoid mdas! */
+ unsigned mda_count = 0;
+ uint64_t mda_size2 = 0;
/* FIXME Cope with pvchange */
/* FIXME Merge code with _text_create_text_instance */
@@ -1428,11 +1418,16 @@
if ((info = info_from_pvid(pv->dev->pvid))) {
pvmdas = &info->mdas;
list_iterate_items(mda, pvmdas) {
+ mda_count++;
mdac =
(struct mda_context *) mda->metadata_locn;
/* FIXME Check it isn't already in use */
+ /* Reduce usable device size */
+ if (mda_count > 1)
+ mda_size2 = mdac->area.size >> SECTOR_SHIFT;
+
/* Ensure it isn't already on list */
found = 0;
list_iterate_items(mda2, mdas) {
@@ -1470,6 +1465,17 @@
}
}
+ /* FIXME Cope with genuine pe_count 0 */
+
+ /* If missing, estimate pv->size from file-based metadata */
+ if (!pv->size && pv->pe_count)
+ pv->size = pv->pe_count * (uint64_t) vg->extent_size +
+ pv->pe_start + mda_size2;
+
+ /* Recalculate number of extents that will fit */
+ if (!pv->pe_count)
+ pv->pe_count = (pv->size - pv->pe_start - mda_size2) / vg->extent_size;
+
/* Unlike LVM1, we don't store this outside a VG */
/* FIXME Default from config file? vgextend cmdline flag? */
pv->status |= ALLOCATABLE_PV;
@@ -1533,7 +1539,7 @@
dir_list = &((struct mda_lists *) fmt->private)->dirs;
list_iterate_items(dl, dir_list) {
- if (lvm_snprintf(path, PATH_MAX, "%s/%s",
+ if (dm_snprintf(path, PATH_MAX, "%s/%s",
dl->dir, vgname) < 0) {
log_error("Name too long %s/%s", dl->dir,
vgname);
Modified: lvm2/upstream/current/lib/format_text/import_vsn1.c
==============================================================================
--- lvm2/upstream/current/lib/format_text/import_vsn1.c (original)
+++ lvm2/upstream/current/lib/format_text/import_vsn1.c Mon Oct 23 08:49:10 2006
@@ -179,6 +179,9 @@
return 0;
}
+ /* Late addition */
+ _read_int64(pvn, "dev_size", &pv->size);
+
if (!_read_int64(pvn, "pe_start", &pv->pe_start)) {
log_error("Couldn't read extent size for volume group.");
return 0;
@@ -206,7 +209,7 @@
vg->free_count += pv->pe_count;
pv->pe_size = vg->extent_size;
- pv->size = vg->extent_size * (uint64_t) pv->pe_count;
+
pv->pe_alloc_count = 0;
pv->fmt = fid->fmt;
Modified: lvm2/upstream/current/lib/format_text/layout.h
==============================================================================
--- lvm2/upstream/current/lib/format_text/layout.h (original)
+++ lvm2/upstream/current/lib/format_text/layout.h Mon Oct 23 08:49:10 2006
@@ -83,6 +83,6 @@
#define FMTT_VERSION 1
#define MDA_HEADER_SIZE 512
#define LVM2_LABEL "LVM2 001"
-#define MDA_SIZE_MIN (8 * (unsigned) getpagesize())
+#define MDA_SIZE_MIN (8 * (unsigned) lvm_getpagesize())
#endif
Modified: lvm2/upstream/current/lib/locking/cluster_locking.c
==============================================================================
--- lvm2/upstream/current/lib/locking/cluster_locking.c (original)
+++ lvm2/upstream/current/lib/locking/cluster_locking.c Mon Oct 23 08:49:10 2006
@@ -398,9 +398,9 @@
case LCK_VG:
/* If the VG name is empty then lock the unused PVs */
if (!*resource)
- lvm_snprintf(lockname, sizeof(lockname), "P_orphans");
+ dm_snprintf(lockname, sizeof(lockname), "P_orphans");
else
- lvm_snprintf(lockname, sizeof(lockname), "V_%s",
+ dm_snprintf(lockname, sizeof(lockname), "V_%s",
resource);
cluster_cmd = CLVMD_CMD_LOCK_VG;
Modified: lvm2/upstream/current/lib/locking/file_locking.c
==============================================================================
--- lvm2/upstream/current/lib/locking/file_locking.c (original)
+++ lvm2/upstream/current/lib/locking/file_locking.c Mon Oct 23 08:49:10 2006
@@ -212,10 +212,10 @@
switch (flags & LCK_SCOPE_MASK) {
case LCK_VG:
if (!*resource)
- lvm_snprintf(lockfile, sizeof(lockfile),
+ dm_snprintf(lockfile, sizeof(lockfile),
"%s/P_orphans", _lock_dir);
else
- lvm_snprintf(lockfile, sizeof(lockfile),
+ dm_snprintf(lockfile, sizeof(lockfile),
"%s/V_%s", _lock_dir, resource);
if (!_lock_file(lockfile, flags))
Modified: lvm2/upstream/current/lib/locking/locking.c
==============================================================================
--- lvm2/upstream/current/lib/locking/locking.c (original)
+++ lvm2/upstream/current/lib/locking/locking.c Mon Oct 23 08:49:10 2006
@@ -20,6 +20,7 @@
#include "activate.h"
#include "toolcontext.h"
#include "memlock.h"
+#include "defaults.h"
#include <signal.h>
#include <sys/stat.h>
@@ -134,24 +135,31 @@
return 1;
case 1:
+ log_very_verbose("File-based locking selected.");
if (!init_file_locking(&_locking, cmd))
break;
- log_very_verbose("File-based locking enabled.");
return 1;
#ifdef HAVE_LIBDL
case 2:
- if (!init_external_locking(&_locking, cmd))
+ if (!cmd->is_static) {
+ log_very_verbose("External locking selected.");
+ if (init_external_locking(&_locking, cmd))
+ return 1;
+ }
+ if (!find_config_tree_int(cmd, "locking/fallback_to_clustered_locking",
+ DEFAULT_FALLBACK_TO_CLUSTERED_LOCKING))
break;
- log_very_verbose("External locking enabled.");
- return 1;
#endif
#ifdef CLUSTER_LOCKING_INTERNAL
+ log_very_verbose("Falling back to internal clustered locking.");
+ /* Fall through */
+
case 3:
+ log_very_verbose("Cluster locking selected.");
if (!init_cluster_locking(&_locking, cmd))
break;
- log_very_verbose("Cluster locking enabled.");
return 1;
#endif
@@ -160,6 +168,16 @@
return 0;
}
+ if ((type == 2 || type == 3) &&
+ find_config_tree_int(cmd, "locking/fallback_to_local_locking",
+ DEFAULT_FALLBACK_TO_LOCAL_LOCKING)) {
+ log_print("WARNING: Falling back to local file-based locking.");
+ log_print("Volume Groups with the clustered attribute will "
+ "be inaccessible.");
+ if (init_file_locking(&_locking, cmd))
+ return 1;
+ }
+
if (!ignorelockingfailure())
return 0;
@@ -189,7 +207,7 @@
if (!*vgname)
return 1;
- if (lvm_snprintf(path, sizeof(path), "%s/lvm/VGs/%s", cmd->proc_dir,
+ if (dm_snprintf(path, sizeof(path), "%s/lvm/VGs/%s", cmd->proc_dir,
vgname) < 0) {
log_error("LVM1 proc VG pathname too long for %s", vgname);
return 0;
Modified: lvm2/upstream/current/lib/log/log.c
==============================================================================
--- lvm2/upstream/current/lib/log/log.c (original)
+++ lvm2/upstream/current/lib/log/log.c Mon Oct 23 08:49:10 2006
@@ -32,6 +32,7 @@
static int _md_filtering = 0;
static int _pvmove = 0;
static int _full_scan_done = 0; /* Restrict to one full scan during each cmd */
+static int _trust_cache = 0; /* Don't scan when incomplete VGs encountered */
static int _debug_level = 0;
static int _syslog = 0;
static int _log_to_file = 0;
@@ -163,6 +164,11 @@
_full_scan_done = level;
}
+void init_trust_cache(int trustcache)
+{
+ _trust_cache = trustcache;
+}
+
void init_ignorelockingfailure(int level)
{
_ignorelockingfailure = level;
@@ -237,6 +243,11 @@
return _full_scan_done;
}
+int trust_cache()
+{
+ return _trust_cache;
+}
+
int lockingfailed()
{
return _lockingfailed;
@@ -307,7 +318,7 @@
log_it:
if (!_log_suppress) {
if (_verbose_level > _LOG_DEBUG)
- lvm_snprintf(locn, sizeof(locn), "#%s:%d ",
+ dm_snprintf(locn, sizeof(locn), "#%s:%d ",
file, line);
else
locn[0] = '\0';
@@ -402,7 +413,7 @@
_already_logging = 1;
memset(&buf, ' ', sizeof(buf));
bufused = 0;
- if ((n = lvm_snprintf(buf, sizeof(buf) - bufused - 1,
+ if ((n = dm_snprintf(buf, sizeof(buf) - bufused - 1,
"%s:%d %s%s", file, line, _cmd_name,
_msg_prefix)) == -1)
goto done;
Modified: lvm2/upstream/current/lib/log/log.h
==============================================================================
--- lvm2/upstream/current/lib/log/log.h (original)
+++ lvm2/upstream/current/lib/log/log.h Mon Oct 23 08:49:10 2006
@@ -66,6 +66,7 @@
void init_md_filtering(int level);
void init_pvmove(int level);
void init_full_scan_done(int level);
+void init_trust_cache(int trustcache);
void init_debug(int level);
void init_cmd_name(int status);
void init_msg_prefix(const char *prefix);
@@ -83,6 +84,7 @@
int md_filtering(void);
int pvmove_mode(void);
int full_scan_done(void);
+int trust_cache(void);
int debug_level(void);
int ignorelockingfailure(void);
int lockingfailed(void);
Modified: lvm2/upstream/current/lib/metadata/lv_manip.c
==============================================================================
--- lvm2/upstream/current/lib/metadata/lv_manip.c (original)
+++ lvm2/upstream/current/lib/metadata/lv_manip.c Mon Oct 23 08:49:10 2006
@@ -158,7 +158,7 @@
}
if (seg_lv(seg, s)->status & MIRROR_IMAGE) {
- lv_reduce(seg_lv(seg, s), area_reduction);
+ lv_reduce(seg_lv(seg, s), area_reduction);
return;
}
@@ -398,6 +398,7 @@
* Details of an allocation attempt
*/
struct alloc_handle {
+ struct cmd_context *cmd;
struct dm_pool *mem;
alloc_policy_t alloc; /* Overall policy */
@@ -417,7 +418,8 @@
/*
* Preparation for a specific allocation attempt
*/
-static struct alloc_handle *_alloc_init(struct dm_pool *mem,
+static struct alloc_handle *_alloc_init(struct cmd_context *cmd,
+ struct dm_pool *mem,
const struct segment_type *segtype,
alloc_policy_t alloc,
uint32_t mirrors,
@@ -464,6 +466,8 @@
if (segtype_is_virtual(segtype))
return ah;
+ ah->cmd = cmd;
+
if (!(ah->mem = dm_pool_create("allocation", 1024))) {
log_error("allocation pool creation failed");
return NULL;
@@ -490,6 +494,49 @@
dm_pool_destroy(ah->mem);
}
+static int _log_parallel_areas(struct dm_pool *mem, struct list *parallel_areas)
+{
+ struct seg_pvs *spvs;
+ struct pv_list *pvl;
+ char *pvnames;
+
+ if (!parallel_areas)
+ return 1;
+
+ if (!dm_pool_begin_object(mem, 256)) {
+ log_error("dm_pool_begin_object failed");
+ return 0;
+ }
+
+ list_iterate_items(spvs, parallel_areas) {
+ list_iterate_items(pvl, &spvs->pvs) {
+ if (!dm_pool_grow_object(mem, dev_name(pvl->pv->dev), strlen(dev_name(pvl->pv->dev)))) {
+ log_error("dm_pool_grow_object failed");
+ dm_pool_abandon_object(mem);
+ return 0;
+ }
+ if (!dm_pool_grow_object(mem, " ", 1)) {
+ log_error("dm_pool_grow_object failed");
+ dm_pool_abandon_object(mem);
+ return 0;
+ }
+ }
+
+ if (!dm_pool_grow_object(mem, "\0", 1)) {
+ log_error("dm_pool_grow_object failed");
+ dm_pool_abandon_object(mem);
+ return 0;
+ }
+
+ pvnames = dm_pool_end_object(mem);
+ log_debug("Parallel PVs at LE %" PRIu32 " length %" PRIu32 ": %s",
+ spvs->le, spvs->len, pvnames);
+ dm_pool_free(mem, pvnames);
+ }
+
+ return 1;
+}
+
static int _setup_alloced_segment(struct logical_volume *lv, uint32_t status,
uint32_t area_count,
uint32_t stripe_size,
@@ -614,7 +661,7 @@
if (log_area) {
ah->log_area.pv = log_area->map->pv;
ah->log_area.pe = log_area->start;
- ah->log_area.len = 1; /* FIXME Calculate & check this */
+ ah->log_area.len = MIRROR_LOG_SIZE; /* FIXME Calculate & check this */
consume_pv_area(log_area, ah->log_area.len);
}
@@ -623,6 +670,82 @@
return 1;
}
+/*
+ * Call fn for each AREA_PV used by the LV segment at lv:le of length *max_seg_len.
+ * If any constituent area contains more than one segment, max_seg_len is
+ * reduced to cover only the first.
+ * fn should return 0 on error, 1 to continue scanning or >1 to terminate without error.
+ * In the last case, this function passes on the return code.
+ */
+static int _for_each_pv(struct cmd_context *cmd, struct logical_volume *lv,
+ uint32_t le, uint32_t len, uint32_t *max_seg_len,
+ uint32_t first_area, uint32_t max_areas,
+ int top_level_area_index,
+ int only_single_area_segments,
+ int (*fn)(struct cmd_context *cmd,
+ struct pv_segment *peg, uint32_t s,
+ void *data),
+ void *data)
+{
+ struct lv_segment *seg;
+ uint32_t s;
+ uint32_t remaining_seg_len, area_len, area_multiple;
+ int r = 1;
+
+ if (!(seg = find_seg_by_le(lv, le))) {
+ log_error("Failed to find segment for %s extent %" PRIu32,
+ lv->name, le);
+ return 0;
+ }
+
+ /* Remaining logical length of segment */
+ remaining_seg_len = seg->len - (le - seg->le);
+
+ if (remaining_seg_len > len)
+ remaining_seg_len = len;
+
+ if (max_seg_len && *max_seg_len > remaining_seg_len)
+ *max_seg_len = remaining_seg_len;
+
+ area_multiple = segtype_is_striped(seg->segtype) ? seg->area_count : 1;
+ area_len = remaining_seg_len / area_multiple ? : 1;
+
+ for (s = first_area;
+ s < seg->area_count && (!max_areas || s <= max_areas);
+ s++) {
+ if (seg_type(seg, s) == AREA_LV) {
+ if (!(r = _for_each_pv(cmd, seg_lv(seg, s),
+ seg_le(seg, s) +
+ (le - seg->le) / area_multiple,
+ area_len, max_seg_len,
+ only_single_area_segments ? 0 : 0,
+ only_single_area_segments ? 1 : 0,
+ top_level_area_index != -1 ? top_level_area_index : s,
+ only_single_area_segments, fn,
+ data)))
+ stack;
+ } else if (seg_type(seg, s) == AREA_PV)
+ if (!(r = fn(cmd, seg_pvseg(seg, s), top_level_area_index != -1 ? top_level_area_index : s, data)))
+ stack;
+ if (r != 1)
+ return r;
+ }
+
+ /* FIXME only_single_area_segments used as workaround to skip log LV - needs new param? */
+ if (!only_single_area_segments && seg_is_mirrored(seg) && seg->log_lv) {
+ if (!(r = _for_each_pv(cmd, seg->log_lv, 0, MIRROR_LOG_SIZE,
+ NULL, 0, 0, 0, only_single_area_segments,
+ fn, data)))
+ stack;
+ if (r != 1)
+ return r;
+ }
+
+ /* FIXME Add snapshot cow LVs etc. */
+
+ return 1;
+}
+
static int _comp_area(const void *l, const void *r)
{
const struct pv_area *lhs = *((const struct pv_area **) l);
@@ -638,32 +761,113 @@
}
/*
- * Is pva contiguous to any existing areas or on the same PV?
+ * Search for pvseg that matches condition
+ */
+struct pv_match {
+ int (*condition)(struct pv_segment *pvseg, struct pv_area *pva);
+
+ struct pv_area **areas;
+ struct pv_area *pva;
+ uint32_t areas_size;
+ int s; /* Area index of match */
+};
+
+/*
+ * Is PV area on the same PV?
*/
-static int _check_contiguous(struct lv_segment *prev_lvseg,
- struct physical_volume *pv, struct pv_area *pva,
- struct pv_area **areas)
+static int _is_same_pv(struct pv_segment *pvseg, struct pv_area *pva)
{
- struct pv_segment *prev_pvseg;
- uint32_t s;
+ if (pvseg->pv != pva->map->pv)
+ return 0;
- for (s = 0; s < prev_lvseg->area_count; s++) {
- if (seg_type(prev_lvseg, s) != AREA_PV)
- continue; /* FIXME Broken */
+ return 1;
+}
- if (!(prev_pvseg = seg_pvseg(prev_lvseg, s)))
- continue; /* FIXME Broken */
+/*
+ * Is PV area contiguous to PV segment?
+ */
+static int _is_contiguous(struct pv_segment *pvseg, struct pv_area *pva)
+{
+ if (pvseg->pv != pva->map->pv)
+ return 0;
- if ((prev_pvseg->pv != pv))
- continue;
+ if (pvseg->pe + pvseg->len != pva->start)
+ return 0;
- if (prev_pvseg->pe + prev_pvseg->len == pva->start) {
- areas[s] = pva;
- return 1;
- }
- }
+ return 1;
+}
- return 0;
+static int _is_condition(struct cmd_context *cmd,
+ struct pv_segment *pvseg, uint32_t s,
+ void *data)
+{
+ struct pv_match *pvmatch = data;
+
+ if (!pvmatch->condition(pvseg, pvmatch->pva))
+ return 1; /* Continue */
+
+ if (s >= pvmatch->areas_size)
+ return 1;
+
+ pvmatch->areas[s] = pvmatch->pva;
+
+ return 2; /* Finished */
+}
+
+/*
+ * Is pva on same PV as any existing areas?
+ */
+static int _check_cling(struct cmd_context *cmd,
+ struct lv_segment *prev_lvseg, struct pv_area *pva,
+ struct pv_area **areas, uint32_t areas_size)
+{
+ struct pv_match pvmatch;
+ int r;
+
+ pvmatch.condition = _is_same_pv;
+ pvmatch.areas = areas;
+ pvmatch.areas_size = areas_size;
+ pvmatch.pva = pva;
+
+ /* FIXME Cope with stacks by flattening */
+ if (!(r = _for_each_pv(cmd, prev_lvseg->lv,
+ prev_lvseg->le + prev_lvseg->len - 1, 1, NULL,
+ 0, 0, -1, 1,
+ _is_condition, &pvmatch)))
+ stack;
+
+ if (r != 2)
+ return 0;
+
+ return 1;
+}
+
+/*
+ * Is pva contiguous to any existing areas or on the same PV?
+ */
+static int _check_contiguous(struct cmd_context *cmd,
+ struct lv_segment *prev_lvseg, struct pv_area *pva,
+ struct pv_area **areas, uint32_t areas_size)
+{
+ struct pv_match pvmatch;
+ int r;
+
+ pvmatch.condition = _is_contiguous;
+ pvmatch.areas = areas;
+ pvmatch.areas_size = areas_size;
+ pvmatch.pva = pva;
+
+ /* FIXME Cope with stacks by flattening */
+ if (!(r = _for_each_pv(cmd, prev_lvseg->lv,
+ prev_lvseg->le + prev_lvseg->len - 1, 1, NULL,
+ 0, 0, -1, 1,
+ _is_condition, &pvmatch)))
+ stack;
+
+ if (r != 2)
+ return 0;
+
+ return 1;
}
/*
@@ -679,9 +883,9 @@
struct pv_area *pva;
struct pv_list *pvl;
unsigned already_found_one = 0;
- unsigned contiguous = 0, contiguous_count = 0;
+ unsigned contiguous = 0, cling = 0, preferred_count = 0;
unsigned ix;
- unsigned ix_offset = 0; /* Offset for non-contiguous allocations */
+ unsigned ix_offset = 0; /* Offset for non-preferred allocations */
uint32_t max_parallel; /* Maximum extents to allocate */
uint32_t next_le;
struct seg_pvs *spvs;
@@ -691,9 +895,14 @@
/* FIXME Select log PV appropriately if there isn't one yet */
/* Are there any preceding segments we must follow on from? */
- if ((alloc == ALLOC_CONTIGUOUS) && prev_lvseg) {
- contiguous = 1;
+ if (prev_lvseg) {
ix_offset = prev_lvseg->area_count;
+ if ((alloc == ALLOC_CONTIGUOUS))
+ contiguous = 1;
+ else if ((alloc == ALLOC_CLING))
+ cling = 1;
+ else
+ ix_offset = 0;
}
/* FIXME This algorithm needs a lot of cleaning up! */
@@ -702,6 +911,7 @@
/* ix holds the number of areas found on other PVs */
do {
ix = 0;
+ preferred_count = 0;
parallel_pvs = NULL;
max_parallel = needed;
@@ -711,14 +921,15 @@
* the maximum we can allocate in one go accordingly.
*/
if (ah->parallel_areas) {
+ next_le = (prev_lvseg ? prev_lvseg->le + prev_lvseg->len : 0) + *allocated / ah->area_multiple;
list_iterate_items(spvs, ah->parallel_areas) {
- next_le = (prev_lvseg ? prev_lvseg->le + prev_lvseg->len : 0) + *allocated;
- if (next_le >= spvs->le) {
- if (next_le + max_parallel > spvs->le + spvs->len)
- max_parallel = (spvs->le + spvs->len - next_le) * ah->area_multiple;
- parallel_pvs = &spvs->pvs;
- break;
- }
+ if (next_le >= spvs->le + spvs->len)
+ continue;
+
+ if (max_parallel > (spvs->le + spvs->len) * ah->area_multiple)
+ max_parallel = (spvs->le + spvs->len) * ah->area_multiple;
+ parallel_pvs = &spvs->pvs;
+ break;
}
}
@@ -750,17 +961,30 @@
list_iterate_items(pva, &pvm->areas) {
if (contiguous) {
if (prev_lvseg &&
- _check_contiguous(prev_lvseg,
- pvm->pv,
- pva, areas)) {
- contiguous_count++;
+ _check_contiguous(ah->cmd,
+ prev_lvseg,
+ pva, areas,
+ areas_size)) {
+ preferred_count++;
goto next_pv;
}
continue;
}
+ if (cling) {
+ if (prev_lvseg &&
+ _check_cling(ah->cmd,
+ prev_lvseg,
+ pva, areas,
+ areas_size)) {
+ preferred_count++;
+ }
+ goto next_pv;
+ }
+
/* Is it big enough on its own? */
- if ((pva->count < max_parallel - *allocated) &&
+ if (pva->count * ah->area_multiple <
+ max_parallel - *allocated &&
((!can_split && !ah->log_count) ||
(already_found_one &&
!(alloc == ALLOC_ANYWHERE))))
@@ -781,7 +1005,7 @@
break;
}
- if (contiguous && (contiguous_count < ix_offset))
+ if ((contiguous || cling) && (preferred_count < ix_offset))
break;
/* Only allocate log_area the first time around */
@@ -853,6 +1077,9 @@
return 0;
}
+ if (!_log_parallel_areas(ah->mem, ah->parallel_areas))
+ stack;
+
areas_size = list_size(pvms);
if (areas_size < ah->area_count + ah->log_count) {
if (ah->alloc != ALLOC_ANYWHERE) {
@@ -888,6 +1115,18 @@
goto finished;
old_allocated = allocated;
+ if (!_find_parallel_space(ah, ALLOC_CLING, pvms, areas,
+ areas_size, can_split,
+ prev_lvseg, &allocated, new_extents)) {
+ stack;
+ goto out;
+ }
+
+ if ((allocated == new_extents) || (ah->alloc == ALLOC_CLING) ||
+ (!can_split && (allocated != old_allocated)))
+ goto finished;
+
+ old_allocated = allocated;
if (!_find_parallel_space(ah, ALLOC_NORMAL, pvms, areas,
areas_size, can_split,
prev_lvseg, &allocated, new_extents)) {
@@ -982,7 +1221,7 @@
if (alloc == ALLOC_INHERIT)
alloc = vg->alloc;
- if (!(ah = _alloc_init(vg->cmd->mem, segtype, alloc, mirrors,
+ if (!(ah = _alloc_init(vg->cmd, vg->cmd->mem, segtype, alloc, mirrors,
stripes, log_count, mirrored_pv,
mirrored_pe, parallel_areas))) {
stack;
@@ -1213,7 +1452,7 @@
log_error("Aborting. Failed to extend %s.",
seg_lv(seg, m)->name);
return 0;
- }
+ }
}
seg->area_len += extents;
seg->len += extents;
@@ -1240,7 +1479,7 @@
high = i;
}
- if (lvm_snprintf(buffer, len, format, high + 1) < 0)
+ if (dm_snprintf(buffer, len, format, high + 1) < 0)
return NULL;
return buffer;
@@ -1326,58 +1565,16 @@
return lv;
}
-/* Recursively process each PV used by part of an LV */
-static int _for_each_pv(struct cmd_context *cmd, struct logical_volume *lv,
- uint32_t le, uint32_t len,
- int (*fn)(struct cmd_context *cmd, struct pv_segment *peg, struct seg_pvs *spvs),
- struct seg_pvs *spvs)
-{
- struct lv_segment *seg;
- uint32_t s;
- uint32_t remaining_seg_len, area_len, area_multiple;
-
- if (!(seg = find_seg_by_le(lv, le))) {
- log_error("Failed to find segment for %s extent %" PRIu32,
- lv->name, le);
- return 0;
- }
-
- /* Remaining logical length of segment */
- remaining_seg_len = seg->len - (le - seg->le);
-
- if (len > remaining_seg_len)
- remaining_seg_len = len;
-
- if (spvs->len > remaining_seg_len)
- spvs->len = remaining_seg_len;
-
- area_multiple = segtype_is_striped(seg->segtype) ? seg->area_count : 1;
- area_len = remaining_seg_len / area_multiple;
-
- for (s = 0; s < seg->area_count; s++) {
- if (seg_type(seg, s) == AREA_LV) {
- if (!_for_each_pv(cmd, seg_lv(seg, s),
- seg_le(seg, s) + (le - seg->le) / area_multiple,
- area_len, fn, spvs)) {
- stack;
- return 0;
- }
- } else if (seg_type(seg, s) == AREA_PV) {
- if (!fn(cmd, seg_pvseg(seg, s), spvs)) {
- stack;
- return 0;
- }
- }
- }
-
- return 1;
-}
-
-static int _add_pvs(struct cmd_context *cmd, struct pv_segment *peg, struct seg_pvs *spvs)
+static int _add_pvs(struct cmd_context *cmd, struct pv_segment *peg,
+ uint32_t s __attribute((unused)), void *data)
{
+ struct seg_pvs *spvs = (struct seg_pvs *) data;
struct pv_list *pvl;
- /* FIXME Don't add again if it's already on the list! */
+ /* Don't add again if it's already on list. */
+ list_iterate_items(pvl, &spvs->pvs)
+ if (pvl->pv == peg->pv)
+ return 1;
if (!(pvl = dm_pool_alloc(cmd->mem, sizeof(*pvl)))) {
log_error("pv_list allocation failed");
@@ -1386,11 +1583,8 @@
pvl->pv = peg->pv;
- /* FIXME Use ordered list to facilitate comparison */
list_add(&spvs->pvs, &pvl->list);
- /* FIXME Add mirror logs, snapshot cow LVs etc. */
-
return 1;
}
@@ -1426,7 +1620,8 @@
/* Find next segment end */
/* FIXME Unnecessary nesting! */
- if (!_for_each_pv(cmd, lv, current_le, lv->le_count, _add_pvs, spvs)) {
+ if (!_for_each_pv(cmd, lv, current_le, spvs->len, &spvs->len,
+ 0, 0, -1, 0, _add_pvs, (void *) spvs)) {
stack;
return NULL;
}
Modified: lvm2/upstream/current/lib/metadata/metadata.c
==============================================================================
--- lvm2/upstream/current/lib/metadata/metadata.c (original)
+++ lvm2/upstream/current/lib/metadata/metadata.c Mon Oct 23 08:49:10 2006
@@ -24,6 +24,13 @@
#include "pv_alloc.h"
#include "activate.h"
+#include <sys/param.h>
+
+unsigned long pe_align(void)
+{
+ return MAX(65536UL, lvm_getpagesize()) >> SECTOR_SHIFT;
+}
+
static int _add_pv_to_vg(struct format_instance *fid, struct volume_group *vg,
const char *pv_name)
{
@@ -78,15 +85,12 @@
/* FIXME Do proper rounding-up alignment? */
/* Reserved space for label; this holds 0 for PVs created by LVM1 */
- if (pv->pe_start < PE_ALIGN)
- pv->pe_start = PE_ALIGN;
+ if (pv->pe_start < pe_align())
+ pv->pe_start = pe_align();
/*
- * The next two fields should be corrected
- * by fid->pv_setup.
+ * pe_count must always be calculated by pv_setup
*/
- pv->pe_count = (pv->size - pv->pe_start) / vg->extent_size;
-
pv->pe_alloc_count = 0;
if (!fid->fmt->ops->pv_setup(fid->fmt, UINT64_C(0), 0,
@@ -722,23 +726,70 @@
int vg_validate(struct volume_group *vg)
{
- struct lv_list *lvl;
+ struct pv_list *pvl, *pvl2;
+ struct lv_list *lvl, *lvl2;
+ char uuid[64];
+ int r = 1;
+
+ /* FIXME Also check there's no data/metadata overlap */
+
+ list_iterate_items(pvl, &vg->pvs) {
+ list_iterate_items(pvl2, &vg->pvs) {
+ if (pvl == pvl2)
+ break;
+ if (id_equal(&pvl->pv->id,
+ &pvl2->pv->id)) {
+ if (!id_write_format(&pvl->pv->id, uuid,
+ sizeof(uuid)))
+ stack;
+ log_error("Internal error: Duplicate PV id "
+ "%s detected for %s in %s.",
+ uuid, dev_name(pvl->pv->dev),
+ vg->name);
+ r = 0;
+ }
+ }
+ }
if (!check_pv_segments(vg)) {
log_error("Internal error: PV segments corrupted in %s.",
vg->name);
- return 0;
+ r = 0;
+ }
+
+ list_iterate_items(lvl, &vg->lvs) {
+ list_iterate_items(lvl2, &vg->lvs) {
+ if (lvl == lvl2)
+ break;
+ if (!strcmp(lvl->lv->name, lvl2->lv->name)) {
+ log_error("Internal error: Duplicate LV name "
+ "%s detected in %s.", lvl->lv->name,
+ vg->name);
+ r = 0;
+ }
+ if (id_equal(&lvl->lv->lvid.id[1],
+ &lvl2->lv->lvid.id[1])) {
+ if (!id_write_format(&lvl->lv->lvid.id[1], uuid,
+ sizeof(uuid)))
+ stack;
+ log_error("Internal error: Duplicate LV id "
+ "%s detected for %s and %s in %s.",
+ uuid, lvl->lv->name, lvl2->lv->name,
+ vg->name);
+ r = 0;
+ }
+ }
}
list_iterate_items(lvl, &vg->lvs) {
if (!check_lv_segments(lvl->lv, 1)) {
log_error("Internal error: LV segments corrupted in %s.",
lvl->lv->name);
- return 0;
+ r = 0;
}
}
- return 1;
+ return r;
}
/*
@@ -992,7 +1043,7 @@
if (correct_vg) {
if (list_size(&correct_vg->pvs) != list_size(pvids)) {
log_debug("Cached VG %s had incorrect PV list",
- vg->name);
+ vgname);
if (memlock())
inconsistent = 1;
@@ -1001,7 +1052,7 @@
} else list_iterate_items(pvl, &correct_vg->pvs) {
if (!str_list_match_item(pvids, pvl->pv->dev->pvid)) {
log_debug("Cached VG %s had incorrect PV list",
- vg->name);
+ vgname);
correct_vg = NULL;
break;
}
Modified: lvm2/upstream/current/lib/metadata/metadata.h
==============================================================================
--- lvm2/upstream/current/lib/metadata/metadata.h (original)
+++ lvm2/upstream/current/lib/metadata/metadata.h Mon Oct 23 08:49:10 2006
@@ -29,12 +29,12 @@
#define MAX_STRIPES 128U
#define SECTOR_SHIFT 9L
#define SECTOR_SIZE ( 1L << SECTOR_SHIFT )
-#define STRIPE_SIZE_MIN ( (unsigned) getpagesize() >> SECTOR_SHIFT) /* PAGESIZE in sectors */
+#define STRIPE_SIZE_MIN ( (unsigned) lvm_getpagesize() >> SECTOR_SHIFT) /* PAGESIZE in sectors */
#define STRIPE_SIZE_MAX ( 512L * 1024L >> SECTOR_SHIFT) /* 512 KB in sectors */
#define STRIPE_SIZE_LIMIT ((UINT_MAX >> 2) + 1)
#define PV_MIN_SIZE ( 512L * 1024L >> SECTOR_SHIFT) /* 512 KB in sectors */
-#define PE_ALIGN (65536UL >> SECTOR_SHIFT) /* PE alignment */
#define MAX_RESTRICTED_LVS 255 /* Used by FMT_RESTRICTED_LVIDS */
+#define MIRROR_LOG_SIZE 1 /* Extents */
/* Various flags */
/* Note that the bits no longer necessarily correspond to LVM1 disk format */
@@ -82,6 +82,7 @@
ALLOC_INVALID = 0,
ALLOC_INHERIT,
ALLOC_CONTIGUOUS,
+ ALLOC_CLING,
ALLOC_NORMAL,
ALLOC_ANYWHERE
} alloc_policy_t;
@@ -403,6 +404,7 @@
/*
* Utility functions
*/
+unsigned long pe_align(void);
int vg_validate(struct volume_group *vg);
int vg_write(struct volume_group *vg);
int vg_commit(struct volume_group *vg);
Modified: lvm2/upstream/current/lib/metadata/mirror.c
==============================================================================
--- lvm2/upstream/current/lib/metadata/mirror.c (original)
+++ lvm2/upstream/current/lib/metadata/mirror.c Mon Oct 23 08:49:10 2006
@@ -161,9 +161,11 @@
remove_log = 1;
}
- if (remove_log) {
+ if (remove_log && mirrored_seg->log_lv) {
log_lv = mirrored_seg->log_lv;
mirrored_seg->log_lv = NULL;
+ log_lv->status &= ~MIRROR_LOG;
+ log_lv->status |= VISIBLE_LV;
}
/*
@@ -199,6 +201,12 @@
/* Delete the 'orphan' LVs */
for (m = num_mirrors; m < old_area_count; m++) {
+ /* LV is now independent of the mirror so must acquire lock. */
+ if (!activate_lv(mirrored_seg->lv->vg->cmd, seg_lv(mirrored_seg, m))) {
+ stack;
+ return 0;
+ }
+
if (!deactivate_lv(mirrored_seg->lv->vg->cmd, seg_lv(mirrored_seg, m))) {
stack;
return 0;
@@ -211,6 +219,11 @@
}
if (lv1) {
+ if (!activate_lv(mirrored_seg->lv->vg->cmd, lv1)) {
+ stack;
+ return 0;
+ }
+
if (!deactivate_lv(mirrored_seg->lv->vg->cmd, lv1)) {
stack;
return 0;
@@ -223,6 +236,11 @@
}
if (log_lv) {
+ if (!activate_lv(mirrored_seg->lv->vg->cmd, log_lv)) {
+ stack;
+ return 0;
+ }
+
if (!deactivate_lv(mirrored_seg->lv->vg->cmd, log_lv)) {
stack;
return 0;
@@ -412,7 +430,7 @@
return 0;
}
- if (lvm_snprintf(img_name, len, "%s_mimage_%%d", lv->name) < 0) {
+ if (dm_snprintf(img_name, len, "%s_mimage_%%d", lv->name) < 0) {
log_error("img_name allocation failed. "
"Remove new LV and retry.");
return 0;
Modified: lvm2/upstream/current/lib/metadata/segtype.h
==============================================================================
--- lvm2/upstream/current/lib/metadata/segtype.h (original)
+++ lvm2/upstream/current/lib/metadata/segtype.h Mon Oct 23 08:49:10 2006
@@ -77,6 +77,9 @@
uint64_t *total_numerator,
uint64_t *total_denominator, float *percent);
int (*target_present) (void);
+ int (*modules_needed) (struct dm_pool *mem,
+ const struct lv_segment *seg,
+ struct list *modules);
void (*destroy) (const struct segment_type * segtype);
int (*target_register_events) (struct lv_segment *seg, int events);
int (*target_unregister_events) (struct lv_segment *seg, int events);
Modified: lvm2/upstream/current/lib/mirror/mirrored.c
==============================================================================
--- lvm2/upstream/current/lib/mirror/mirrored.c (original)
+++ lvm2/upstream/current/lib/mirror/mirrored.c Mon Oct 23 08:49:10 2006
@@ -26,6 +26,7 @@
#include "targets.h"
#include "activate.h"
#include "sharedlib.h"
+#include "str_list.h"
#ifdef DMEVENTD
# include <libdevmapper-event.h>
@@ -447,6 +448,28 @@
#endif /* DMEVENTD */
#endif /* DEVMAPPER_SUPPORT */
+static int _mirrored_modules_needed(struct dm_pool *mem,
+ const struct lv_segment *seg,
+ struct list *modules)
+{
+ if (seg->log_lv &&
+ !list_segment_modules(mem, first_seg(seg->log_lv), modules))
+ return_0;
+
+ if ((seg->lv->vg->status & CLUSTERED) &&
+ !str_list_add(mem, modules, "clog")) {
+ log_error("cluster log string list allocation failed");
+ return 0;
+ }
+
+ if (!str_list_add(mem, modules, "mirror")) {
+ log_error("mirror string list allocation failed");
+ return 0;
+ }
+
+ return 1;
+}
+
static void _mirrored_destroy(const struct segment_type *segtype)
{
dm_free((void *) segtype);
@@ -467,6 +490,7 @@
.target_unregister_events = _target_unregister_events,
#endif
#endif
+ .modules_needed = _mirrored_modules_needed,
.destroy = _mirrored_destroy,
};
Modified: lvm2/upstream/current/lib/misc/configure.h.in
==============================================================================
--- lvm2/upstream/current/lib/misc/configure.h.in (original)
+++ lvm2/upstream/current/lib/misc/configure.h.in Mon Oct 23 08:49:10 2006
@@ -174,6 +174,9 @@
/* Define to 1 if you have the <selinux/selinux.h> header file. */
#undef HAVE_SELINUX_SELINUX_H
+/* define to 1 to include support for realtime clock */
+#undef HAVE_REALTIME
+
/* Define to 1 if you have the `setlocale' function. */
#undef HAVE_SETLOCALE
Modified: lvm2/upstream/current/lib/misc/lib.h
==============================================================================
--- lvm2/upstream/current/lib/misc/lib.h (original)
+++ lvm2/upstream/current/lib/misc/lib.h Mon Oct 23 08:49:10 2006
@@ -28,6 +28,7 @@
#include "log.h"
#include "intl.h"
#include "lvm-types.h"
+#include "lvm-wrappers.h"
#include <libdevmapper.h>
Modified: lvm2/upstream/current/lib/misc/lvm-file.c
==============================================================================
--- lvm2/upstream/current/lib/misc/lvm-file.c (original)
+++ lvm2/upstream/current/lib/misc/lvm-file.c Mon Oct 23 08:49:10 2006
@@ -50,7 +50,7 @@
for (i = 0; i < 20; i++, num++) {
- if (lvm_snprintf(buffer, len, "%s/.lvm_%s_%d_%d",
+ if (dm_snprintf(buffer, len, "%s/.lvm_%s_%d_%d",
dir, hostname, pid, num) == -1) {
log_err("Not enough space to build temporary file "
"string.");
Modified: lvm2/upstream/current/lib/misc/lvm-string.c
==============================================================================
--- lvm2/upstream/current/lib/misc/lvm-string.c (original)
+++ lvm2/upstream/current/lib/misc/lvm-string.c Mon Oct 23 08:49:10 2006
@@ -14,33 +14,10 @@
*/
#include "lib.h"
-#include "lvm-types.h"
#include "lvm-string.h"
#include <ctype.h>
-/*
- * On error, up to glibc 2.0.6, snprintf returned -1 if buffer was too small;
- * From glibc 2.1 it returns number of chars (excl. trailing null) that would
- * have been written had there been room.
- *
- * lvm_snprintf reverts to the old behaviour.
- */
-int lvm_snprintf(char *buf, size_t bufsize, const char *format, ...)
-{
- int n;
- va_list ap;
-
- va_start(ap, format);
- n = vsnprintf(buf, bufsize, format, ap);
- va_end(ap);
-
- if (n < 0 || (n > bufsize - 1))
- return -1;
-
- return n;
-}
-
int emit_to_buffer(char **buffer, size_t *size, const char *fmt, ...)
{
int n;
@@ -59,47 +36,6 @@
}
/*
- * consume characters while they match the predicate function.
- */
-static char *_consume(char *buffer, int (*fn) (int))
-{
- while (*buffer && fn(*buffer))
- buffer++;
-
- return buffer;
-}
-
-static int _isword(int c)
-{
- return !isspace(c);
-}
-
-/*
- * Split buffer into NULL-separated words in argv.
- * Returns number of words.
- */
-int split_words(char *buffer, unsigned max, char **argv)
-{
- unsigned arg;
-
- for (arg = 0; arg < max; arg++) {
- buffer = _consume(buffer, isspace);
- if (!*buffer)
- break;
-
- argv[arg] = buffer;
- buffer = _consume(buffer, _isword);
-
- if (*buffer) {
- *buffer = '\0';
- buffer++;
- }
- }
-
- return arg;
-}
-
-/*
* Device layer names are all of the form <vg>-<lv>-<layer>, any
* other hyphens that appear in these names are quoted with yet
* another hyphen. The top layer of any device has no layer
@@ -169,47 +105,6 @@
return r;
}
-/*
- * Remove hyphen quoting from a component of a name.
- * NULL-terminates the component and returns start of next component.
- */
-static char *_unquote(char *component)
-{
- char *c = component;
- char *o = c;
- char *r;
-
- while (*c) {
- if (*(c + 1)) {
- if (*c == '-') {
- if (*(c + 1) == '-')
- c++;
- else
- break;
- }
- }
- *o = *c;
- o++;
- c++;
- }
-
- r = (*c) ? c + 1 : c;
- *o = '\0';
-
- return r;
-}
-
-int split_dm_name(struct dm_pool *mem, const char *dmname,
- char **vgname, char **lvname, char **layer)
-{
- if (!(*vgname = dm_pool_strdup(mem, dmname)))
- return 0;
-
- _unquote(*layer = _unquote(*lvname = _unquote(*vgname)));
-
- return 1;
-}
-
int validate_name(const char *n)
{
register char c;
Modified: lvm2/upstream/current/lib/misc/lvm-string.h
==============================================================================
--- lvm2/upstream/current/lib/misc/lvm-string.h (original)
+++ lvm2/upstream/current/lib/misc/lvm-string.h Mon Oct 23 08:49:10 2006
@@ -23,25 +23,11 @@
struct pool;
-/*
- * On error, up to glibc 2.0.6, snprintf returned -1 if buffer was too small;
- * From glibc 2.1 it returns number of chars (excl. trailing null) that would
- * have been written had there been room.
- *
- * lvm_snprintf reverts to the old behaviour.
- */
-int lvm_snprintf(char *buf, size_t bufsize, const char *format, ...);
-
int emit_to_buffer(char **buffer, size_t *size, const char *fmt, ...);
-int split_words(char *buffer, unsigned max, char **argv);
-
char *build_dm_name(struct dm_pool *mem, const char *vg,
const char *lv, const char *layer);
-int split_dm_name(struct dm_pool *mem, const char *dmname,
- char **vgname, char **lvname, char **layer);
-
int validate_name(const char *n);
#endif
Added: lvm2/upstream/current/lib/misc/lvm-wrappers.c
==============================================================================
--- (empty file)
+++ lvm2/upstream/current/lib/misc/lvm-wrappers.c Mon Oct 23 08:49:10 2006
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2006 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "lib.h"
+
+#include <unistd.h>
+
+int lvm_getpagesize(void)
+{
+ return getpagesize();
+}
Added: lvm2/upstream/current/lib/misc/lvm-wrappers.h
==============================================================================
--- (empty file)
+++ lvm2/upstream/current/lib/misc/lvm-wrappers.h Mon Oct 23 08:49:10 2006
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
+ * Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LVM_WRAPPERS_H
+#define _LVM_WRAPPERS_H
+
+int lvm_getpagesize(void);
+
+#endif
Modified: lvm2/upstream/current/lib/misc/sharedlib.c
==============================================================================
--- lvm2/upstream/current/lib/misc/sharedlib.c (original)
+++ lvm2/upstream/current/lib/misc/sharedlib.c Mon Oct 23 08:49:10 2006
@@ -17,6 +17,7 @@
#include "config.h"
#include "lvm-string.h"
#include "sharedlib.h"
+#include "toolcontext.h"
#include <limits.h>
#include <sys/stat.h>
@@ -32,7 +33,7 @@
* if present */
if (libname[0] == '/' ||
!(lib_dir = find_config_tree_str(cmd, "global/library_dir", 0)) ||
- (lvm_snprintf(path, path_len, "%s/%s", lib_dir,
+ (dm_snprintf(path, path_len, "%s/%s", lib_dir,
libname) == -1) || stat(path, &info) == -1)
strncpy(path, libname, path_len);
}
@@ -43,6 +44,12 @@
char path[PATH_MAX];
void *library;
+ if (cmd->is_static) {
+ log_error("Not loading shared %s library %s in static mode.",
+ desc, libname);
+ return NULL;
+ }
+
get_shared_library_path(cmd, libname, path, sizeof(path));
log_very_verbose("Opening shared %s library %s", desc, path);
Added: lvm2/upstream/current/lib/misc/timestamp.c
==============================================================================
--- (empty file)
+++ lvm2/upstream/current/lib/misc/timestamp.c Mon Oct 23 08:49:10 2006
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2006 Rackable Systems All rights reserved.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Abstract out the time methods used so they can be adjusted later -
+ * the results of these routines should stay in-core. This implementation
+ * requires librt.
+ */
+
+#include "lib.h"
+#include <stdlib.h>
+
+#include "timestamp.h"
+
+/*
+ * The realtime section uses clock_gettime with the CLOCK_MONOTONIC
+ * parameter to prevent issues with time warps
+ */
+#ifdef HAVE_REALTIME
+
+#include <time.h>
+#include <bits/time.h>
+
+struct timestamp {
+ struct timespec t;
+};
+
+struct timestamp *get_timestamp(void)
+{
+ struct timestamp *ts = NULL;
+
+ if (!(ts = dm_malloc(sizeof(*ts))))
+ return_NULL;
+
+ if (clock_gettime(CLOCK_MONOTONIC, &ts->t)) {
+ log_sys_error("clock_gettime", "get_timestamp");
+ return NULL;
+ }
+
+ return ts;
+}
+
+/* cmp_timestamp: Compare two timestamps
+ *
+ * Return: -1 if t1 is less than t2
+ * 0 if t1 is equal to t2
+ * 1 if t1 is greater than t2
+ */
+int cmp_timestamp(struct timestamp *t1, struct timestamp *t2)
+{
+ if(t1->t.tv_sec < t2->t.tv_sec)
+ return -1;
+ if(t1->t.tv_sec > t2->t.tv_sec)
+ return 1;
+
+ if(t1->t.tv_nsec < t2->t.tv_nsec)
+ return -1;
+ if(t1->t.tv_nsec > t2->t.tv_nsec)
+ return 1;
+
+ return 0;
+}
+
+#else /* ! HAVE_REALTIME */
+
+/*
+ * The !realtime section just uses gettimeofday and is therefore subject
+ * to ntp-type time warps - not sure if should allow that.
+ */
+
+#include <sys/time.h>
+
+struct timestamp {
+ struct timeval t;
+};
+
+struct timestamp *get_timestamp(void)
+{
+ struct timestamp *ts = NULL;
+
+ if (!(ts = dm_malloc(sizeof(*ts))))
+ return_NULL;
+
+ if (gettimeofday(&ts->t, NULL)) {
+ log_sys_error("gettimeofday", "get_timestamp");
+ return NULL;
+ }
+
+ return ts;
+}
+
+/* cmp_timestamp: Compare two timestamps
+ *
+ * Return: -1 if t1 is less than t2
+ * 0 if t1 is equal to t2
+ * 1 if t1 is greater than t2
+ */
+int cmp_timestamp(struct timestamp *t1, struct timestamp *t2)
+{
+ if(t1->t.tv_sec < t2->t.tv_sec)
+ return -1;
+ if(t1->t.tv_sec > t2->t.tv_sec)
+ return 1;
+
+ if(t1->t.tv_usec < t2->t.tv_usec)
+ return -1;
+ if(t1->t.tv_usec > t2->t.tv_usec)
+ return 1;
+
+ return 0;
+}
+
+#endif /* HAVE_REALTIME */
+
+void destroy_timestamp(struct timestamp *t)
+{
+ if (t)
+ dm_free(t);
+}
Added: lvm2/upstream/current/lib/misc/timestamp.h
==============================================================================
--- (empty file)
+++ lvm2/upstream/current/lib/misc/timestamp.h Mon Oct 23 08:49:10 2006
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2006 Rackable Systems All rights reserved.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LVM_TIMESTAMP_H
+#define _LVM_TIMESTAMP_H
+
+struct timestamp;
+
+struct timestamp *get_timestamp(void);
+
+/* cmp_timestamp: Compare two timestamps
+ *
+ * Return: -1 if t1 is less than t2
+ * 0 if t1 is equal to t2
+ * 1 if t1 is greater than t2
+ */
+int cmp_timestamp(struct timestamp *t1, struct timestamp *t2);
+
+void destroy_timestamp(struct timestamp *t);
+
+#endif /* _LVM_TIMESTAMP_H */
+
Modified: lvm2/upstream/current/lib/mm/memlock.c
==============================================================================
--- lvm2/upstream/current/lib/mm/memlock.c (original)
+++ lvm2/upstream/current/lib/mm/memlock.c Mon Oct 23 08:49:10 2006
@@ -58,7 +58,7 @@
static void _touch_memory(void *mem, size_t size)
{
- size_t pagesize = getpagesize();
+ size_t pagesize = lvm_getpagesize();
void *pos = mem;
void *end = mem + size - sizeof(long);
Modified: lvm2/upstream/current/lib/report/columns.h
==============================================================================
--- lvm2/upstream/current/lib/report/columns.h (original)
+++ lvm2/upstream/current/lib/report/columns.h Mon Oct 23 08:49:10 2006
@@ -33,6 +33,7 @@
FIELD(LVS, lv, STR, "Move", lvid, 4, movepv, "move_pv")
FIELD(LVS, lv, STR, "LV Tags", tags, 7, tags, "lv_tags")
FIELD(LVS, lv, STR, "Log", lvid, 3, loglv, "mirror_log")
+FIELD(LVS, lv, STR, "Modules", lvid, 7, modules, "modules")
FIELD(PVS, pv, STR, "Fmt", id, 3, pvfmt, "pv_fmt")
FIELD(PVS, pv, STR, "PV UUID", id, 38, uuid, "pv_uuid")
@@ -68,8 +69,11 @@
FIELD(SEGS, seg, STR, "Type", list, 4, segtype, "segtype")
FIELD(SEGS, seg, NUM, "#Str", area_count, 4, uint32, "stripes")
FIELD(SEGS, seg, NUM, "Stripe", stripe_size, 6, size32, "stripesize")
+FIELD(SEGS, seg, NUM, "Stripe", stripe_size, 6, size32, "stripe_size")
FIELD(SEGS, seg, NUM, "Chunk", list, 5, chunksize, "chunksize")
+FIELD(SEGS, seg, NUM, "Chunk", list, 5, chunksize, "chunk_size")
FIELD(SEGS, seg, NUM, "Region", region_size, 6, size32, "regionsize")
+FIELD(SEGS, seg, NUM, "Region", region_size, 6, size32, "region_size")
FIELD(SEGS, seg, NUM, "Start", list, 5, segstart, "seg_start")
FIELD(SEGS, seg, NUM, "SSize", list, 5, segsize, "seg_size")
FIELD(SEGS, seg, STR, "Seg Tags", tags, 8, tags, "seg_tags")
Modified: lvm2/upstream/current/lib/report/report.c
==============================================================================
--- lvm2/upstream/current/lib/report/report.c (original)
+++ lvm2/upstream/current/lib/report/report.c Mon Oct 23 08:49:10 2006
@@ -21,6 +21,7 @@
#include "display.h"
#include "activate.h"
#include "segtype.h"
+#include "str_list.h"
/*
* For macro use
@@ -103,6 +104,8 @@
switch (alloc) {
case ALLOC_CONTIGUOUS:
return 'c';
+ case ALLOC_CLING:
+ return 'C';
case ALLOC_NORMAL:
return 'n';
case ALLOC_ANYWHERE:
@@ -172,9 +175,9 @@
return 0;
}
- if (lvm_snprintf(extent_str, sizeof(extent_str), "(%" PRIu32
+ if (dm_snprintf(extent_str, sizeof(extent_str), "(%" PRIu32
")", extent) < 0) {
- log_error("Extent number lvm_snprintf failed");
+ log_error("Extent number dm_snprintf failed");
return 0;
}
@@ -200,6 +203,7 @@
return 1;
}
+
static int _tags_disp(struct report_handle *rh, struct field *field,
const void *data)
{
@@ -230,6 +234,23 @@
return 1;
}
+static int _modules_disp(struct report_handle *rh, struct field *field,
+ const void *data)
+{
+ const struct logical_volume *lv = (const struct logical_volume *) data;
+ struct list *modules;
+
+ if (!(modules = str_list_create(rh->mem))) {
+ log_error("modules str_list allocation failed");
+ return 0;
+ }
+
+ if (!list_lv_modules(rh->mem, lv, modules))
+ return_0;
+
+ return _tags_disp(rh, field, modules);
+}
+
static int _vgfmt_disp(struct report_handle *rh, struct field *field,
const void *data)
{
@@ -276,7 +297,7 @@
return 0;
}
- if (lvm_snprintf(repstr, 12, "%d", value) < 0) {
+ if (dm_snprintf(repstr, 12, "%d", value) < 0) {
log_error("int too big: %d", value);
return 0;
}
@@ -540,7 +561,7 @@
return 0;
}
- if (lvm_snprintf(repstr, len, "[%s]", lv->name) < 0) {
+ if (dm_snprintf(repstr, len, "[%s]", lv->name) < 0) {
log_error("lvname snprintf failed");
return 0;
}
@@ -784,7 +805,7 @@
return 0;
}
- if (lvm_snprintf(repstr, 11, "%u", value) < 0) {
+ if (dm_snprintf(repstr, 11, "%u", value) < 0) {
log_error("uint32 too big: %u", value);
return 0;
}
@@ -813,7 +834,7 @@
return 0;
}
- if (lvm_snprintf(repstr, 12, "%d", value) < 0) {
+ if (dm_snprintf(repstr, 12, "%d", value) < 0) {
log_error("int32 too big: %d", value);
return 0;
}
@@ -870,7 +891,7 @@
return 0;
}
- if (lvm_snprintf(repstr, 7, "%.2f", snap_percent) < 0) {
+ if (dm_snprintf(repstr, 7, "%.2f", snap_percent) < 0) {
log_error("snapshot percentage too large");
return 0;
}
@@ -910,7 +931,7 @@
return 0;
}
- if (lvm_snprintf(repstr, 7, "%.2f", percent) < 0) {
+ if (dm_snprintf(repstr, 7, "%.2f", percent) < 0) {
log_error("copy percentage too large");
return 0;
}
@@ -948,6 +969,44 @@
const unsigned int _num_fields = sizeof(_fields) / sizeof(_fields[0]);
+static void _display_fields(void)
+{
+ uint32_t f;
+ const char *type, *last_type = "";
+
+ for (f = 0; f < _num_fields; f++) {
+ switch (_fields[f].type) {
+ case PVS:
+ type = "Physical Volume";
+ break;
+ case LVS:
+ type = "Logical Volume";
+ break;
+ case VGS:
+ type = "Volume Group";
+ break;
+ case SEGS:
+ type = "Logical Volume Segment";
+ break;
+ case PVSEGS:
+ type = "Physical Volume Segment";
+ break;
+ default:
+ type = " ";
+ }
+
+ if (type != last_type) {
+ if (*last_type)
+ log_print(" ");
+ log_print("%s Fields", type);
+ }
+
+ log_print("- %s", _fields[f].id);
+
+ last_type = type;
+ }
+}
+
/*
* Initialise report handle
*/
@@ -1080,6 +1139,8 @@
while (*we && *we != ',')
we++;
if (!_field_match(rh, ws, (size_t) (we - ws))) {
+ _display_fields();
+ log_print(" ");
log_error("Unrecognised field: %.*s", (int) (we - ws),
ws);
return 0;
@@ -1324,7 +1385,7 @@
heading = _fields[fp->field_num].heading;
if (rh->flags & RH_ALIGNED) {
- if (lvm_snprintf(buf, sizeof(buf), "%-*.*s",
+ if (dm_snprintf(buf, sizeof(buf), "%-*.*s",
fp->width, fp->width, heading) < 0) {
log_error("snprintf heading failed");
dm_pool_end_object(rh->mem);
@@ -1467,7 +1528,7 @@
strlen(repstr)))
goto bad;
} else if (field->props->flags & FLD_ALIGN_LEFT) {
- if (lvm_snprintf(buf, sizeof(buf), "%-*.*s",
+ if (dm_snprintf(buf, sizeof(buf), "%-*.*s",
width, width, repstr) < 0) {
log_error("snprintf repstr failed");
dm_pool_end_object(rh->mem);
@@ -1476,7 +1537,7 @@
if (!dm_pool_grow_object(rh->mem, buf, width))
goto bad;
} else if (field->props->flags & FLD_ALIGN_RIGHT) {
- if (lvm_snprintf(buf, sizeof(buf), "%*.*s",
+ if (dm_snprintf(buf, sizeof(buf), "%*.*s",
width, width, repstr) < 0) {
log_error("snprintf repstr failed");
dm_pool_end_object(rh->mem);
Modified: lvm2/upstream/current/lib/snapshot/snapshot.c
==============================================================================
--- lvm2/upstream/current/lib/snapshot/snapshot.c (original)
+++ lvm2/upstream/current/lib/snapshot/snapshot.c Mon Oct 23 08:49:10 2006
@@ -20,6 +20,7 @@
#include "text_export.h"
#include "config.h"
#include "activate.h"
+#include "str_list.h"
static const char *_snap_name(const struct lv_segment *seg)
{
@@ -126,6 +127,18 @@
}
#endif
+static int _snap_modules_needed(struct dm_pool *mem,
+ const struct lv_segment *seg,
+ struct list *modules)
+{
+ if (!str_list_add(mem, modules, "snapshot")) {
+ log_error("snapshot string list allocation failed");
+ return 0;
+ }
+
+ return 1;
+}
+
static void _snap_destroy(const struct segment_type *segtype)
{
dm_free((void *)segtype);
@@ -139,6 +152,7 @@
.target_percent = _snap_target_percent,
.target_present = _snap_target_present,
#endif
+ .modules_needed = _snap_modules_needed,
.destroy = _snap_destroy,
};
Modified: lvm2/upstream/current/lib/zero/zero.c
==============================================================================
--- lvm2/upstream/current/lib/zero/zero.c (original)
+++ lvm2/upstream/current/lib/zero/zero.c Mon Oct 23 08:49:10 2006
@@ -63,6 +63,18 @@
}
#endif
+static int _zero_modules_needed(struct dm_pool *mem,
+ const struct lv_segment *seg,
+ struct list *modules)
+{
+ if (!str_list_add(mem, modules, "zero")) {
+ log_error("zero module string list allocation failed");
+ return 0;
+ }
+
+ return 1;
+}
+
static void _zero_destroy(const struct segment_type *segtype)
{
dm_free((void *) segtype);
@@ -75,6 +87,7 @@
.add_target_line = _zero_add_target_line,
.target_present = _zero_target_present,
#endif
+ .modules_needed = _zero_modules_needed,
.destroy = _zero_destroy,
};
Modified: lvm2/upstream/current/man/Makefile.in
==============================================================================
--- lvm2/upstream/current/man/Makefile.in (original)
+++ lvm2/upstream/current/man/Makefile.in Mon Oct 23 08:49:10 2006
@@ -17,7 +17,8 @@
VPATH = @srcdir@
MAN5=lvm.conf.5
-MAN8=lvchange.8 lvcreate.8 lvdisplay.8 lvextend.8 lvm.8 lvmchange.8 \
+MAN8=lvchange.8 lvconvert.8 lvcreate.8 lvdisplay.8 lvextend.8 lvm.8 \
+ lvmchange.8 \
lvmdiskscan.8 lvreduce.8 lvremove.8 lvrename.8 lvresize.8 lvs.8 \
lvscan.8 pvchange.8 pvcreate.8 pvdisplay.8 pvmove.8 pvremove.8 \
pvresize.8 pvs.8 pvscan.8 vgcfgbackup.8 vgcfgrestore.8 vgchange.8 \
Modified: lvm2/upstream/current/man/clvmd.8
==============================================================================
--- lvm2/upstream/current/man/clvmd.8 (original)
+++ lvm2/upstream/current/man/clvmd.8 Mon Oct 23 08:49:10 2006
@@ -4,6 +4,7 @@
.SH SYNOPSIS
.B clvmd
[\-d] [\-h]
+[\-R]
[\-t <timeout>]
[\-V]
.SH DESCRIPTION
@@ -22,6 +23,11 @@
may need to increase this on systems with very large disk farms.
The default is 30 seconds.
.TP
+.I \-R
+Tells all the running clvmd in the cluster to reload their device cache and
+re-read the lvm configuration file. This command should be run whenever the
+devices on a cluster system are changed.
+.TP
.I \-V
Display the version of the cluster LVM daemon.
.SH SEE ALSO
Modified: lvm2/upstream/current/man/lvchange.8
==============================================================================
--- lvm2/upstream/current/man/lvchange.8 (original)
+++ lvm2/upstream/current/man/lvchange.8 Mon Oct 23 08:49:10 2006
@@ -9,6 +9,7 @@
[\-C/\-\-contiguous y/n] [\-d/\-\-debug] [\-\-deltag Tag]
[\-h/\-?/\-\-help]
[\-\-ignorelockingfailure]
+[\-\-monitor {y|n}]
[\-M/\-\-persistent y/n] [\-\-minor minor]
[\-P/\-\-partial y/n]
[\-p/\-\-permission r/w] [\-r/\-\-readahead ReadAheadSectors]
@@ -42,6 +43,14 @@
.I \-\-minor minor
Set the minor number.
.TP
+.I \-\-monitor y/n
+Controls whether or not a mirrored logical volume is monitored by
+dmeventd, if it is installed.
+If a device used by a monitored mirror reports an I/O error,
+the failure is handled according to
+\fBmirror_image_fault_policy\fP and \fBmirror_log_fault_policy\fP
+set in \fBlvm.conf\fP.
+.TP
.I \-M, \-\-persistent y/n
Set to y to make the minor number specified persistent.
.TP
Added: lvm2/upstream/current/man/lvconvert.8
==============================================================================
--- (empty file)
+++ lvm2/upstream/current/man/lvconvert.8 Mon Oct 23 08:49:10 2006
@@ -0,0 +1,61 @@
+.TH LVCONVERT 8 "LVM TOOLS" "Red Hat, Inc" \" -*- nroff -*-
+.SH NAME
+lvconvert \- convert a logical volume between linear and mirror
+.SH SYNOPSIS
+.B lvconvert
+[\-m/\-\-mirrors Mirrors [\-\-corelog] [\-R/\-\-regionsize MirrorLogRegionSize]]
+[\-A/\-\-alloc AllocationPolicy]
+[\-h/\-?/\-\-help]
+[\-v/\-\-verbose]
+[\-\-version]
+LogicalVolume[Path] [PhysicalVolume[Path]...]
+.SH DESCRIPTION
+lvconvert will change a linear logical volume to a mirror
+logical volume or vis versa. It is also used to add and
+remove disk logs from mirror devices.
+.SH OPTIONS
+See \fBlvm\fP for common options.
+.TP
+.I \-m, \-\-mirrors Mirrors
+Specifies the degree of the mirror you wish to create.
+For example, "-m 1" would convert the original logical
+volume to a mirror volume with 2-sides; that is, a
+linear volume plus one copy.
+.TP
+.I \-\-corelog
+This optional argument tells lvconvert to switch the
+mirror from using a disk-based (persistent) log to
+an in-memory log. You may only specify this option
+when the \-\-mirror argument is the same degree of
+the mirror you are changing.
+.TP
+.I \-R, \-\-regionsize MirrorLogRegionSize
+A mirror is divided into regions of this size (in MB), and the mirror log
+uses this granularity to track which regions are in sync.
+.SH Examples
+"lvconvert -m1 vg00/lvol1"
+.br
+converts the linear logical volume "vg00/lvol1" to
+a mirror logical volume. This command could also
+be used to convert a two-way mirror with an
+in-memory log to a two-way mirror with a disk log.
+
+"lvconvert -m1 --corelog vg00/lvol1"
+.br
+converts a two-way mirror with a disk log to a
+two-way mirror with an in-memory log.
+
+"lvconvert -m0 vg00/lvol1"
+.br
+converts a mirror logical volume to a linear logical
+volume.
+
+.SH SEE ALSO
+.BR lvm (8),
+.BR vgcreate (8),
+.BR lvremove (8),
+.BR lvrename (8),
+.BR lvextend (8),
+.BR lvreduce (8),
+.BR lvdisplay (8),
+.BR lvscan (8)
Modified: lvm2/upstream/current/man/lvcreate.8
==============================================================================
--- lvm2/upstream/current/man/lvcreate.8 (original)
+++ lvm2/upstream/current/man/lvcreate.8 Mon Oct 23 08:49:10 2006
@@ -8,12 +8,13 @@
[\-A/\-\-autobackup y/n] [\-C/\-\-contiguous y/n] [\-d/\-\-debug]
[\-h/\-?/\-\-help]
[\-i/\-\-stripes Stripes [\-I/\-\-stripesize StripeSize]]
-{\-l/\-\-extents LogicalExtentsNumber |
+{\-l/\-\-extents LogicalExtentsNumber[%{VG|FREE}] |
\-L/\-\-size LogicalVolumeSize[kKmMgGtT]}
[\-M/\-\-persistent y/n] [\-\-minor minor]
+[\-m/\-\-mirrors Mirrors [\-\-nosync] [\-\-corelog]
+[\-R/\-\-regionsize MirrorLogRegionSize]]
[\-n/\-\-name LogicalVolumeName]
[\-p/\-\-permission r/rw] [\-r/\-\-readahead ReadAheadSectors]
-[-R|--regionsize MirrorLogRegionSize]
[\-t/\-\-test]
[\-v/\-\-verbose] [\-Z/\-\-zero y/n]
VolumeGroupName [PhysicalVolumePath...]
@@ -21,7 +22,7 @@
.br
.B lvcreate
-{\-l/\-\-extents LogicalExtentsNumber |
+{\-l/\-\-extents LogicalExtentsNumber[%{VG|FREE}] |
\-L/\-\-size LogicalVolumeSize[kKmMgGtT]}
[\-c/\-\-chunksize ChunkSize]
\-s/\-\-snapshot \-n/\-\-name SnapshotLogicalVolumeName OriginalLogicalVolumePath
@@ -62,9 +63,12 @@
For metadata in LVM2 format, the stripe size may be a larger
power of 2 but must not exceed the physical extent size.
.TP
-.I \-l, \-\-extents LogicalExtentsNumber
+.I \-l, \-\-extents LogicalExtentsNumber[%{VG|FREE}]
Gives the number of logical extents to allocate for the new
logical volume.
+This can also be expressed as a percentage of the total space
+in the Volume Group with the suffix %VG or of the remaining free space
+with the suffix %FREE.
.TP
.I \-L, \-\-size LogicalVolumeSize[kKmMgGtT]
Gives the size to allocate for the new logical volume.
@@ -79,6 +83,23 @@
.I \-M, \-\-persistent y/n
Set to y to make the minor number specified persistent.
.TP
+.I \-m, \-\-mirrors Mirrors
+Creates a mirrored logical volume with "Mirrors" copies. For example,
+specifying "-m 1" would result in a mirror with two-sides; that is, a
+linear volume plus one copy.
+
+Specifying the optional argument "--nosync" will cause the creation
+of the mirror to skip the initial resynchronization. Any data written
+afterwards will be mirrored, but the original contents will not be
+copied. This is useful for skipping a potentially long and resource
+intensive initial sync.
+
+Specifying the optional argument "--corelog" will create a mirror with
+an in-memory log verses a disk-based (persistent) log. While this
+removes the need for an extra log device and *may* be slightly faster,
+it requires that the entire mirror be resynchronized upon each
+instantiation (e.g. a reboot).
+.TP
.I \-n, \-\-name LogicalVolumeName
The name for the new logical volume.
.br
@@ -94,8 +115,8 @@
Set read ahead sector count of this logical volume to a value between 2 and 120.
Ignored by device-mapper.
.TP
-.I \-R \-\-regionsize MirrorLogRegionSize
-A mirror is divided into regions of this size (in KB), and the mirror log
+.I \-R, \-\-regionsize MirrorLogRegionSize
+A mirror is divided into regions of this size (in MB), and the mirror log
uses this granularity to track which regions are in sync.
.TP
.I \-s, \-\-snapshot
@@ -122,10 +143,15 @@
Warning: trying to mount an unzeroed logical volume can cause the system to
hang.
.SH Examples
-"lvcreate -i 3 -I 8 -L 100 vg00" tries to create a striped logical
+"lvcreate -i 3 -I 8 -L 100M vg00" tries to create a striped logical
volume with 3 stripes, a stripesize of 8KB and a size of 100MB in the volume
group named vg00. The logical volume name will be chosen by lvcreate.
+"lvcreate -m1 -L 500M vg00" tries to create a mirror logical volume
+with 2 sides with a useable size of 500 MiB. This operation would
+require 3 devices - two for the mirror devices and one for the disk
+log.
+
"lvcreate --size 100m --snapshot --name snap /dev/vg00/lvol1"
.br
creates a snapshot logical volume named /dev/vg00/snap which has access to the
Modified: lvm2/upstream/current/man/lvextend.8
==============================================================================
--- lvm2/upstream/current/man/lvextend.8 (original)
+++ lvm2/upstream/current/man/lvextend.8 Mon Oct 23 08:49:10 2006
@@ -6,7 +6,7 @@
[\-\-alloc AllocationPolicy]
[\-A/\-\-autobackup y/n] [\-d/\-\-debug] [\-h/\-?/\-\-help]
[\-i/\-\-stripes Stripes [\-I/\-\-stripesize StripeSize]]
-{\-l/\-\-extents [+]LogicalExtentsNumber |
+{\-l/\-\-extents [+]LogicalExtentsNumber[%{VG|LV|FREE}] |
\-L/\-\-size [+]LogicalVolumeSize[kKmMgGtT]}
[\-t/\-\-test]
[\-v/\-\-verbose] LogicalVolumePath [PhysicalVolumePath...]
@@ -15,13 +15,20 @@
Extension of snapshot logical volumes (see
.B lvcreate(8)
for information to create snapshots) is supported as well.
+But to change the number of copies in a mirrored logical
+volume use
+.BR lvconvert (8).
.SH OPTIONS
See \fBlvm\fP for common options.
.TP
-.I \-l, \-\-extents [+]LogicalExtentsNumber
+.I \-l, \-\-extents [+]LogicalExtentsNumber[%{VG|LV|FREE}]
Extend or set the logical volume size in units of logical extents.
With the + sign the value is added to the actual size
of the logical volume and without it, the value is taken as an absolute one.
+The number can also be expressed as a percentage of the total space
+in the Volume Group with the suffix %VG or relative to the existing
+size of the Logical Volume with the suffix %LV or as a percentage of the remaining
+free space in the Volume Group with the suffix %FREE.
.TP
.I \-L, \-\-size [+]LogicalVolumeSize[kKmMgGtT]
Extend or set the logical volume size in units in units of megabytes.
@@ -48,6 +55,7 @@
.SH SEE ALSO
.BR lvm (8),
.BR lvcreate (8),
+.BR lvconvert (8),
.BR lvreduce (8),
.BR lvresize (8),
.BR lvchange (8)
Modified: lvm2/upstream/current/man/lvm.8
==============================================================================
--- lvm2/upstream/current/man/lvm.8 (original)
+++ lvm2/upstream/current/man/lvm.8 Mon Oct 23 08:49:10 2006
@@ -38,7 +38,7 @@
being created in the filesystem for them.
.TP
\fBdumpconfig\fP \(em Display the configuration information after
-loading \fBlvm.conf\fP (8) and any other configuration files.
+loading \fBlvm.conf\fP (5) and any other configuration files.
.TP
\fBformats\fP \(em Display recognised metadata formats.
.TP
@@ -136,7 +136,7 @@
Delete the tag \fBtag\fP from a PV, VG or LV, if it's present.
.TP
\fB--alloc AllocationPolicy\fP
-The allocation policy to use: \fBcontiguous\fP, \fBnormal\fP, \fBanywhere\fP or \fBinherit\fP.
+The allocation policy to use: \fBcontiguous\fP, \fBcling\fP, \fBnormal\fP, \fBanywhere\fP or \fBinherit\fP.
When a command needs to allocate physical extents from the volume group,
the allocation policy controls how they are chosen.
Each volume group and logical volume has an allocation policy.
@@ -146,15 +146,18 @@
which applies the same policy as for the volume group. These policies can
be changed using \fBlvchange\fP (8) and \fBvgchange\fP (8) or over-ridden
on the command line of any command that performs allocation.
-The \fBcontiguous\fP policy requires that new extents are adjacent to
-existing extents. If there are sufficient free extents to satisfy
+The \fBcontiguous\fP policy requires that new extents be placed adjacent
+to existing extents.
+The \fBcling\fP policy places new extents on the same physical
+volume as existing extents in the same stripe of the Logical Volume.
+If there are sufficient free extents to satisfy
an allocation request but \fBnormal\fP doesn't use them,
\fBanywhere\fP will - even if that reduces performance by
placing two stripes on the same physical volume.
.IP
N.B. The policies described above are not implemented fully yet.
-In particular, \fBcontiguous\fP does not place new extents adjacent to existing
-extents and \fBanywhere\fP is not implemented at all.
+In particular, contiguous free space cannot be broken up to
+satisfy allocation attempts.
.SH ENVIRONMENT VARIABLES
.TP
\fBLVM_SYSTEM_DIR\fP
Modified: lvm2/upstream/current/man/lvm.conf.5
==============================================================================
--- lvm2/upstream/current/man/lvm.conf.5 (original)
+++ lvm2/upstream/current/man/lvm.conf.5 Mon Oct 23 08:49:10 2006
@@ -252,7 +252,7 @@
.IP
\fBlocking_library\fP \(em The name of the external locking
library to load if \fBlocking_type\fP is set to 2.
-The default is \fBlvm2_locking.so\fP. If you need to write
+The default is \fBliblvm2clusterlock.so\fP. If you need to write
such a library, look at the lib/locking source code directory.
.TP
\fBtags\fP \(em Host tag settings
Modified: lvm2/upstream/current/man/lvreduce.8
==============================================================================
--- lvm2/upstream/current/man/lvreduce.8 (original)
+++ lvm2/upstream/current/man/lvreduce.8 Mon Oct 23 08:49:10 2006
@@ -4,7 +4,8 @@
.SH SYNOPSIS
.B lvreduce
[\-A/\-\-autobackup y/n] [\-d/\-\-debug] [\-f/\-\-force]
-[\-h/\-?/\-\-help] {\-l/\-\-extents [\-]LogicalExtentsNumber |
+[\-h/\-?/\-\-help]
+{\-l/\-\-extents [\-]LogicalExtentsNumber[%{VG|LV|FREE}] |
\-L/\-\-size [\-]LogicalVolumeSize[kKmMgGtT]}
[\-t/\-\-test]
[\-v/\-\-verbose] LogicalVolume[Path]
@@ -21,21 +22,29 @@
Shrinking snapshot logical volumes (see
.B lvcreate(8)
for information to create snapshots) is supported as well.
+But to change the number of copies in a mirrored logical
+volume use
+.B lvconvert (8).
.br
Sizes will be rounded if necessary - for example, the volume size must
be an exact number of extents and the size of a striped segment must
be a multiple of the number of stripes.
+.br
.SH OPTIONS
See \fBlvm\fP for common options.
.TP
.I \-f, \-\-force
Force size reduction without any question.
.TP
-.I \-l, \-\-extents [\-]LogicalExtentsNumber
+.I \-l, \-\-extents [\-]LogicalExtentsNumber[%{VG|LV|FREE}]
Reduce or set the logical volume size in units of logical extents.
With the - sign the value will be subtracted from
the logical volume's actual size and without it the will be taken as
an absolute size.
+The number can also be expressed as a percentage of the total space
+in the Volume Group with the suffix %VG or relative to the existing
+size of the Logical Volume with the suffix %LV or as a percentage of the remaining
+free space in the Volume Group with the suffix %FREE.
.TP
.I \-L, \-\-size [\-]LogicalVolumeSize[kKmMgGtT]
Reduce or set the logical volume size in units of megabyte by default.
@@ -49,6 +58,7 @@
in volume group vg00 by 3 logical extents.
.SH SEE ALSO
.BR lvchange (8),
+.BR lvconvert (8),
.BR lvcreate (8),
.BR lvextend (8),
.BR lvm (8),
Modified: lvm2/upstream/current/man/lvresize.8
==============================================================================
--- lvm2/upstream/current/man/lvresize.8 (original)
+++ lvm2/upstream/current/man/lvresize.8 Mon Oct 23 08:49:10 2006
@@ -6,7 +6,7 @@
[\-\-alloc AllocationPolicy]
[\-A/\-\-autobackup y/n] [\-d/\-\-debug] [\-h/\-?/\-\-help]
[\-i/\-\-stripes Stripes [\-I/\-\-stripesize StripeSize]]
-{\-l/\-\-extents [+]LogicalExtentsNumber |
+{\-l/\-\-extents [+]LogicalExtentsNumber[%{VG|LV|FREE}] |
\-L/\-\-size [+]LogicalVolumeSize[kKmMgGtT]}
[\-t/\-\-test]
[\-v/\-\-verbose] LogicalVolumePath [PhysicalVolumePath...]
@@ -19,13 +19,20 @@
Resizing snapshot logical volumes (see
.B lvcreate(8)
for information about creating snapshots) is supported as well.
+But to change the number of copies in a mirrored logical
+volume use
+.BR lvconvert (8).
.SH OPTIONS
See \fBlvm\fP for common options.
.TP
-.I \-l, \-\-extents [+/-]LogicalExtentsNumber
+.I \-l, \-\-extents [+/-]LogicalExtentsNumber[%{VG|LV|FREE}]
Change or set the logical volume size in units of logical extents.
With the + or - sign the value is added to or subtracted from the actual size
of the logical volume and without it, the value is taken as an absolute one.
+The number can also be expressed as a percentage of the total space
+in the Volume Group with the suffix %VG or relative to the existing
+size of the Logical Volume with the suffix %LV or as a percentage of the remaining
+free space in the Volume Group with the suffix %FREE.
.TP
.I \-L, \-\-size [+/-]LogicalVolumeSize[kKmMgGtT]
Change or set the logical volume size in units of megabytes.
@@ -49,6 +56,7 @@
StripeSize must be 2^n (n = 2 to 9)
.SH SEE ALSO
.BR lvm (8),
+.BR lvconvert (8),
.BR lvcreate (8),
.BR lvreduce (8),
.BR lvchange (8)
Modified: lvm2/upstream/current/man/vgchange.8
==============================================================================
--- lvm2/upstream/current/man/vgchange.8 (original)
+++ lvm2/upstream/current/man/vgchange.8 Mon Oct 23 08:49:10 2006
@@ -9,6 +9,7 @@
.IR AllocationPolicy ]
.RB [ \-A | \-\-autobackup " {" y | n }]
.RB [ \-a | \-\-available " [e|l] {" y | n }]
+.RB [ \-\-monitor " {" y | n }]
.RB [ \-d | \-\-debug]
.RB [ \-\-deltag
.IR Tag ]
@@ -16,6 +17,8 @@
.RB [ \-\-ignorelockingfailure]
.RB [ \-l | \-\-logicalvolume
.IR MaxLogicalVolumes ]
+.RB [ -p | \-\-maxphysicalvolumes
+.IR MaxPhysicalVolumes ]
.RB [ \-P | \-\-partial]
.RB [ \-s | \-\-physicalextentsize
.IR PhysicalExtentSize [ \fBkKmMgGtT\fR ]]
@@ -57,10 +60,33 @@
Logical volumes with single-host snapshots are always activated
exclusively because they can only be used on one node at once.
.TP
+.BR \-\-monitor " " { y | n }
+Controls whether or not a mirrored logical volume is monitored by
+dmeventd, if it is installed.
+If a device used by a monitored mirror reports an I/O error,
+the failure is handled according to
+.BR mirror_image_fault_policy
+and
+.BR mirror_log_fault_policy
+set in
+.BR lvm.conf (5).
+.TP
.BR \-l ", " \-\-logicalvolume " " \fIMaxLogicalVolumes\fR
Changes the maximum logical volume number of an existing inactive
volume group.
.TP
+.BR \-p ", " \-\-maxphysicalvolumes " " \fIMaxPhysicalVolumes\fR
+Changes the maximum number of physical volumes that can belong
+to this volume group.
+For volume groups with metadata in lvm1 format, the limit is 255.
+If the metadata uses lvm2 format, the value 0
+removes this restriction: there is then no limit.
+If you have a large number of physical volumes in
+a volume group with metadata in lvm2 format,
+for tool performance reasons, you should consider
+some use of \fB--metadatacopies 0\fP
+as described in \fBpvcreate(8)\fP.
+.TP
.BR \-s ", " \-\-physicalextentsize " " \fIPhysicalExtentSize\fR[\fBkKmMgGtT\fR]
Changes the physical extent size on physical volumes of this volume group.
A size suffix (k for kilobytes up to t for terabytes) is optional, megabytes
Modified: lvm2/upstream/current/man/vgscan.8
==============================================================================
--- lvm2/upstream/current/man/vgscan.8 (original)
+++ lvm2/upstream/current/man/vgscan.8 Mon Oct 23 08:49:10 2006
@@ -11,7 +11,7 @@
.SH DESCRIPTION
vgscan scans all SCSI, (E)IDE disks, multiple devices and a bunch
of other disk devices in the system looking for LVM physical volumes
-and volume groups. Define a filter in \fBlvm.conf\fP(8) to restrict
+and volume groups. Define a filter in \fBlvm.conf\fP(5) to restrict
the scan to avoid a CD ROM, for example.
.LP
In LVM2, vgscans take place automatically; but you might still need to
Modified: lvm2/upstream/current/scripts/clvmd_init_rhel4
==============================================================================
--- lvm2/upstream/current/scripts/clvmd_init_rhel4 (original)
+++ lvm2/upstream/current/scripts/clvmd_init_rhel4 Mon Oct 23 08:49:10 2006
@@ -93,6 +93,24 @@
return $rtrn
}
+wait_for_finish()
+{
+ count=0
+
+ while [ "$count" -le 10 -a -n "`pidof clvmd`" ]
+ do
+ sleep 1
+ count=$((count + 1))
+ done
+
+ if [ `pidof clvmd` ]
+ then
+ return 1
+ else
+ return 0
+ fi
+}
+
rtrn=1
# See how we were called.
@@ -112,6 +130,7 @@
restart)
if stop
then
+ wait_for_finish
start
fi
rtrn=$?
@@ -119,9 +138,9 @@
status)
status clvmd
+ rtrn=$?
vols=$( $LVDISPLAY -C --nohead 2> /dev/null | awk '($3 ~ /....a./) {print $1}' )
echo active volumes: ${vols:-"(none)"}
- rtrn=0
;;
*)
Added: lvm2/upstream/current/scripts/lvm_dump.sh
==============================================================================
--- (empty file)
+++ lvm2/upstream/current/scripts/lvm_dump.sh Mon Oct 23 08:49:10 2006
@@ -0,0 +1,118 @@
+#!/bin/bash
+#
+# lvm_dump: This script is used to collect pertinent information for
+# the debugging of lvm issues.
+#
+
+function usage {
+ echo "$0 [options]"
+ echo " -h print this message"
+ echo " -a advanced collection - warning: if lvm is already hung,"
+ echo " then this script may hang as well if -a is used"
+ echo " -m gather LVM metadata from the PVs"
+ echo " -d dump directory to place data in (default=/tmp/lvm_dump.\$\$)"
+ echo " -c if running clvmd, gather cluster data as well"
+ echo ""
+
+ exit 1
+}
+
+advanced=0
+clustered=0
+metadata=0
+while getopts :acd:hm opt; do
+ case $opt in
+ a) advanced=1 ;;
+ c) clustered=1 ;;
+ d) lvm_dir=$OPTARG ;;
+ h) usage ;;
+ m) metadata=1 ;;
+ :) echo "$0: $OPTARG requires a value:"; usage ;;
+ \?) echo "$0: unknown option $OPTARG"; usage ;;
+ *) usage ;;
+ esac
+done
+
+dir=`mktemp -d -p /tmp lvm_dump.XXXXXX` || exit 2
+lvm_dir="$dir/lvm_dump"
+
+echo " "
+echo "Creating dump directory: $lvm_dir"
+echo " "
+
+mkdir -p $lvm_dir || exit 3
+
+if (( $advanced )); then
+ echo "Gathering LVM volume info..."
+
+ echo " vgscan..."
+ vgscan -vvvv > $lvm_dir/vgscan 2>&1
+
+ echo " pvscan..."
+ pvscan -v >> $lvm_dir/pvscan 2>/dev/null
+
+ echo " lvs..."
+ lvs -a -o +devices >> $lvm_dir/lvs 2>/dev/null
+
+ echo " pvs..."
+ pvs -a -v > $lvm_dir/pvs 2>/dev/null
+
+ echo " vgs..."
+ vgs -v > $lvm_dir/vgs 2>/dev/null
+fi
+
+if (( $clustered )); then
+ echo "Gathering cluster info..."
+ echo "STATUS: " > $lvm_dir/cluster_info
+ echo "----------------------------------" >> $lvm_dir/cluster_info
+ cman_tool status >> $lvm_dir/cluster_info
+ echo " " >> $lvm_dir/lvm_info
+
+ echo "SERVICES: " >> $lvm_dir/cluster_info
+ echo "----------------------------------" >> $lvm_dir/cluster_info
+ cman_tool services >> $lvm_dir/cluster_info
+ echo " " >> $lvm_dir/lvm_info
+fi
+
+echo "Gathering LVM & device-mapper version info..."
+echo "LVM VERSION:" > $lvm_dir/versions
+lvs --version >> $lvm_dir/versions
+echo "DEVICE MAPPER VERSION:" >> $lvm_dir/versions
+dmsetup --version >> $lvm_dir/versions
+
+echo "Gathering dmsetup info..."
+dmsetup info -c > $lvm_dir/dmsetup_info
+dmsetup table > $lvm_dir/dmsetup_table
+dmsetup status > $lvm_dir/dmsetup_status
+
+echo "Gathering process info..."
+ps alx > $lvm_dir/ps_info
+
+echo "Gathering console messages..."
+tail -n 75 /var/log/messages > $lvm_dir/messages
+
+echo "Gathering /etc/lvm info..."
+cp -a /etc/lvm $lvm_dir/lvm
+
+echo "Gathering /dev listing..."
+ls -la /dev > $lvm_dir/dev_listing
+
+if (( $metadata )); then
+ echo "Gathering LVM metadata from Physical Volumes..."
+
+ mkdir -p $lvm_dir/metadata
+
+ for pv in `pvs --noheadings -o name`
+ do
+ echo " $pv"
+ name=`basename $pv`
+ dd if=$pv of=$lvm_dir/metadata/$name bs=512 count=`pvs --noheadings --nosuffix --units s -o pe_start $pv | tr -d \ `
+ done 2>/dev/null
+fi
+
+lvm_dump=$lvm_dir.tgz
+echo "Creating tarball $lvm_dump..."
+tar czf $lvm_dump $lvm_dir 2>/dev/null
+
+exit 0
+
Modified: lvm2/upstream/current/scripts/lvmconf.sh
==============================================================================
--- lvm2/upstream/current/scripts/lvmconf.sh (original)
+++ lvm2/upstream/current/scripts/lvmconf.sh Mon Oct 23 08:49:10 2006
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
+# Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
#
# This file is part of the lvm2-cluster package.
#
@@ -21,8 +21,9 @@
echo "usage: $0 <command>"
echo ""
echo "Commands:"
- echo "Enable clvm: --enable-cluster --lockinglibdir <dir> [--lockinglib <lib>]"
+ echo "Enable clvm: --enable-cluster [--lockinglibdir <dir>] [--lockinglib <lib>]"
echo "Disable clvm: --disable-cluster"
+ echo "Set locking library: --lockinglibdir <dir> [--lockinglib <lib>]"
echo ""
echo "Global options:"
echo "Config file location: --file <configfile>"
@@ -86,14 +87,13 @@
exit 10
fi
- if [ -z "$LOCKING_TYPE" ]; then
+ if [ -z "$LOCKING_TYPE" ] && [ -z "$LOCKINGLIBDIR" ]; then
usage
exit 1
fi
- if [ "$LOCKING_TYPE" == "2" ]; then
+ if [ -n "$LOCKINGLIBDIR" ]; then
- [ -z "$LOCKINGLIBDIR" ] && usage && exit 1
[ -z "$LOCKINGLIB" ] && LOCKINGLIB="liblvm2clusterlock.so"
if [ "${LOCKINGLIBDIR:0:1}" != "/" ]
@@ -109,6 +109,10 @@
fi
fi
+
+ if [ "$LOCKING_TYPE" = "1" ] && [ -n "$LOCKINGLIBDIR" -o -n "$LOCKINGLIB" ]; then
+ echo "Superfluous locking lib parameter, ignoring"
+ fi
}
umask 0077
@@ -153,11 +157,19 @@
fi
fi
+if [ "$LOCKING_TYPE" = "2" ] && [ -z "$LOCKINGLIBDIR" ] && [ "$have_dir" = "1" ]; then
+ echo "no library_dir specified in $CONFIGFILE"
+ exit 16
+fi
+
# So if we don't have "global {" we need to create one and
# populate it
if [ "$have_global" = "1" ]
then
+ if [ -z "$LOCKING_TYPE" ]; then
+ LOCKING_TYPE=1
+ fi
if [ "$LOCKING_TYPE" = "2" ]; then
cat $CONFIGFILE - <<EOF > $TMPFILE
global {
@@ -180,14 +192,16 @@
# locking entries as appropriate
#
- if [ "$have_type" = "0" ]
- then
- SEDCMD=" s/^[[:blank:]]*locking_type[[:blank:]]*=.*/\ \ \ \ locking_type = $LOCKING_TYPE/g"
- else
- SEDCMD=" /global[[:blank:]]*{/a\ \ \ \ locking_type = $LOCKING_TYPE"
+ if [ -n "$LOCKING_TYPE" ]; then
+ if [ "$have_type" = "0" ]
+ then
+ SEDCMD=" s/^[[:blank:]]*locking_type[[:blank:]]*=.*/\ \ \ \ locking_type = $LOCKING_TYPE/g"
+ else
+ SEDCMD=" /global[[:blank:]]*{/a\ \ \ \ locking_type = $LOCKING_TYPE"
+ fi
fi
- if [ "$LOCKING_TYPE" = "2" ]; then
+ if [ -n "$LOCKINGLIBDIR" ]; then
if [ "$have_dir" = "0" ]
then
SEDCMD="${SEDCMD}\ns'^[[:blank:]]*library_dir[[:blank:]]*=.*'\ \ \ \ library_dir = \"$LOCKINGLIBDIR\"'g"
@@ -201,7 +215,9 @@
else
SEDCMD="${SEDCMD}\n/global[[:blank:]]*{/a\ \ \ \ locking_library = \"$LOCKINGLIB\""
fi
- else
+ fi
+
+ if [ "$LOCKING_TYPE" = "1" ]; then
# if we're not using cluster locking, remove the library dir and locking library name
if [ "$have_dir" = "0" ]
then
Modified: lvm2/upstream/current/tools/Makefile.in
==============================================================================
--- lvm2/upstream/current/tools/Makefile.in (original)
+++ lvm2/upstream/current/tools/Makefile.in Mon Oct 23 08:49:10 2006
@@ -80,7 +80,9 @@
LVMLIBS = -llvm
-CLEAN_TARGETS = liblvm2cmd.so liblvm2cmd.a lvm lvm.o lvm.static lvm.cflow lvm.xref lvm.tree lvm.rxref lvm.rtree
+CLEAN_TARGETS = liblvm2cmd.so liblvm2cmd.a liblvm2cmd-static.a lvm lvm.o \
+ lvm2cmd.o lvm2cmd-static.o lvm2cmdlib.o lvm.static \
+ lvm.cflow lvm.xref lvm.tree lvm.rxref lvm.rtree
ifeq ("@CMDLIB@", "yes")
TARGETS += liblvm2cmd.so
@@ -104,9 +106,13 @@
$(CC) -o $@ $(OBJECTS) lvm-static.o -static $(LDFLAGS) $(LVMLIBS) \
$(LIBS) -rdynamic
-liblvm2cmd.a: $(top_srcdir)/lib/liblvm.a $(OBJECTS)
+liblvm2cmd.a: $(top_srcdir)/lib/liblvm.a $(OBJECTS) lvmcmdlib.o lvm2cmd.o
cat $(top_srcdir)/lib/liblvm.a > $@
- $(AR) rs $@ $(OBJECTS)
+ $(AR) rs $@ $(OBJECTS) lvmcmdlib.o lvm2cmd.o
+
+liblvm2cmd-static.a: $(top_srcdir)/lib/liblvm.a $(OBJECTS) lvmcmdlib.o lvm2cmd-static.o
+ cat $(top_srcdir)/lib/liblvm.a > $@
+ $(AR) rs $@ $(OBJECTS) lvmcmdlib.o lvm2cmd-static.o
liblvm2cmd.so: liblvm2cmd.a $(LDDEPS)
@@ -141,8 +147,8 @@
$(INSTALL) -D $(OWNER) $(GROUP) -m 444 lvm2cmd.h \
$(includedir)/lvm2cmd.h
-install_cmdlib_static: liblvm2cmd.a
- $(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) liblvm2cmd.a \
+install_cmdlib_static: liblvm2cmd-static.a
+ $(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) liblvm2cmd-static.a \
$(libdir)/liblvm2cmd.a.$(LIB_VERSION)
$(LN_S) -f liblvm2cmd.a.$(LIB_VERSION) $(libdir)/liblvm2cmd.a
$(INSTALL) -D $(OWNER) $(GROUP) -m 444 lvm2cmd.h \
Modified: lvm2/upstream/current/tools/args.h
==============================================================================
--- lvm2/upstream/current/tools/args.h (original)
+++ lvm2/upstream/current/tools/args.h Mon Oct 23 08:49:10 2006
@@ -49,6 +49,7 @@
arg(corelog_ARG, '\0', "corelog", NULL)
arg(monitor_ARG, '\0', "monitor", yes_no_arg)
arg(config_ARG, '\0', "config", string_arg)
+arg(trustcache_ARG, '\0', "trustcache", NULL)
/* Allow some variations */
arg(resizable_ARG, '\0', "resizable", yes_no_arg)
@@ -83,7 +84,7 @@
arg(iop_version_ARG, 'i', "iop_version", NULL)
arg(logicalvolume_ARG, 'l', "logicalvolume", int_arg)
arg(maxlogicalvolumes_ARG, 'l', "maxlogicalvolumes", int_arg)
-arg(extents_ARG, 'l', "extents", int_arg_with_sign)
+arg(extents_ARG, 'l', "extents", int_arg_with_sign_and_percent)
arg(lvmpartition_ARG, 'l', "lvmpartition", NULL)
arg(list_ARG, 'l', "list", NULL)
arg(size_ARG, 'L', "size", size_mb_arg)
Modified: lvm2/upstream/current/tools/commands.h
==============================================================================
--- lvm2/upstream/current/tools/commands.h (original)
+++ lvm2/upstream/current/tools/commands.h Mon Oct 23 08:49:10 2006
@@ -83,6 +83,7 @@
"Change logical volume layout",
"lvconvert "
"[-m|--mirrors Mirrors [--corelog]]\n"
+ "\t[-R|--regionsize MirrorLogRegionSize]\n"
"\t[--alloc AllocationPolicy]\n"
"\t[-d|--debug]\n"
"\t[-h|-?|--help]\n"
@@ -100,7 +101,7 @@
"\t[--version]" "\n"
"\tOriginalLogicalVolume[Path] SnapshotLogicalVolume[Path]\n",
- alloc_ARG, chunksize_ARG, mirrors_ARG, corelog_ARG,
+ alloc_ARG, chunksize_ARG, mirrors_ARG, corelog_ARG, regionsize_ARG,
snapshot_ARG, test_ARG, zero_ARG)
xx(lvcreate,
@@ -137,7 +138,7 @@
"\t[-d|--debug]\n"
"\t[-h|-?|--help]\n"
"\t[-i|--stripes Stripes [-I|--stripesize StripeSize]]\n"
- "\t{-l|--extents LogicalExtentsNumber |\n"
+ "\t{-l|--extents LogicalExtentsNumber[%{VG|LV|FREE}] |\n"
"\t -L|--size LogicalVolumeSize[kKmMgGtT]}\n"
"\t[-M|--persistent {y|n}] [--major major] [--minor minor]\n"
"\t[-n|--name LogicalVolumeName]\n"
@@ -202,7 +203,7 @@
"\t[-d|--debug]\n"
"\t[-h|--help]\n"
"\t[-i|--stripes Stripes [-I|--stripesize StripeSize]]\n"
- "\t{-l|--extents [+]LogicalExtentsNumber |\n"
+ "\t{-l|--extents [+]LogicalExtentsNumber[%{VG|FREE}] |\n"
"\t -L|--size [+]LogicalVolumeSize[kKmMgGtT]}\n"
"\t[-m|--mirrors Mirrors]\n"
"\t[-n|--nofsck]\n"
@@ -267,7 +268,7 @@
"\t[-d|--debug]\n"
"\t[-f|--force]\n"
"\t[-h|--help]\n"
- "\t{-l|--extents [-]LogicalExtentsNumber |\n"
+ "\t{-l|--extents [-]LogicalExtentsNumber[%{VG|LV|FREE}] |\n"
"\t -L|--size [-]LogicalVolumeSize[kKmMgGtT]}\n"
"\t[-n|--nofsck]\n"
"\t[-r|--resizefs]\n"
@@ -315,7 +316,7 @@
"\t[-d|--debug]\n"
"\t[-h|--help]\n"
"\t[-i|--stripes Stripes [-I|--stripesize StripeSize]]\n"
- "\t{-l|--extents [+|-]LogicalExtentsNumber |\n"
+ "\t{-l|--extents [+|-]LogicalExtentsNumber[%{VG|LV|FREE}] |\n"
"\t -L|--size [+|-]LogicalVolumeSize[kKmMgGtT]}\n"
"\t[-n|--nofsck]\n"
"\t[-r|--resizefs]\n"
@@ -343,6 +344,7 @@
"\t[-P|--partial] " "\n"
"\t[--segments]\n"
"\t[--separator Separator]\n"
+ "\t[--trustcache]\n"
"\t[--unbuffered]\n"
"\t[--units hsbkmgtHKMGT]\n"
"\t[-v|--verbose]\n"
@@ -351,7 +353,7 @@
aligned_ARG, all_ARG, ignorelockingfailure_ARG, noheadings_ARG,
nolocking_ARG, nosuffix_ARG, options_ARG, partial_ARG, segments_ARG,
- separator_ARG, sort_ARG, unbuffered_ARG, units_ARG)
+ separator_ARG, sort_ARG, trustcache_ARG, unbuffered_ARG, units_ARG)
xx(lvscan,
"List all logical volumes in all volume groups",
@@ -527,6 +529,7 @@
"\t[-P|--partial] " "\n"
"\t[--segments]\n"
"\t[--separator Separator]\n"
+ "\t[--trustcache]\n"
"\t[--unbuffered]\n"
"\t[--units hsbkmgtHKMGT]\n"
"\t[-v|--verbose]\n"
@@ -535,7 +538,7 @@
aligned_ARG, all_ARG, ignorelockingfailure_ARG, noheadings_ARG,
nolocking_ARG, nosuffix_ARG, options_ARG, partial_ARG, segments_ARG,
- separator_ARG, sort_ARG, unbuffered_ARG, units_ARG)
+ separator_ARG, sort_ARG, trustcache_ARG, unbuffered_ARG, units_ARG)
xx(pvscan,
"List all physical volumes",
@@ -605,6 +608,7 @@
"\t -c|--clustered {y|n} |" "\n"
"\t -x|--resizeable {y|n} |" "\n"
"\t -l|--logicalvolume MaxLogicalVolumes |" "\n"
+ "\t -p|--maxphysicalvolumes MaxPhysicalVolumes |" "\n"
"\t -s|--physicalextentsize PhysicalExtentSize[kKmMgGtT] |" "\n"
"\t --addtag Tag |\n"
"\t --deltag Tag}\n"
@@ -612,8 +616,8 @@
addtag_ARG, alloc_ARG, allocation_ARG, autobackup_ARG, available_ARG,
clustered_ARG, deltag_ARG, ignorelockingfailure_ARG, logicalvolume_ARG,
- monitor_ARG, partial_ARG, physicalextentsize_ARG, resizeable_ARG,
- resizable_ARG, test_ARG, uuid_ARG)
+ maxphysicalvolumes_ARG, monitor_ARG, partial_ARG, physicalextentsize_ARG,
+ resizeable_ARG, resizable_ARG, test_ARG, uuid_ARG)
xx(vgck,
"Check the consistency of volume group(s)",
@@ -819,6 +823,7 @@
"\t[-O|--sort [+|-]key1[,[+|-]key2[,...]]]\n"
"\t[-P|--partial] " "\n"
"\t[--separator Separator]\n"
+ "\t[--trustcache]\n"
"\t[--unbuffered]\n"
"\t[--units hsbkmgtHKMGT]\n"
"\t[-v|--verbose]\n"
@@ -827,7 +832,7 @@
aligned_ARG, all_ARG, ignorelockingfailure_ARG, noheadings_ARG,
nolocking_ARG, nosuffix_ARG, options_ARG, partial_ARG, separator_ARG,
- sort_ARG, unbuffered_ARG, units_ARG)
+ sort_ARG, trustcache_ARG, unbuffered_ARG, units_ARG)
xx(vgscan,
"Search for all volume groups",
Modified: lvm2/upstream/current/tools/lvchange.c
==============================================================================
--- lvm2/upstream/current/tools/lvchange.c (original)
+++ lvm2/upstream/current/tools/lvchange.c Mon Oct 23 08:49:10 2006
@@ -294,16 +294,15 @@
log_error("Major number must be specified with -My");
return 0;
}
- if (lv_info(cmd, lv, &info, 0) && info.exists &&
- !arg_count(cmd, force_ARG)) {
- if (yes_no_prompt("Logical volume %s will be "
- "deactivated temporarily. "
- "Continue? [y/n]: ", lv->name) == 'n') {
- log_print("%s device number not changed.",
- lv->name);
- return 0;
- }
+ if (lv_info(cmd, lv, &info, 0) && info.exists)
active = 1;
+ if (active && !arg_count(cmd, force_ARG) &&
+ yes_no_prompt("Logical volume %s will be "
+ "deactivated temporarily. "
+ "Continue? [y/n]: ", lv->name) == 'n') {
+ log_print("%s device number not changed.",
+ lv->name);
+ return 0;
}
log_verbose("Ensuring %s is inactive.", lv->name);
if (!deactivate_lv(cmd, lv)) {
Modified: lvm2/upstream/current/tools/lvconvert.c
==============================================================================
--- lvm2/upstream/current/tools/lvconvert.c (original)
+++ lvm2/upstream/current/tools/lvconvert.c Mon Oct 23 08:49:10 2006
@@ -102,7 +102,7 @@
int argc, char **argv)
{
int region_size;
- int pagesize = getpagesize();
+ int pagesize = lvm_getpagesize();
memset(lp, 0, sizeof(*lp));
@@ -344,8 +344,7 @@
lp->mirrors - 1);
return 1;
}
- }
- if (lp->mirrors > existing_mirrors) {
+ } else if (lp->mirrors > existing_mirrors) {
/* FIXME Unless anywhere, remove PV of log_lv
* from allocatable_pvs & allocate
* (mirrors - existing_mirrors) new areas
@@ -565,6 +564,12 @@
goto error;
}
+ if ((vg->status & CLUSTERED) && !locking_is_clustered() &&
+ !lockingfailed()) {
+ log_error("Skipping clustered volume group %s", lp.vg_name);
+ goto error;
+ }
+
if (vg->status & EXPORTED_VG) {
log_error("Volume group \"%s\" is exported", lp.vg_name);
goto error;
Modified: lvm2/upstream/current/tools/lvcreate.c
==============================================================================
--- lvm2/upstream/current/tools/lvcreate.c (original)
+++ lvm2/upstream/current/tools/lvcreate.c Mon Oct 23 08:49:10 2006
@@ -43,6 +43,7 @@
/* size */
uint32_t extents;
uint64_t size;
+ percent_t percent;
uint32_t permission;
uint32_t read_ahead;
@@ -94,19 +95,7 @@
}
} else {
- vg_name = argv[0];
- /* Strip dev_dir (optional) */
- if (*vg_name == '/') {
- while (*vg_name == '/')
- vg_name++;
- vg_name--;
- }
- if (!strncmp(vg_name, cmd->dev_dir,
- strlen(cmd->dev_dir))) {
- vg_name += strlen(cmd->dev_dir);
- while (*vg_name == '/')
- vg_name++;
- }
+ vg_name = skip_dev_dir(cmd, argv[0]);
if (strrchr(vg_name, '/')) {
log_error("Volume group name expected "
"(no slash)");
@@ -169,6 +158,7 @@
return 0;
}
lp->extents = arg_uint_value(cmd, extents_ARG, 0);
+ lp->percent = arg_percent_value(cmd, extents_ARG, PERCENT_NONE);
}
/* Size returned in kilobyte units; held in sectors */
@@ -178,6 +168,7 @@
return 0;
}
lp->size = arg_uint64_value(cmd, size_ARG, UINT64_C(0)) * 2;
+ lp->percent = PERCENT_NONE;
}
return 1;
@@ -249,7 +240,7 @@
{
int argc = *pargc;
int region_size;
- int pagesize = getpagesize();
+ int pagesize = lvm_getpagesize();
if (argc && (unsigned) argc < lp->mirrors) {
log_error("Too few physical volumes on "
@@ -498,6 +489,12 @@
return 0;
}
+ if ((vg->status & CLUSTERED) && !locking_is_clustered() &&
+ !lockingfailed()) {
+ log_error("Skipping clustered volume group %s", lp->vg_name);
+ return 0;
+ }
+
if (vg->status & EXPORTED_VG) {
log_error("Volume group \"%s\" is exported", lp->vg_name);
return 0;
@@ -562,6 +559,20 @@
lp->extents = tmp_size / vg->extent_size;
}
+ switch(lp->percent) {
+ case PERCENT_VG:
+ lp->extents = lp->extents * vg->extent_count / 100;
+ break;
+ case PERCENT_FREE:
+ lp->extents = lp->extents * vg->free_count / 100;
+ break;
+ case PERCENT_LV:
+ log_error("Please express size as %%VG or %%FREE.");
+ return 0;
+ case PERCENT_NONE:
+ break;
+ }
+
if ((size_rest = lp->extents % lp->stripes)) {
log_print("Rounding size (%d extents) up to stripe boundary "
"size (%d extents)", lp->extents,
Added: lvm2/upstream/current/tools/lvm2cmd-static.c
==============================================================================
--- (empty file)
+++ lvm2/upstream/current/tools/lvm2cmd-static.c Mon Oct 23 08:49:10 2006
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2006 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "lvm2cmdline.h"
+#include "lvm2cmd.h"
+
+void *lvm2_init(void)
+{
+ return cmdlib_lvm2_init(1);
+}
Added: lvm2/upstream/current/tools/lvm2cmd.c
==============================================================================
--- (empty file)
+++ lvm2/upstream/current/tools/lvm2cmd.c Mon Oct 23 08:49:10 2006
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2006 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "lvm2cmdline.h"
+#include "lvm2cmd.h"
+
+void *lvm2_init(void)
+{
+ return cmdlib_lvm2_init(0);
+}
Modified: lvm2/upstream/current/tools/lvm2cmdline.h
==============================================================================
--- lvm2/upstream/current/tools/lvm2cmdline.h (original)
+++ lvm2/upstream/current/tools/lvm2cmdline.h Mon Oct 23 08:49:10 2006
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -16,6 +16,16 @@
#ifndef _LVM_CMDLINE_H
#define _LVM_CMDLINE_H
-int lvm2_main(int argc, char **argv, int is_static);
+struct cmd_context;
+
+int lvm2_main(int argc, char **argv, unsigned is_static);
+
+void *cmdlib_lvm2_init(unsigned is_static);
+void lvm_fin(struct cmd_context *cmd);
+
+struct cmd_context *init_lvm(unsigned is_static);
+void lvm_register_commands(void);
+int lvm_split(char *str, int *argc, char **argv, int max);
+int lvm_run_command(struct cmd_context *cmd, int argc, char **argv);
#endif
Added: lvm2/upstream/current/tools/lvmcmdlib.c
==============================================================================
--- (empty file)
+++ lvm2/upstream/current/tools/lvmcmdlib.c Mon Oct 23 08:49:10 2006
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
+ * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "tools.h"
+#include "lvm2cmdline.h"
+#include "label.h"
+#include "version.h"
+
+#include "lvm2cmd.h"
+
+#include <signal.h>
+#include <syslog.h>
+#include <libgen.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <sys/resource.h>
+
+void *cmdlib_lvm2_init(unsigned is_static)
+{
+ struct cmd_context *cmd;
+
+ lvm_register_commands();
+
+ if (!(cmd = init_lvm(is_static)))
+ return NULL;
+
+ return (void *) cmd;
+}
+
+int lvm2_run(void *handle, const char *cmdline)
+{
+ int argc, ret, oneoff = 0;
+ char *args[MAX_ARGS], **argv, *cmdcopy = NULL;
+ struct cmd_context *cmd;
+
+ argv = args;
+
+ if (!handle) {
+ oneoff = 1;
+ if (!(handle = lvm2_init())) {
+ log_error("Handle initialisation failed.");
+ return ECMD_FAILED;
+ }
+ }
+
+ cmd = (struct cmd_context *) handle;
+
+ cmd->argv = argv;
+
+ if (!(cmdcopy = dm_strdup(cmdline))) {
+ log_error("Cmdline copy failed.");
+ ret = ECMD_FAILED;
+ goto out;
+ }
+
+ if (lvm_split(cmdcopy, &argc, argv, MAX_ARGS) == MAX_ARGS) {
+ log_error("Too many arguments. Limit is %d.", MAX_ARGS);
+ ret = EINVALID_CMD_LINE;
+ goto out;
+ }
+
+ if (!argc) {
+ log_error("No command supplied");
+ ret = EINVALID_CMD_LINE;
+ goto out;
+ }
+
+ ret = lvm_run_command(cmd, argc, argv);
+
+ out:
+ dm_free(cmdcopy);
+
+ if (oneoff)
+ lvm2_exit(handle);
+
+ return ret;
+}
+
+void lvm2_log_level(void *handle, int level)
+{
+ struct cmd_context *cmd = (struct cmd_context *) handle;
+
+ cmd->default_settings.verbose = level - VERBOSE_BASE_LEVEL;
+
+ return;
+}
+
+void lvm2_log_fn(lvm2_log_fn_t log_fn)
+{
+ init_log_fn(log_fn);
+}
+
+void lvm2_exit(void *handle)
+{
+ struct cmd_context *cmd = (struct cmd_context *) handle;
+
+ lvm_fin(cmd);
+}
Modified: lvm2/upstream/current/tools/lvmcmdline.c
==============================================================================
--- lvm2/upstream/current/tools/lvmcmdline.c (original)
+++ lvm2/upstream/current/tools/lvmcmdline.c Mon Oct 23 08:49:10 2006
@@ -54,7 +54,7 @@
*/
struct arg the_args[ARG_COUNT + 1] = {
-#define arg(a, b, c, d) {b, "", "--" c, d, 0, NULL, 0, 0, INT64_C(0), UINT64_C(0), 0, NULL},
+#define arg(a, b, c, d) {b, "", "--" c, d, 0, NULL, 0, 0, INT64_C(0), UINT64_C(0), SIGN_NONE, PERCENT_NONE, NULL},
#include "args.h"
#undef arg
@@ -69,6 +69,7 @@
int yes_no_arg(struct cmd_context *cmd __attribute((unused)), struct arg *a)
{
a->sign = SIGN_NONE;
+ a->percent = PERCENT_NONE;
if (!strcmp(a->value, "y")) {
a->i_value = 1;
@@ -90,6 +91,7 @@
struct arg *a)
{
a->sign = SIGN_NONE;
+ a->percent = PERCENT_NONE;
if (!strcmp(a->value, "e") || !strcmp(a->value, "ey") ||
!strcmp(a->value, "ye")) {
@@ -148,6 +150,8 @@
char *val;
long v;
+ a->percent = PERCENT_NONE;
+
val = a->value;
switch (*val) {
case '+':
@@ -186,6 +190,8 @@
char *val;
double v;
+ a->percent = PERCENT_NONE;
+
val = a->value;
switch (*val) {
case '+':
@@ -259,6 +265,33 @@
return 1;
}
+int int_arg_with_sign_and_percent(struct cmd_context *cmd __attribute((unused)),
+ struct arg *a)
+{
+ char *ptr;
+
+ if (!_get_int_arg(a, &ptr))
+ return 0;
+
+ if (!*ptr)
+ return 1;
+
+ if (*ptr++ != '%')
+ return 0;
+
+ if (!strcasecmp(ptr, "V") || !strcasecmp(ptr, "VG"))
+ a->percent = PERCENT_VG;
+ else if (!strcasecmp(ptr, "L") || !strcasecmp(ptr, "LV"))
+ a->percent = PERCENT_LV;
+ else if (!strcasecmp(ptr, "F") || !strcasecmp(ptr, "FR") ||
+ !strcasecmp(ptr, "FREE"))
+ a->percent = PERCENT_FREE;
+ else
+ return 0;
+
+ return 1;
+}
+
int minor_arg(struct cmd_context *cmd __attribute((unused)), struct arg *a)
{
char *ptr;
@@ -443,7 +476,7 @@
_create_new_command(name, fn, desc, usagestr, nargs, args);
}
-static void _register_commands()
+void lvm_register_commands(void)
{
#define xx(a, b, c...) _register_command(# a, a, b, ## c, \
driverloaded_ARG, \
@@ -707,6 +740,17 @@
return EINVALID_CMD_LINE;
}
+ if (arg_count(cmd, trustcache_ARG)) {
+ if (arg_count(cmd, all_ARG)) {
+ log_error("--trustcache is incompatible with --all");
+ return EINVALID_CMD_LINE;
+ }
+ init_trust_cache(1);
+ log_print("WARNING: Cache file of PVs will be trusted. "
+ "New devices holding PVs may get ignored.");
+ } else
+ init_trust_cache(0);
+
/* Handle synonyms */
if (!_merge_synonym(cmd, resizable_ARG, resizeable_ARG) ||
!_merge_synonym(cmd, allocation_ARG, allocatable_ARG) ||
@@ -832,7 +876,7 @@
return NULL;
}
-static int _run_command(struct cmd_context *cmd, int argc, char **argv)
+int lvm_run_command(struct cmd_context *cmd, int argc, char **argv)
{
int ret = 0;
int locking_type;
@@ -925,7 +969,7 @@
return ret;
}
-static int _split(char *str, int *argc, char **argv, int max)
+int lvm_split(char *str, int *argc, char **argv, int max)
{
char *b = str, *e;
*argc = 0;
@@ -984,11 +1028,11 @@
}
}
-static struct cmd_context *_init_lvm(void)
+struct cmd_context *init_lvm(unsigned is_static)
{
struct cmd_context *cmd;
- if (!(cmd = create_toolcontext(&the_args[0]))) {
+ if (!(cmd = create_toolcontext(&the_args[0], is_static))) {
stack;
return NULL;
}
@@ -1010,7 +1054,7 @@
dm_free(_commands);
}
-static void _fin(struct cmd_context *cmd)
+void lvm_fin(struct cmd_context *cmd)
{
_fin_commands();
destroy_toolcontext(cmd);
@@ -1044,7 +1088,7 @@
ret = EINVALID_CMD_LINE;
break;
}
- if (_split(buffer, &argc, argv, MAX_ARGS) == MAX_ARGS) {
+ if (lvm_split(buffer, &argc, argv, MAX_ARGS) == MAX_ARGS) {
buffer[50] = '\0';
log_error("Too many arguments: %s", buffer);
ret = EINVALID_CMD_LINE;
@@ -1054,7 +1098,7 @@
continue;
if (!strcmp(argv[0], "quit") || !strcmp(argv[0], "exit"))
break;
- _run_command(cmd, argc, argv);
+ lvm_run_command(cmd, argc, argv);
}
fclose(script);
@@ -1177,7 +1221,7 @@
{
char *e = getenv("HOME");
- if (lvm_snprintf(buffer, size, "%s/.lvm_history", e) < 0) {
+ if (dm_snprintf(buffer, size, "%s/.lvm_history", e) < 0) {
log_error("$HOME/.lvm_history: path too long");
return 0;
}
@@ -1240,7 +1284,7 @@
argv = args;
- if (_split(input, &argc, argv, MAX_ARGS) == MAX_ARGS) {
+ if (lvm_split(input, &argc, argv, MAX_ARGS) == MAX_ARGS) {
log_error("Too many arguments, sorry.");
continue;
}
@@ -1259,7 +1303,7 @@
break;
}
- ret = _run_command(cmd, argc, argv);
+ ret = lvm_run_command(cmd, argc, argv);
if (ret == ENO_SUCH_CMD)
log_error("No such command '%s'. Try 'help'.",
argv[0]);
@@ -1273,92 +1317,6 @@
#endif
-#ifdef CMDLIB
-
-void *lvm2_init(void)
-{
- struct cmd_context *cmd;
-
- _register_commands();
-
- if (!(cmd = _init_lvm()))
- return NULL;
-
- return (void *) cmd;
-}
-
-int lvm2_run(void *handle, const char *cmdline)
-{
- int argc, ret, oneoff = 0;
- char *args[MAX_ARGS], **argv, *cmdcopy = NULL;
- struct cmd_context *cmd;
-
- argv = args;
-
- if (!handle) {
- oneoff = 1;
- if (!(handle = lvm2_init())) {
- log_error("Handle initialisation failed.");
- return ECMD_FAILED;
- }
- }
-
- cmd = (struct cmd_context *) handle;
-
- cmd->argv = argv;
-
- if (!(cmdcopy = dm_strdup(cmdline))) {
- log_error("Cmdline copy failed.");
- ret = ECMD_FAILED;
- goto out;
- }
-
- if (_split(cmdcopy, &argc, argv, MAX_ARGS) == MAX_ARGS) {
- log_error("Too many arguments. Limit is %d.", MAX_ARGS);
- ret = EINVALID_CMD_LINE;
- goto out;
- }
-
- if (!argc) {
- log_error("No command supplied");
- ret = EINVALID_CMD_LINE;
- goto out;
- }
-
- ret = _run_command(cmd, argc, argv);
-
- out:
- dm_free(cmdcopy);
-
- if (oneoff)
- lvm2_exit(handle);
-
- return ret;
-}
-
-void lvm2_log_level(void *handle, int level)
-{
- struct cmd_context *cmd = (struct cmd_context *) handle;
-
- cmd->default_settings.verbose = level - VERBOSE_BASE_LEVEL;
-
- return;
-}
-
-void lvm2_log_fn(lvm2_log_fn_t log_fn)
-{
- init_log_fn(log_fn);
-}
-
-void lvm2_exit(void *handle)
-{
- struct cmd_context *cmd = (struct cmd_context *) handle;
-
- _fin(cmd);
-}
-
-#endif
-
/*
* Determine whether we should fall back and exec the equivalent LVM1 tool
*/
@@ -1386,7 +1344,7 @@
{
char path[PATH_MAX];
- if (lvm_snprintf(path, sizeof(path), "%s.lvm1", argv[0]) < 0) {
+ if (dm_snprintf(path, sizeof(path), "%s.lvm1", argv[0]) < 0) {
log_error("Failed to create LVM1 tool pathname");
return;
}
@@ -1395,7 +1353,7 @@
log_sys_error("execvp", path);
}
-int lvm2_main(int argc, char **argv, int is_static)
+int lvm2_main(int argc, char **argv, unsigned is_static)
{
char *namebase, *base;
int ret, alias = 0;
@@ -1421,11 +1379,11 @@
free(namebase);
- if (!(cmd = _init_lvm()))
+ if (!(cmd = init_lvm(is_static)))
return -1;
cmd->argv = argv;
- _register_commands();
+ lvm_register_commands();
if (_lvm1_fallback(cmd)) {
/* Attempt to run equivalent LVM1 tool instead */
@@ -1461,14 +1419,14 @@
argv++;
}
- ret = _run_command(cmd, argc, argv);
+ ret = lvm_run_command(cmd, argc, argv);
if ((ret == ENO_SUCH_CMD) && (!alias))
ret = _run_script(cmd, argc, argv);
if (ret == ENO_SUCH_CMD)
log_error("No such command. Try 'help'.");
out:
- _fin(cmd);
+ lvm_fin(cmd);
if (ret == ECMD_PROCESSED)
ret = 0;
return ret;
Modified: lvm2/upstream/current/tools/lvrename.c
==============================================================================
--- lvm2/upstream/current/tools/lvrename.c (original)
+++ lvm2/upstream/current/tools/lvrename.c Mon Oct 23 08:49:10 2006
@@ -29,9 +29,7 @@
struct lv_list *lvl;
if (argc == 3) {
- vg_name = argv[0];
- if (!strncmp(vg_name, cmd->dev_dir, strlen(cmd->dev_dir)))
- vg_name += strlen(cmd->dev_dir);
+ vg_name = skip_dev_dir(cmd, argv[0]);
lv_name_old = argv[1];
lv_name_new = argv[2];
if (strchr(lv_name_old, '/') &&
@@ -111,6 +109,12 @@
goto error;
}
+ if ((vg->status & CLUSTERED) && !locking_is_clustered() &&
+ !lockingfailed()) {
+ log_error("Skipping clustered volume group %s", vg->name);
+ goto error;
+ }
+
if (vg->status & EXPORTED_VG) {
log_error("Volume group \"%s\" is exported", vg->name);
goto error;
@@ -140,6 +144,14 @@
goto error;
}
+ if ((lv->status & MIRRORED) ||
+ (lv->status & MIRROR_LOG) ||
+ (lv->status & MIRROR_IMAGE)) {
+ log_error("Mirrored LV, \"%s\" cannot be renamed: %s",
+ lv->name, strerror(ENOSYS));
+ goto error;
+ }
+
if (!archive(lv->vg)) {
stack;
goto error;
Modified: lvm2/upstream/current/tools/lvresize.c
==============================================================================
--- lvm2/upstream/current/tools/lvresize.c (original)
+++ lvm2/upstream/current/tools/lvresize.c Mon Oct 23 08:49:10 2006
@@ -31,6 +31,7 @@
uint32_t extents;
uint64_t size;
sign_t sign;
+ percent_t percent;
enum {
LV_ANY = 0,
@@ -68,12 +69,14 @@
if (arg_count(cmd, extents_ARG)) {
lp->extents = arg_uint_value(cmd, extents_ARG, 0);
lp->sign = arg_sign_value(cmd, extents_ARG, SIGN_NONE);
+ lp->percent = arg_percent_value(cmd, extents_ARG, PERCENT_NONE);
}
/* Size returned in kilobyte units; held in sectors */
if (arg_count(cmd, size_ARG)) {
lp->size = arg_uint64_value(cmd, size_ARG, UINT64_C(0)) * 2;
lp->sign = arg_sign_value(cmd, size_ARG, SIGN_NONE);
+ lp->percent = PERCENT_NONE;
}
if (lp->resize == LV_EXTEND && lp->sign == SIGN_MINUS) {
@@ -138,6 +141,12 @@
return ECMD_FAILED;
}
+ if ((vg->status & CLUSTERED) && !locking_is_clustered() &&
+ !lockingfailed()) {
+ log_error("Skipping clustered volume group %s", vg->name);
+ return ECMD_FAILED;
+ }
+
if (vg->status & EXPORTED_VG) {
log_error("Volume group %s is exported", vg->name);
return ECMD_FAILED;
@@ -232,6 +241,20 @@
lp->extents = lp->size / vg->extent_size;
}
+ switch(lp->percent) {
+ case PERCENT_VG:
+ lp->extents = lp->extents * vg->extent_count / 100;
+ break;
+ case PERCENT_FREE:
+ lp->extents = lp->extents * vg->free_count / 100;
+ break;
+ case PERCENT_LV:
+ lp->extents = lp->extents * lv->le_count / 100;
+ break;
+ case PERCENT_NONE:
+ break;
+ }
+
if (lp->sign == SIGN_PLUS)
lp->extents += lv->le_count;
@@ -480,14 +503,14 @@
}
if (lp->resizefs) {
- if (lvm_snprintf(lv_path, PATH_MAX, "%s%s/%s", cmd->dev_dir,
+ if (dm_snprintf(lv_path, PATH_MAX, "%s%s/%s", cmd->dev_dir,
lp->vg_name, lp->lv_name) < 0) {
log_error("Couldn't create LV path for %s",
lp->lv_name);
return ECMD_FAILED;
}
- if (lvm_snprintf(size_buf, SIZE_BUF, "%" PRIu64,
+ if (dm_snprintf(size_buf, SIZE_BUF, "%" PRIu64,
(uint64_t) lp->extents * vg->extent_size / 2)
< 0) {
log_error("Couldn't generate new LV size string");
Modified: lvm2/upstream/current/tools/pvchange.c
==============================================================================
--- lvm2/upstream/current/tools/pvchange.c (original)
+++ lvm2/upstream/current/tools/pvchange.c Mon Oct 23 08:49:10 2006
@@ -67,6 +67,12 @@
return 0;
}
+ if ((vg->status & CLUSTERED) && !locking_is_clustered() &&
+ !lockingfailed()) {
+ log_error("Skipping clustered volume group %s", vg->name);
+ return 0;
+ }
+
if (vg->status & EXPORTED_VG) {
unlock_vg(cmd, pv->vg_name);
log_error("Volume group \"%s\" is exported", vg->name);
Modified: lvm2/upstream/current/tools/pvdisplay.c
==============================================================================
--- lvm2/upstream/current/tools/pvdisplay.c (original)
+++ lvm2/upstream/current/tools/pvdisplay.c Mon Oct 23 08:49:10 2006
@@ -19,10 +19,32 @@
struct volume_group *vg __attribute((unused)),
struct physical_volume *pv, void *handle)
{
+ int consistent = 0;
+ int ret = ECMD_PROCESSED;
uint64_t size;
const char *pv_name = dev_name(pv->dev);
+ if (pv->vg_name) {
+ if (!lock_vol(cmd, pv->vg_name, LCK_VG_READ)) {
+ log_error("Can't lock %s: skipping", pv->vg_name);
+ return ECMD_FAILED;
+ }
+
+ if (!(vg = vg_read(cmd, pv->vg_name, (char *)&pv->vgid, &consistent))) {
+ log_error("Can't read %s: skipping", pv->vg_name);
+ goto out;
+ }
+
+ if ((vg->status & CLUSTERED) && !locking_is_clustered() &&
+ !lockingfailed()) {
+ log_error("Skipping clustered volume group %s",
+ vg->name);
+ ret = ECMD_FAILED;
+ goto out;
+ }
+ }
+
if (!*pv->vg_name)
size = pv->size;
else
@@ -31,7 +53,7 @@
if (arg_count(cmd, short_ARG)) {
log_print("Device \"%s\" has a capacity of %s", pv_name,
display_size(cmd, size));
- return ECMD_PROCESSED;
+ goto out;
}
if (pv->status & EXPORTED_VG)
@@ -44,15 +66,19 @@
if (arg_count(cmd, colon_ARG)) {
pvdisplay_colons(pv);
- return ECMD_PROCESSED;
+ goto out;
}
pvdisplay_full(cmd, pv, handle);
if (!arg_count(cmd, maps_ARG))
- return ECMD_PROCESSED;
+ goto out;
+
+out:
+ if (pv->vg_name)
+ unlock_vg(cmd, pv->vg_name);
- return ECMD_PROCESSED;
+ return ret;
}
int pvdisplay(struct cmd_context *cmd, int argc, char **argv)
Modified: lvm2/upstream/current/tools/pvmove.c
==============================================================================
--- lvm2/upstream/current/tools/pvmove.c (original)
+++ lvm2/upstream/current/tools/pvmove.c Mon Oct 23 08:49:10 2006
@@ -27,9 +27,7 @@
if (!strchr(arg, '/'))
return arg;
- lvname = arg;
- if (!strncmp(lvname, cmd->dev_dir, strlen(cmd->dev_dir)))
- lvname += strlen(cmd->dev_dir);
+ lvname = skip_dev_dir(cmd, arg);
while (*lvname == '/')
lvname++;
if (!strchr(lvname, '/')) {
@@ -68,6 +66,12 @@
return NULL;
}
+ if ((vg->status & CLUSTERED) && !locking_is_clustered() &&
+ !lockingfailed()) {
+ log_error("Skipping clustered volume group %s", vgname);
+ return NULL;
+ }
+
if (vg->status & EXPORTED_VG) {
log_error("Volume group \"%s\" is exported", vgname);
unlock_vg(cmd, vgname);
Modified: lvm2/upstream/current/tools/pvresize.c
==============================================================================
--- lvm2/upstream/current/tools/pvresize.c (original)
+++ lvm2/upstream/current/tools/pvresize.c Mon Oct 23 08:49:10 2006
@@ -77,6 +77,13 @@
return ECMD_FAILED;
}
+ if ((vg->status & CLUSTERED) && !locking_is_clustered() &&
+ !lockingfailed()) {
+ unlock_vg(cmd, vg_name);
+ log_error("Skipping clustered volume group %s", vg->name);
+ return ECMD_FAILED;
+ }
+
if (vg->status & EXPORTED_VG) {
unlock_vg(cmd, vg_name);
log_error("Volume group \"%s\" is exported", vg->name);
Modified: lvm2/upstream/current/tools/reporter.c
==============================================================================
--- lvm2/upstream/current/tools/reporter.c (original)
+++ lvm2/upstream/current/tools/reporter.c Mon Oct 23 08:49:10 2006
@@ -68,13 +68,20 @@
if (!(vg = vg_read(cmd, pv->vg_name, NULL, &consistent))) {
log_error("Can't read %s: skipping", pv->vg_name);
- unlock_vg(cmd, pv->vg_name);
- return ECMD_FAILED;
+ goto out;
+ }
+
+ if ((vg->status & CLUSTERED) && !locking_is_clustered() &&
+ !lockingfailed()) {
+ log_error("Skipping clustered volume group %s", vg->name);
+ ret = ECMD_FAILED;
+ goto out;
}
if (!report_object(handle, vg, NULL, pv, NULL, pvseg))
ret = ECMD_FAILED;
+out:
unlock_vg(cmd, pv->vg_name);
return ret;
}
@@ -109,14 +116,22 @@
if (!(vg = vg_read(cmd, pv->vg_name, (char *)&pv->vgid, &consistent))) {
log_error("Can't read %s: skipping", pv->vg_name);
- unlock_vg(cmd, pv->vg_name);
- return ECMD_FAILED;
+ goto out;
+ }
+
+ if ((vg->status & CLUSTERED) && !locking_is_clustered() &&
+ !lockingfailed()) {
+ log_error("Skipping clustered volume group %s",
+ vg->name);
+ ret = ECMD_FAILED;
+ goto out;
}
}
if (!report_object(handle, vg, NULL, pv, NULL, NULL))
ret = ECMD_FAILED;
+out:
if (pv->vg_name)
unlock_vg(cmd, pv->vg_name);
Modified: lvm2/upstream/current/tools/toollib.c
==============================================================================
--- lvm2/upstream/current/tools/toollib.c (original)
+++ lvm2/upstream/current/tools/toollib.c Mon Oct 23 08:49:10 2006
@@ -70,6 +70,11 @@
return arg_count(cmd, a) ? cmd->args[a].sign : def;
}
+percent_t arg_percent_value(struct cmd_context *cmd, int a, const percent_t def)
+{
+ return arg_count(cmd, a) ? cmd->args[a].percent : def;
+}
+
int arg_count_increment(struct cmd_context *cmd, int a)
{
return cmd->args[a].count++;
@@ -81,6 +86,28 @@
}
/*
+ * Strip dev_dir if present
+ */
+char *skip_dev_dir(struct cmd_context *cmd, const char *vg_name)
+{
+ /* FIXME Do this properly */
+
+ if (*vg_name == '/') {
+ while (*vg_name == '/')
+ vg_name++;
+ vg_name--;
+ }
+
+ if (!strncmp(vg_name, cmd->dev_dir, strlen(cmd->dev_dir))) {
+ vg_name += strlen(cmd->dev_dir);
+ while (*vg_name == '/')
+ vg_name++;
+ }
+
+ return (char *) vg_name;
+}
+
+/*
* Metadata iteration functions
*/
int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
@@ -268,7 +295,7 @@
} else {
vglv_sz = strlen(vgname) + strlen(lv_name) + 2;
if (!(vglv = dm_pool_alloc(cmd->mem, vglv_sz)) ||
- lvm_snprintf(vglv, vglv_sz, "%s/%s", vgname,
+ dm_snprintf(vglv, vglv_sz, "%s/%s", vgname,
lv_name) < 0) {
log_error("vg/lv string alloc failed");
return ECMD_FAILED;
@@ -307,9 +334,20 @@
if (!vg)
log_error("Volume group \"%s\" "
"not found", vgname);
- else
+ else {
+ if ((vg->status & CLUSTERED) &&
+ !locking_is_clustered() &&
+ !lockingfailed()) {
+ log_error("Skipping clustered volume "
+ "group %s", vgname);
+ if (ret_max < ECMD_FAILED)
+ ret_max = ECMD_FAILED;
+ continue;
+ }
log_error("Volume group \"%s\" "
"inconsistent", vgname);
+ }
+
if (!vg || !(vg = recover_vg(cmd, vgname, lock_type))) {
if (ret_max < ECMD_FAILED)
ret_max = ECMD_FAILED;
@@ -317,6 +355,15 @@
}
}
+ if ((vg->status & CLUSTERED) && !locking_is_clustered() &&
+ !lockingfailed()) {
+ unlock_vg(cmd, vgname);
+ log_error("Skipping clustered volume group %s", vgname);
+ if (ret_max < ECMD_FAILED)
+ ret_max = ECMD_FAILED;
+ continue;
+ }
+
tags_arg = &tags;
list_init(&lvnames); /* LVs to be processed in this VG */
list_iterate_items(sll, &arg_lvnames) {
@@ -416,6 +463,13 @@
return ECMD_FAILED;
}
+ if ((vg->status & CLUSTERED) && !locking_is_clustered() &&
+ !lockingfailed()) {
+ log_error("Skipping clustered volume group %s", vg_name);
+ unlock_vg(cmd, vg_name);
+ return ECMD_FAILED;
+ }
+
if (!list_empty(tags)) {
/* Only process if a tag matches or it's on arg_vgnames */
if (!str_list_match_item(arg_vgnames, vg_name) &&
@@ -450,7 +504,6 @@
struct list arg_vgnames, tags;
const char *vg_name, *vgid;
- char *dev_dir = cmd->dev_dir;
list_init(&tags);
list_init(&arg_vgnames);
@@ -475,13 +528,7 @@
continue;
}
- if (*vg_name == '/') {
- while (*vg_name == '/')
- vg_name++;
- vg_name--;
- }
- if (!strncmp(vg_name, dev_dir, strlen(dev_dir)))
- vg_name += strlen(dev_dir);
+ vg_name = skip_dev_dir(cmd, vg_name);
if (strchr(vg_name, '/')) {
log_error("Invalid volume group name: %s",
vg_name);
@@ -665,6 +712,15 @@
}
if (!consistent)
continue;
+
+ if ((vg->status & CLUSTERED) &&
+ !locking_is_clustered() &&
+ !lockingfailed()) {
+ log_error("Skipping clustered volume "
+ "group %s", sll->str);
+ continue;
+ }
+
ret = process_each_pv_in_vg(cmd, vg, &tags,
handle,
process_single);
@@ -768,21 +824,13 @@
char *default_vgname(struct cmd_context *cmd)
{
char *vg_path;
- char *dev_dir = cmd->dev_dir;
/* Take default VG from environment? */
vg_path = getenv("LVM_VG_NAME");
if (!vg_path)
return 0;
- /* Strip dev_dir (optional) */
- if (*vg_path == '/') {
- while (*vg_path == '/')
- vg_path++;
- vg_path--;
- }
- if (!strncmp(vg_path, dev_dir, strlen(dev_dir)))
- vg_path += strlen(dev_dir);
+ vg_path = skip_dev_dir(cmd, vg_path);
if (strchr(vg_path, '/')) {
log_error("Environment Volume Group in LVM_VG_NAME invalid: "
@@ -1038,6 +1086,10 @@
{
int consistent = 1;
+ /* Don't attempt automatic recovery without proper locking */
+ if (lockingfailed())
+ return NULL;
+
lock_type &= ~LCK_TYPE_MASK;
lock_type |= LCK_WRITE;
@@ -1098,14 +1150,14 @@
int generate_log_name_format(struct volume_group *vg __attribute((unused)),
const char *lv_name, char *buffer, size_t size)
{
- if (lvm_snprintf(buffer, size, "%s_mlog", lv_name) < 0) {
+ if (dm_snprintf(buffer, size, "%s_mlog", lv_name) < 0) {
stack;
return 0;
}
/* FIXME I think we can cope without this. Cf. _add_lv_to_dtree()
if (find_lv_in_vg(vg, buffer) &&
- lvm_snprintf(buffer, size, "%s_mlog_%%d",
+ dm_snprintf(buffer, size, "%s_mlog_%%d",
lv_name) < 0) {
stack;
return 0;
@@ -1135,7 +1187,7 @@
return 0;
}
- if (lvm_snprintf(name, PATH_MAX, "%s%s/%s", cmd->dev_dir,
+ if (dm_snprintf(name, PATH_MAX, "%s%s/%s", cmd->dev_dir,
lv->vg->name, lv->name) < 0) {
log_error("Name too long - device not cleared (%s)", lv->name);
return 0;
@@ -1157,7 +1209,6 @@
return 1;
}
-
/*
* This function writes a new header to the mirror log header to the lv
*
@@ -1183,7 +1234,7 @@
return 0;
}
- if (lvm_snprintf(name, PATH_MAX, "%s%s/%s", cmd->dev_dir,
+ if (dm_snprintf(name, PATH_MAX, "%s%s/%s", cmd->dev_dir,
lv->vg->name, lv->name) < 0) {
log_error("Name too long - log header not written (%s)", lv->name);
return 0;
@@ -1254,6 +1305,12 @@
goto error;
}
+ if (!activation() && in_sync) {
+ log_error("Aborting. Unable to create in-sync mirror log "
+ "while activation is disabled.");
+ goto error;
+ }
+
if (!activate_lv(cmd, log_lv)) {
log_error("Aborting. Failed to activate mirror log. "
"Remove new LVs and retry.");
@@ -1266,7 +1323,7 @@
goto error;
}
- if (!_write_log_header(cmd, log_lv)) {
+ if (activation() && !_write_log_header(cmd, log_lv)) {
log_error("Aborting. Failed to write mirror log header. "
"Remove new LV and retry.");
goto error;
Modified: lvm2/upstream/current/tools/toollib.h
==============================================================================
--- lvm2/upstream/current/tools/toollib.h (original)
+++ lvm2/upstream/current/tools/toollib.h Mon Oct 23 08:49:10 2006
@@ -76,6 +76,7 @@
char *default_vgname(struct cmd_context *cmd);
const char *extract_vgname(struct cmd_context *cmd, const char *lv_name);
+char *skip_dev_dir(struct cmd_context *cmd, const char *vg_name);
/*
* Builds a list of pv's from the names in argv. Used in
Modified: lvm2/upstream/current/tools/tools.h
==============================================================================
--- lvm2/upstream/current/tools/tools.h (original)
+++ lvm2/upstream/current/tools/tools.h Mon Oct 23 08:49:10 2006
@@ -80,6 +80,13 @@
SIGN_MINUS = 2
} sign_t;
+typedef enum {
+ PERCENT_NONE = 0,
+ PERCENT_VG,
+ PERCENT_FREE,
+ PERCENT_LV
+} percent_t;
+
enum {
CHANGE_AY = 0,
CHANGE_AN = 1,
@@ -103,6 +110,7 @@
int64_t i64_value;
uint64_t ui64_value;
sign_t sign;
+ percent_t percent;
void *ptr;
};
@@ -126,6 +134,7 @@
int size_mb_arg(struct cmd_context *cmd, struct arg *a);
int int_arg(struct cmd_context *cmd, struct arg *a);
int int_arg_with_sign(struct cmd_context *cmd, struct arg *a);
+int int_arg_with_sign_and_percent(struct cmd_context *cmd, struct arg *a);
int major_arg(struct cmd_context *cmd, struct arg *a);
int minor_arg(struct cmd_context *cmd, struct arg *a);
int string_arg(struct cmd_context *cmd, struct arg *a);
@@ -148,6 +157,7 @@
uint64_t arg_uint64_value(struct cmd_context *cmd, int a, const uint64_t def);
const void *arg_ptr_value(struct cmd_context *cmd, int a, const void *def);
sign_t arg_sign_value(struct cmd_context *cmd, int a, const sign_t def);
+percent_t arg_percent_value(struct cmd_context *cmd, int a, const percent_t def);
int arg_count_increment(struct cmd_context *cmd, int a);
const char *command_name(struct cmd_context *cmd);
Modified: lvm2/upstream/current/tools/vgcfgrestore.c
==============================================================================
--- lvm2/upstream/current/tools/vgcfgrestore.c (original)
+++ lvm2/upstream/current/tools/vgcfgrestore.c Mon Oct 23 08:49:10 2006
@@ -24,10 +24,7 @@
return ECMD_FAILED;
}
- vg_name = argv[0];
-
- if (!strncmp(vg_name, cmd->dev_dir, strlen(cmd->dev_dir)))
- vg_name += strlen(cmd->dev_dir);
+ vg_name = skip_dev_dir(cmd, argv[0]);
if (!validate_name(vg_name)) {
log_error("Volume group name \"%s\" is invalid", vg_name);
Modified: lvm2/upstream/current/tools/vgchange.c
==============================================================================
--- lvm2/upstream/current/tools/vgchange.c (original)
+++ lvm2/upstream/current/tools/vgchange.c Mon Oct 23 08:49:10 2006
@@ -312,7 +312,7 @@
if (max_lv && max_lv < vg->lv_count) {
log_error("MaxLogicalVolume is less than the current number "
- "%d of logical volume(s) for \"%s\"", vg->lv_count,
+ "%d of LVs for \"%s\"", vg->lv_count,
vg->name);
return ECMD_FAILED;
}
@@ -332,6 +332,53 @@
return ECMD_PROCESSED;
}
+static int _vgchange_physicalvolumes(struct cmd_context *cmd,
+ struct volume_group *vg)
+{
+ uint32_t max_pv = arg_uint_value(cmd, maxphysicalvolumes_ARG, 0);
+
+ if (!(vg->status & RESIZEABLE_VG)) {
+ log_error("Volume group \"%s\" must be resizeable "
+ "to change MaxPhysicalVolumes", vg->name);
+ return ECMD_FAILED;
+ }
+
+ if (arg_sign_value(cmd, maxphysicalvolumes_ARG, 0) == SIGN_MINUS) {
+ log_error("MaxPhysicalVolumes may not be negative");
+ return EINVALID_CMD_LINE;
+ }
+
+ if (!(vg->fid->fmt->features & FMT_UNLIMITED_VOLS)) {
+ if (!max_pv)
+ max_pv = 255;
+ else if (max_pv > 255) {
+ log_error("MaxPhysicalVolume limit is 255");
+ return ECMD_FAILED;
+ }
+ }
+
+ if (max_pv && max_pv < vg->pv_count) {
+ log_error("MaxPhysicalVolumes is less than the current number "
+ "%d of PVs for \"%s\"", vg->pv_count,
+ vg->name);
+ return ECMD_FAILED;
+ }
+
+ if (!archive(vg))
+ return ECMD_FAILED;
+
+ vg->max_pv = max_pv;
+
+ if (!vg_write(vg) || !vg_commit(vg))
+ return ECMD_FAILED;
+
+ backup(vg);
+
+ log_print("Volume group \"%s\" successfully changed", vg->name);
+
+ return ECMD_PROCESSED;
+}
+
static int _vgchange_pesize(struct cmd_context *cmd, struct volume_group *vg)
{
uint32_t extent_size;
@@ -508,6 +555,9 @@
else if (arg_count(cmd, logicalvolume_ARG))
r = _vgchange_logicalvolume(cmd, vg);
+ else if (arg_count(cmd, maxphysicalvolumes_ARG))
+ r = _vgchange_physicalvolumes(cmd, vg);
+
else if (arg_count(cmd, addtag_ARG))
r = _vgchange_tag(cmd, vg, addtag_ARG);
@@ -533,24 +583,26 @@
{
if (!
(arg_count(cmd, available_ARG) + arg_count(cmd, logicalvolume_ARG) +
+ arg_count(cmd, maxphysicalvolumes_ARG) +
arg_count(cmd, resizeable_ARG) + arg_count(cmd, deltag_ARG) +
arg_count(cmd, addtag_ARG) + arg_count(cmd, uuid_ARG) +
arg_count(cmd, physicalextentsize_ARG) +
arg_count(cmd, clustered_ARG) + arg_count(cmd, alloc_ARG) +
arg_count(cmd, monitor_ARG))) {
- log_error("One of -a, -c, -l, -s, -x, --uuid, --alloc, --addtag or "
- "--deltag required");
+ log_error("One of -a, -c, -l, -p, -s, -x, --uuid, --alloc, "
+ "--addtag or --deltag required");
return EINVALID_CMD_LINE;
}
/* FIXME Cope with several changes at once! */
if (arg_count(cmd, available_ARG) + arg_count(cmd, logicalvolume_ARG) +
+ arg_count(cmd, maxphysicalvolumes_ARG) +
arg_count(cmd, resizeable_ARG) + arg_count(cmd, deltag_ARG) +
arg_count(cmd, addtag_ARG) + arg_count(cmd, alloc_ARG) +
arg_count(cmd, uuid_ARG) + arg_count(cmd, clustered_ARG) +
arg_count(cmd, physicalextentsize_ARG) > 1) {
- log_error("Only one of -a, -c, -l, -s, -x, --uuid, --alloc, "
- "--addtag or --deltag allowed");
+ log_error("Only one of -a, -c, -l, -p, -s, -x, --uuid, "
+ "--alloc, --addtag or --deltag allowed");
return EINVALID_CMD_LINE;
}
Modified: lvm2/upstream/current/tools/vgcreate.c
==============================================================================
--- lvm2/upstream/current/tools/vgcreate.c (original)
+++ lvm2/upstream/current/tools/vgcreate.c Mon Oct 23 08:49:10 2006
@@ -38,7 +38,7 @@
return EINVALID_CMD_LINE;
}
- vg_name = argv[0];
+ vg_name = skip_dev_dir(cmd, argv[0]);
max_lv = arg_uint_value(cmd, maxlogicalvolumes_ARG, 0);
max_pv = arg_uint_value(cmd, maxphysicalvolumes_ARG, 0);
alloc = arg_uint_value(cmd, alloc_ARG, ALLOC_NORMAL);
@@ -84,10 +84,6 @@
return EINVALID_CMD_LINE;
}
- /* Strip dev_dir if present */
- if (!strncmp(vg_name, cmd->dev_dir, strlen(cmd->dev_dir)))
- vg_name += strlen(cmd->dev_dir);
-
if (!validate_vg_name(cmd, vg_name)) {
log_error("New volume group name \"%s\" is invalid", vg_name);
return ECMD_FAILED;
Modified: lvm2/upstream/current/tools/vgextend.c
==============================================================================
--- lvm2/upstream/current/tools/vgextend.c (original)
+++ lvm2/upstream/current/tools/vgextend.c Mon Oct 23 08:49:10 2006
@@ -32,7 +32,7 @@
return EINVALID_CMD_LINE;
}
- vg_name = argv[0];
+ vg_name = skip_dev_dir(cmd, argv[0]);
argc--;
argv++;
@@ -53,6 +53,12 @@
goto error;
}
+ if ((vg->status & CLUSTERED) && !locking_is_clustered() &&
+ !lockingfailed()) {
+ log_error("Skipping clustered volume group %s", vg->name);
+ goto error;
+ }
+
if (vg->status & EXPORTED_VG) {
log_error("Volume group \"%s\" is exported", vg->name);
goto error;
Modified: lvm2/upstream/current/tools/vgmerge.c
==============================================================================
--- lvm2/upstream/current/tools/vgmerge.c (original)
+++ lvm2/upstream/current/tools/vgmerge.c Mon Oct 23 08:49:10 2006
@@ -41,6 +41,13 @@
return ECMD_FAILED;
}
+ if ((vg_to->status & CLUSTERED) && !locking_is_clustered() &&
+ !lockingfailed()) {
+ log_error("Skipping clustered volume group %s", vg_name_to);
+ unlock_vg(cmd, vg_name_to);
+ return ECMD_FAILED;
+ }
+
if (vg_to->status & EXPORTED_VG) {
log_error("Volume group \"%s\" is exported", vg_to->name);
unlock_vg(cmd, vg_name_to);
@@ -66,6 +73,12 @@
goto error;
}
+ if ((vg_from->status & CLUSTERED) && !locking_is_clustered() &&
+ !lockingfailed()) {
+ log_error("Skipping clustered volume group %s", vg_name_from);
+ goto error;
+ }
+
if (vg_from->status & EXPORTED_VG) {
log_error("Volume group \"%s\" is exported", vg_from->name);
goto error;
@@ -231,7 +244,7 @@
int vgmerge(struct cmd_context *cmd, int argc, char **argv)
{
- char *vg_name_to;
+ char *vg_name_to, *vg_name_from;
int opt = 0;
int ret = 0, ret_max = 0;
@@ -240,12 +253,14 @@
return EINVALID_CMD_LINE;
}
- vg_name_to = argv[0];
+ vg_name_to = skip_dev_dir(cmd, argv[0]);
argc--;
argv++;
for (; opt < argc; opt++) {
- ret = _vgmerge_single(cmd, vg_name_to, argv[opt]);
+ vg_name_from = skip_dev_dir(cmd, argv[opt]);
+
+ ret = _vgmerge_single(cmd, vg_name_to, vg_name_from);
if (ret > ret_max)
ret_max = ret;
}
Modified: lvm2/upstream/current/tools/vgreduce.c
==============================================================================
--- lvm2/upstream/current/tools/vgreduce.c (original)
+++ lvm2/upstream/current/tools/vgreduce.c Mon Oct 23 08:49:10 2006
@@ -459,7 +459,7 @@
return EINVALID_CMD_LINE;
}
- vg_name = argv[0];
+ vg_name = skip_dev_dir(cmd, argv[0]);
argv++;
argc--;
@@ -476,6 +476,13 @@
return ECMD_FAILED;
}
+ if (vg && (vg->status & CLUSTERED) && !locking_is_clustered() &&
+ !lockingfailed()) {
+ log_error("Skipping clustered volume group %s", vg->name);
+ unlock_vg(cmd, vg_name);
+ return ECMD_FAILED;
+ }
+
if (arg_count(cmd, removemissing_ARG)) {
if (vg && consistent) {
log_error("Volume group \"%s\" is already consistent",
@@ -491,6 +498,13 @@
unlock_vg(cmd, vg_name);
return ECMD_FAILED;
}
+ if ((vg->status & CLUSTERED) && !locking_is_clustered() &&
+ !lockingfailed()) {
+ log_error("Skipping clustered volume group %s",
+ vg->name);
+ unlock_vg(cmd, vg_name);
+ return ECMD_FAILED;
+ }
if (!archive(vg)) {
init_partial(0);
unlock_vg(cmd, vg_name);
Modified: lvm2/upstream/current/tools/vgrename.c
==============================================================================
--- lvm2/upstream/current/tools/vgrename.c (original)
+++ lvm2/upstream/current/tools/vgrename.c Mon Oct 23 08:49:10 2006
@@ -35,18 +35,12 @@
return EINVALID_CMD_LINE;
}
- vg_name_old = argv[0];
- vg_name_new = argv[1];
+ vg_name_old = skip_dev_dir(cmd, argv[0]);
+ vg_name_new = skip_dev_dir(cmd, argv[1]);
dev_dir = cmd->dev_dir;
length = strlen(dev_dir);
- /* If present, strip dev_dir */
- if (!strncmp(vg_name_old, dev_dir, length))
- vg_name_old += length;
- if (!strncmp(vg_name_new, dev_dir, length))
- vg_name_new += length;
-
/* Check sanity of new name */
if (strlen(vg_name_new) > NAME_LEN - length - 2) {
log_error("New volume group path exceeds maximum length "
@@ -108,6 +102,13 @@
return ECMD_FAILED;
}
+ if ((vg_old->status & CLUSTERED) && !locking_is_clustered() &&
+ !lockingfailed()) {
+ log_error("Skipping clustered volume group %s", vg_old->name);
+ unlock_vg(cmd, vg_name_old);
+ return ECMD_FAILED;
+ }
+
if (vg_old->status & EXPORTED_VG)
log_info("Volume group \"%s\" is exported", vg_old->name);
Modified: lvm2/upstream/current/tools/vgsplit.c
==============================================================================
--- lvm2/upstream/current/tools/vgsplit.c (original)
+++ lvm2/upstream/current/tools/vgsplit.c Mon Oct 23 08:49:10 2006
@@ -196,12 +196,25 @@
return ECMD_FAILED;
}
+ if ((vg_from->status & CLUSTERED) && !locking_is_clustered() &&
+ !lockingfailed()) {
+ log_error("Skipping clustered volume group %s", vg_from->name);
+ unlock_vg(cmd, vg_name_from);
+ return ECMD_FAILED;
+ }
+
if (vg_from->status & EXPORTED_VG) {
log_error("Volume group \"%s\" is exported", vg_from->name);
unlock_vg(cmd, vg_name_from);
return ECMD_FAILED;
}
+ if (!(vg_from->status & RESIZEABLE_VG)) {
+ log_error("Volume group \"%s\" is not resizeable", vg_from->name);
+ unlock_vg(cmd, vg_name_from);
+ return ECMD_FAILED;
+ }
+
if (!(vg_from->status & LVM_WRITE)) {
log_error("Volume group \"%s\" is read-only", vg_from->name);
unlock_vg(cmd, vg_name_from);
@@ -241,6 +254,9 @@
vg_from->alloc, 0, NULL)))
goto error;
+ if (vg_from->status & CLUSTERED)
+ vg_to->status |= CLUSTERED;
+
/* Archive vg_from before changing it */
if (!archive(vg_from))
goto error;
More information about the pkg-lvm-commits
mailing list