[lvm-devel] master - lvmdump: Use O_DIRECT to gather metadata.

Alasdair Kergon agk at fedoraproject.org
Thu Sep 15 13:01:38 UTC 2016


Gitweb:        http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=5da35d879ad073d9fb0d7ec8bfabe9ae39ac5bc1
Commit:        5da35d879ad073d9fb0d7ec8bfabe9ae39ac5bc1
Parent:        d455300d7baff341f1c7fe5776d975369dd3a23a
Author:        Alasdair G Kergon <agk at redhat.com>
AuthorDate:    Thu Sep 15 13:59:52 2016 +0100
Committer:     Alasdair G Kergon <agk at redhat.com>
CommitterDate: Thu Sep 15 14:00:39 2016 +0100

lvmdump: Use O_DIRECT to gather metadata.

---
 WHATS_NEW             |    1 +
 configure             |    5 +-
 configure.in          |    2 +
 scripts/lvmdump.sh    |  356 ------------------------------------------------
 scripts/lvmdump.sh.in |  362 +++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 369 insertions(+), 357 deletions(-)

diff --git a/WHATS_NEW b/WHATS_NEW
index ba394a4..1ef3dc6 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
 Version 2.02.166 - 
 =====================================
+  Use O_DIRECT to gather metadata in lvmdump.
   Fix possible NULL pointer derefence when checking for monitoring.
   Add lvmreport(7) man page.
   Don't install lvmraid(7) man page when raid excluded. (2.02.165)
diff --git a/configure b/configure
index 8253bfc..c82a19b 100755
--- a/configure
+++ b/configure
@@ -676,6 +676,7 @@ PTHREAD_LIBS
 M_LIBS
 POOL
 PKGCONFIG
+ODIRECT
 OCFDIR
 OCF
 MIRRORS
@@ -15341,8 +15342,9 @@ LVM_LIBAPI=`echo "$VER" | $AWK -F '[()]' '{print $2}'`
 
 
 
+
 ################################################################################
-ac_config_files="$ac_config_files Makefile make.tmpl daemons/Makefile daemons/clvmd/Makefile daemons/cmirrord/Makefile daemons/dmeventd/Makefile daemons/dmeventd/libdevmapper-event.pc daemons/dmeventd/plugins/Makefile daemons/dmeventd/plugins/lvm2/Makefile daemons/dmeventd/plugins/raid/Makefile daemons/dmeventd/plugins/mirror/Makefile daemons/dmeventd/plugins/snapshot/Makefile daemons/dmeventd/plugins/thin/Makefile daemons/lvmdbusd/Makefile daemons/lvmdbusd/path.py daemons/lvmetad/Makefile daemons/lvmpolld/Makefile daemons/lvmlockd/Makefile conf/Makefile conf/example.conf conf/lvmlocal.conf conf/command_profile_template.profile conf/metadata_profile_template.profile include/.symlinks include/Makefile lib/Makefile lib/format1/Makefile lib/format_pool/Makefile lib/locking/Makefile lib/mirror/Makefile lib/replicator/Makefile include/lvm-version.h lib/raid/Makefile lib/snapshot/Makefile lib/thin/Makefile lib/cache_segtype/Makefile libdaemon/Makefile libdaemon/client/Makefile lib
 daemon/server/Makefile libdm/Makefile libdm/libdevmapper.pc liblvm/Makefile liblvm/liblvm2app.pc man/Makefile po/Makefile python/Makefile python/setup.py scripts/blkdeactivate.sh scripts/blk_availability_init_red_hat scripts/blk_availability_systemd_red_hat.service scripts/clvmd_init_red_hat scripts/cmirrord_init_red_hat scripts/com.redhat.lvmdbus1.service scripts/dm_event_systemd_red_hat.service scripts/dm_event_systemd_red_hat.socket scripts/lvm2_cluster_activation_red_hat.sh scripts/lvm2_cluster_activation_systemd_red_hat.service scripts/lvm2_clvmd_systemd_red_hat.service scripts/lvm2_cmirrord_systemd_red_hat.service scripts/lvm2_lvmdbusd_systemd_red_hat.service scripts/lvm2_lvmetad_init_red_hat scripts/lvm2_lvmetad_systemd_red_hat.service scripts/lvm2_lvmetad_systemd_red_hat.socket scripts/lvm2_lvmpolld_init_red_hat scripts/lvm2_lvmpolld_systemd_red_hat.service scripts/lvm2_lvmpolld_systemd_red_hat.socket scripts/lvm2_lvmlockd_systemd_red_hat.service scripts/lvm2_lvmlock
 ing_systemd_red_hat.service scripts/lvm2_monitoring_init_red_hat scripts/lvm2_monitoring_systemd_red_hat.service scripts/lvm2_pvscan_systemd_red_hat at .service scripts/lvm2_tmpfiles_red_hat.conf scripts/Makefile test/Makefile test/api/Makefile test/unit/Makefile tools/Makefile udev/Makefile unit-tests/datastruct/Makefile unit-tests/regex/Makefile unit-tests/mm/Makefile"
+ac_config_files="$ac_config_files Makefile make.tmpl daemons/Makefile daemons/clvmd/Makefile daemons/cmirrord/Makefile daemons/dmeventd/Makefile daemons/dmeventd/libdevmapper-event.pc daemons/dmeventd/plugins/Makefile daemons/dmeventd/plugins/lvm2/Makefile daemons/dmeventd/plugins/raid/Makefile daemons/dmeventd/plugins/mirror/Makefile daemons/dmeventd/plugins/snapshot/Makefile daemons/dmeventd/plugins/thin/Makefile daemons/lvmdbusd/Makefile daemons/lvmdbusd/path.py daemons/lvmetad/Makefile daemons/lvmpolld/Makefile daemons/lvmlockd/Makefile conf/Makefile conf/example.conf conf/lvmlocal.conf conf/command_profile_template.profile conf/metadata_profile_template.profile include/.symlinks include/Makefile lib/Makefile lib/format1/Makefile lib/format_pool/Makefile lib/locking/Makefile lib/mirror/Makefile lib/replicator/Makefile include/lvm-version.h lib/raid/Makefile lib/snapshot/Makefile lib/thin/Makefile lib/cache_segtype/Makefile libdaemon/Makefile libdaemon/client/Makefile lib
 daemon/server/Makefile libdm/Makefile libdm/libdevmapper.pc liblvm/Makefile liblvm/liblvm2app.pc man/Makefile po/Makefile python/Makefile python/setup.py scripts/blkdeactivate.sh scripts/blk_availability_init_red_hat scripts/blk_availability_systemd_red_hat.service scripts/clvmd_init_red_hat scripts/cmirrord_init_red_hat scripts/com.redhat.lvmdbus1.service scripts/dm_event_systemd_red_hat.service scripts/dm_event_systemd_red_hat.socket scripts/lvm2_cluster_activation_red_hat.sh scripts/lvm2_cluster_activation_systemd_red_hat.service scripts/lvm2_clvmd_systemd_red_hat.service scripts/lvm2_cmirrord_systemd_red_hat.service scripts/lvm2_lvmdbusd_systemd_red_hat.service scripts/lvm2_lvmetad_init_red_hat scripts/lvm2_lvmetad_systemd_red_hat.service scripts/lvm2_lvmetad_systemd_red_hat.socket scripts/lvm2_lvmpolld_init_red_hat scripts/lvm2_lvmpolld_systemd_red_hat.service scripts/lvm2_lvmpolld_systemd_red_hat.socket scripts/lvm2_lvmlockd_systemd_red_hat.service scripts/lvm2_lvmlock
 ing_systemd_red_hat.service scripts/lvm2_monitoring_init_red_hat scripts/lvm2_monitoring_systemd_red_hat.service scripts/lvm2_pvscan_systemd_red_hat at .service scripts/lvm2_tmpfiles_red_hat.conf scripts/lvmdump.sh scripts/Makefile test/Makefile test/api/Makefile test/unit/Makefile tools/Makefile udev/Makefile unit-tests/datastruct/Makefile unit-tests/regex/Makefile unit-tests/mm/Makefile"
 
 cat >confcache <<\_ACEOF
 # This file is a shell script that caches the results of configure
@@ -16109,6 +16111,7 @@ do
     "scripts/lvm2_monitoring_systemd_red_hat.service") CONFIG_FILES="$CONFIG_FILES scripts/lvm2_monitoring_systemd_red_hat.service" ;;
     "scripts/lvm2_pvscan_systemd_red_hat at .service") CONFIG_FILES="$CONFIG_FILES scripts/lvm2_pvscan_systemd_red_hat at .service" ;;
     "scripts/lvm2_tmpfiles_red_hat.conf") CONFIG_FILES="$CONFIG_FILES scripts/lvm2_tmpfiles_red_hat.conf" ;;
+    "scripts/lvmdump.sh") CONFIG_FILES="$CONFIG_FILES scripts/lvmdump.sh" ;;
     "scripts/Makefile") CONFIG_FILES="$CONFIG_FILES scripts/Makefile" ;;
     "test/Makefile") CONFIG_FILES="$CONFIG_FILES test/Makefile" ;;
     "test/api/Makefile") CONFIG_FILES="$CONFIG_FILES test/api/Makefile" ;;
diff --git a/configure.in b/configure.in
index 33b5c76..cc77aab 100644
--- a/configure.in
+++ b/configure.in
@@ -2068,6 +2068,7 @@ AC_SUBST(MIRRORS)
 AC_SUBST(MSGFMT)
 AC_SUBST(OCF)
 AC_SUBST(OCFDIR)
+AC_SUBST(ODIRECT)
 AC_SUBST(PKGCONFIG)
 AC_SUBST(POOL)
 AC_SUBST(M_LIBS)
@@ -2213,6 +2214,7 @@ scripts/lvm2_monitoring_init_red_hat
 scripts/lvm2_monitoring_systemd_red_hat.service
 scripts/lvm2_pvscan_systemd_red_hat at .service
 scripts/lvm2_tmpfiles_red_hat.conf
+scripts/lvmdump.sh
 scripts/Makefile
 test/Makefile
 test/api/Makefile
diff --git a/scripts/lvmdump.sh b/scripts/lvmdump.sh
deleted file mode 100755
index 85f8e5c..0000000
--- a/scripts/lvmdump.sh
+++ /dev/null
@@ -1,356 +0,0 @@
-#!/bin/bash
-# We use some bash-isms (getopts?)
-
-# Copyright (C) 2007-2015 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-# lvm_dump: This script is used to collect pertinent information for
-#           the debugging of lvm issues.
-
-# following external commands are used throughout the script
-# echo and test are internal in bash at least
-MKDIR=mkdir # need -p
-TAR=tar # need czf
-RM=rm # need -rf
-CP=cp
-TAIL=tail # we need -n
-LS=ls # need -la
-PS=ps # need alx
-SED=sed
-DD=dd
-CUT=cut
-GREP=grep
-DATE=date
-BASENAME=basename
-UDEVADM=udevadm
-UNAME=uname
-TR=tr
-SOCAT=socat # either socat or nc is needed for dumping lvmetad state
-NC=nc
-
-# user may override lvm and dmsetup location by setting LVM_BINARY
-# and DMSETUP_BINARY respectively
-LVM=${LVM_BINARY-lvm}
-DMSETUP=${DMSETUP_BINARY-dmsetup}
-LVMETAD_SOCKET=${LVM_LVMETAD_SOCKET-/var/run/lvm/lvmetad.socket}
-LVMPOLLD_SOCKET=${LVM_LVMPOLLD_SOCKET-/var/run/lvm/lvmpolld.socket}
-
-die() {
-    code=$1; shift
-    echo "$@" 1>&2
-    exit $code
-}
-
-"$LVM" version >& /dev/null || die 2 "Could not run lvm binary '$LVM'"
-"$DMSETUP" version >& /dev/null || DMSETUP=:
-
-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 "    -c if running clvmd, gather cluster data as well"
-	echo "    -d <directory> dump into a directory instead of tarball"
-	echo "    -l gather lvmetad state if running"
-	echo "    -p gather lvmpolld state if running"
-	echo "    -m gather LVM metadata from the PVs"
-	echo "    -s gather system info and context"
-	echo "    -u gather udev info and context"
-	echo ""
-
-	exit 1
-}
-
-advanced=0
-clustered=0
-metadata=0
-sysreport=0
-udev=0
-while getopts :acd:hlpmus opt; do
-	case $opt in 
-		a)	advanced=1 ;;
-		c)	clustered=1 ;;
-		d)	userdir=$OPTARG ;;
-		h)	usage ;;
-		l)	lvmetad=1 ;;
-		p)	lvmpolld=1 ;;
-		m)	metadata=1 ;;
-		s)      sysreport=1 ;;
-		u)	udev=1 ;;
-		:)	echo "$0: $OPTARG requires a value:"; usage ;;
-		\?)     echo "$0: unknown option $OPTARG"; usage ;;
-		*)	usage ;;
-	esac
-done
-
-NOW=`$DATE -u +%G%m%d%k%M%S | $TR -d ' '`
-if test -n "$userdir"; then
-	dir="$userdir"
-else
-	dirbase="lvmdump-$HOSTNAME-$NOW"
-	dir="$HOME/$dirbase"
-fi
-
-if test -d $dir ; then
-	(shopt -s nullglob dotglob; test -r $dir -a -w $dir -a -x $dir && cd $dir && files=(*) && ((! ${#files[@]}))) || \
-		die 5 "Fatal: directory $dir already exists and is not empty or inaccessible"
-else
-	test -e $dir && die 3 "Fatal: $dir already exists"
-	$MKDIR -p $dir || die 4 "Fatal: could not create $dir"
-fi
-
-log="$dir/lvmdump.log"
-
-myecho() {
-	echo "$@"
-	echo "$@" >> "$log"
-}
-
-log() {
-	echo "$@" >> "$log"
-	eval "$@"
-}
-
-warnings() {
-	if test "$UID" != "0" && test "$EUID" != "0"; then
-		myecho "WARNING! Running as non-privileged user, dump is likely incomplete!"
-	elif test "$DMSETUP" = ":"; then
-		myecho "WARNING! Could not run dmsetup, dump is likely incomplete."
-	fi
-}
-
-warnings
-
-myecho "Creating dump directory: $dir"
-echo " "
-
-if (( $advanced )); then
-	myecho "Gathering LVM volume info..."
-
-	myecho "  vgscan..."
-	log "\"$LVM\" vgscan -vvvv >> \"$dir/vgscan\" 2>&1"
-
-	myecho "  pvscan..."
-	log "\"$LVM\" pvscan -v >> \"$dir/pvscan\" 2>> \"$log\""
-
-	myecho "  lvs..."
-	log "\"$LVM\" lvs -a -H -o +devices,kernel_major,kernel_minor >> \"$dir/lvs\" 2>> \"$log\""
-
-	myecho "  pvs..."
-	log "\"$LVM\" pvs -a -o +major,minor -v >> \"$dir/pvs\" 2>> \"$log\""
-
-	myecho "  vgs..."
-	log "\"$LVM\" vgs -v >> \"$dir/vgs\" 2>> \"$log\""
-fi
-
-if (( $clustered )); then
-	myecho "Gathering cluster info..."
-
-	{
-	for i in nodes status services; do
-		cap_i=$(echo $i|tr a-z A-Z)
-		printf "$cap_i:\n----------------------------------\n"
-		log "cman_tool $i 2>> \"$log\""
-		echo
-	done
-
-	echo "LOCKS:"
-	echo "----------------------------------"
-	if [ -f /proc/cluster/dlm_locks ]
-	then
-		echo clvmd > /proc/cluster/dlm_locks
-		cat /proc/cluster/dlm_locks
-		echo
-		echo "RESOURCE DIR:"
-		cat /proc/cluster/dlm_dir
-		echo
-		echo "DEBUG LOG:"
-		cat /proc/cluster/dlm_debug
-		echo
-	fi
-	if [ -f /debug/dlm/clvmd ]
-	then
-		cat /debug/dlm/clvmd
-		echo
-		echo "WAITERS:"
-		cat /debug/dlm/clvmd_waiters
-		echo
-		echo "MASTER:"
-		cat /debug/dlm/clvmd_master
-	fi
-	} >> $dir/cluster_info
-fi
-
-myecho "Gathering LVM & device-mapper version info..."
-echo "LVM VERSION:" >> "$dir/versions"
-"$LVM" lvs --version >> "$dir/versions" 2>> "$log"
-echo "DEVICE MAPPER VERSION:" >> "$dir/versions"
-"$DMSETUP" --version >> "$dir/versions" 2>> "$log"
-echo "KERNEL VERSION:" >> "$dir/versions"
-"$UNAME" -a >> "$dir/versions" 2>> "$log"
-echo "DM TARGETS VERSIONS:" >> "$dir/versions"
-"$DMSETUP" targets >> "$dir/versions" 2>> "$log"
-
-myecho "Gathering dmsetup info..."
-log "\"$DMSETUP\" info -c >> \"$dir/dmsetup_info\" 2>> \"$log\""
-log "\"$DMSETUP\" table >> \"$dir/dmsetup_table\" 2>> \"$log\""
-log "\"$DMSETUP\" status >> \"$dir/dmsetup_status\" 2>> \"$log\""
-
-# cat as workaround to avoid tty ioctl (selinux)
-log "\"$DMSETUP\" ls --tree 2>> \"$log\" | cat >> \"$dir/dmsetup_ls_tree\""
-
-myecho "Gathering process info..."
-log "$PS alx >> \"$dir/ps_info\" 2>> \"$log\""
-
-myecho "Gathering console messages..."
-log "$TAIL -n 75 /var/log/messages >> \"$dir/messages\" 2>> \"$log\""
-
-myecho "Gathering /etc/lvm info..."
-log "$LS -laR /etc/lvm >> \"$dir/etc_lvm_listing\" 2>> \"$log\""
-log "$CP -RL --preserve=all /etc/lvm \"$dir/lvm\" 2>> \"$log\""
-log "$LVM dumpconfig --type diff --file \"$dir/config_diff\" 2>> \"$log\""
-log "$LVM dumpconfig --type missing --file \"$dir/config_missing\" 2>> \"$log\""
-
-myecho "Gathering /dev listing..."
-log "$LS -laR /dev >> \"$dir/dev_listing\" 2>> \"$log\""
-
-myecho "Gathering /sys/block listing..."
-log "$LS -laR /sys/block >> \"$dir/sysblock_listing\"  2>> \"$log\""
-log "$LS -laR /sys/devices/virtual/block >> \"$dir/sysblock_listing\"  2>> \"$log\""
-
-if (( $metadata )); then
-	myecho "Gathering LVM metadata from Physical Volumes..."
-
-	log "$MKDIR -p \"$dir/metadata\""
-
-	pvs="$("$LVM" pvs --separator , --noheadings --units s --nosuffix -o \
-	    name,pe_start 2>> "$log" | $SED -e 's/^ *//')"
-	for line in $pvs
-	do
-		test -z "$line" && continue
-		pv="$(echo $line | $CUT -d, -f1)"
-		pe_start="$(echo $line | $CUT -d, -f2)"
-		name="$($BASENAME "$pv")"
-		myecho "  $pv"
-		log "$DD if=$pv \"of=$dir/metadata/$name\" bs=512 count=$pe_start 2>> \"$log\""
-	done
-fi
-
-if (( $sysreport )); then
-	myecho "Gathering system info..."
-
-	sysreport_dir="$dir/sysreport"
-	log_lines=10000
-
-	SYSTEMCTL=$(which systemctl 2>> $log)
-	JOURNALCTL=$(which journalctl 2>> $log)
-	LSBLK=$(which lsblk 2>> $log)
-
-	log "$MKDIR -p \"$sysreport_dir\""
-
-	if test -z "LSBLK"; then
-		myecho "WARNING: lsblk not found"
-	else
-		if $LSBLK --help | $GREP -- --output-all >/dev/null; then
-			log "$LSBLK -O >> \"$sysreport_dir/lsblk_O\""
-		else
-			log "$LSBLK >> \"$sysreport_dir/lsblk\""
-		fi
-		if $LSBLK --help | $GREP -- --inverse >/dev/null; then
-			log "$LSBLK -s >> \"$sysreport_dir/lsblk_s\""
-		fi
-	fi
-
-	if test -z "$SYSTEMCTL"; then
-		myecho "WARNING: systemctl not found"
-	elif test -z "$JOURNALCTL"; then
-		myecho "WARNING: journalctl not found"
-	else
-		log "$JOURNALCTL -b --no-pager -o short-precise > \"$sysreport_dir/journal_content\" 2>> \"$log\""
-		log "$SYSTEMCTL status -l --no-pager -n $log_lines -o short-precise dm-event.socket dm-event.service \
-						   lvm2-monitor.service \
-						   lvm2-lvmetad.socket lvm2-lvmetad.service \
-						   lvm2-lvmpolld.socket lvm2-lvmpolld.service \
-						   lvm2-cluster-activation.service \
-						   lvm2-clvmd.service \
-						   lvm2-cmirrord.service \
-						   lvm2-activation-early.service \
-						   lvm2-activation.service \
-						   lvm2-activation-net.service \
-						   > \"$sysreport_dir/systemd_lvm2_services_status\" 2>> \"$log\""
-		log "$SYSTEMCTL list-units -l -a --no-legend --no-pager > \"$sysreport_dir/systemd_unit_list\" 2>> \"$log\""
-		for unit in $(cat $sysreport_dir/systemd_unit_list | $GREP lvm2-pvscan | cut -d " " -f 1); do
-			log "$SYSTEMCTL status -l --no-pager -n $log_lines -o short-precise $unit >> \"$sysreport_dir/systemd_lvm2_pvscan_service_status\""
-		done
-	fi
-fi
-
-if (( $udev )); then
-	myecho "Gathering udev info..."
-
-	udev_dir="$dir/udev"
-
-	log "$MKDIR -p \"$udev_dir\""
-	log "$UDEVADM info --version >> \"$udev_dir/version\" 2>> \"$log\""
-	log "$UDEVADM info --export-db >> \"$udev_dir/db\" 2>> \"$log\""
-	log "$CP -a /etc/udev/udev.conf \"$udev_dir/conf\" 2>> \"$log\""
-	log "$LS -la /lib/udev >> \"$udev_dir/lib_dir\" 2>> \"$log\""
-	log "$CP -RL --preserve=all /etc/udev/rules.d \"$udev_dir/rules_etc\" 2>> \"$log\""
-	log "$CP -RL --preserve=all /lib/udev/rules.d \"$udev_dir/rules_lib\" 2>> \"$log\""
-fi
-
-if (( $lvmetad )); then
-    (echo 'request="dump"'; echo '##') | {
-	if type -p $SOCAT >& /dev/null; then
-	    echo "$SOCAT unix-connect:$LVMETAD_SOCKET -" >> "$log"
-	    $SOCAT "unix-connect:$LVMETAD_SOCKET" - 2>> "$log"
-	elif echo | $NC -U "$LVMETAD_SOCKET"; then
-	    echo "$NC -U $LVMETAD_SOCKET" >> "$log"
-	    $NC -U "$LVMETAD_SOCKET" 2>> "$log"
-	else
-	    myecho "WARNING: Neither socat nor nc -U seems to be available." 1>&2
-	    echo "# DUMP FAILED"
-	    return 1
-	fi
-    } > "$dir/lvmetad.txt"
-fi
-
-if (( $lvmpolld )); then
-    (echo 'request="dump"'; echo '##') | {
-	if type -p $SOCAT >& /dev/null; then
-	    echo "$SOCAT unix-connect:$LVMPOLLD_SOCKET -" >> "$log"
-	    $SOCAT "unix-connect:$LVMPOLLD_SOCKET" - 2>> "$log"
-	elif echo | $NC -U "$LVMPOLLD_SOCKET"; then
-	    echo "$NC -U $LVMPOLLD_SOCKET" >> "$log"
-	    $NC -U "$LVMPOLLD_SOCKET" 2>> "$log"
-	else
-	    myecho "WARNING: Neither socat nor nc -U seems to be available." 1>&2
-	    echo "# DUMP FAILED"
-	    return 1
-	fi
-    } > "$dir/lvmpolld.txt"
-fi
-
-if test -z "$userdir"; then
-	lvm_dump="$dirbase.tgz"
-	myecho "Creating report tarball in $HOME/$lvm_dump..."
-fi
-
-warnings
-
-if test -z "$userdir"; then
-	cd "$HOME"
-	"$TAR" czf "$lvm_dump" "$dirbase" 2>/dev/null
-	"$RM" -rf "$dir"
-fi
-
-exit 0
diff --git a/scripts/lvmdump.sh.in b/scripts/lvmdump.sh.in
new file mode 100644
index 0000000..6467863
--- /dev/null
+++ b/scripts/lvmdump.sh.in
@@ -0,0 +1,362 @@
+#!/bin/bash
+# We use some bash-isms (getopts?)
+
+# Copyright (C) 2007-2015 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+# lvm_dump: This script is used to collect pertinent information for
+#           the debugging of lvm issues.
+
+# following external commands are used throughout the script
+# echo and test are internal in bash at least
+MKDIR=mkdir # need -p
+TAR=tar # need czf
+RM=rm # need -rf
+CP=cp
+TAIL=tail # we need -n
+LS=ls # need -la
+PS=ps # need alx
+SED=sed
+DD=dd
+CUT=cut
+GREP=grep
+DATE=date
+BASENAME=basename
+UDEVADM=udevadm
+UNAME=uname
+TR=tr
+SOCAT=socat # either socat or nc is needed for dumping lvmetad state
+NC=nc
+
+if test "@ODIRECT@" = yes; then
+    DDFLAGS='iflag=direct oflag=direct'
+else
+    DDFLAGS=
+fi
+
+# user may override lvm and dmsetup location by setting LVM_BINARY
+# and DMSETUP_BINARY respectively
+LVM=${LVM_BINARY-lvm}
+DMSETUP=${DMSETUP_BINARY-dmsetup}
+LVMETAD_SOCKET=${LVM_LVMETAD_SOCKET-/var/run/lvm/lvmetad.socket}
+LVMPOLLD_SOCKET=${LVM_LVMPOLLD_SOCKET-/var/run/lvm/lvmpolld.socket}
+
+die() {
+    code=$1; shift
+    echo "$@" 1>&2
+    exit $code
+}
+
+"$LVM" version >& /dev/null || die 2 "Could not run lvm binary '$LVM'"
+"$DMSETUP" version >& /dev/null || DMSETUP=:
+
+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 "    -c if running clvmd, gather cluster data as well"
+	echo "    -d <directory> dump into a directory instead of tarball"
+	echo "    -l gather lvmetad state if running"
+	echo "    -p gather lvmpolld state if running"
+	echo "    -m gather LVM metadata from the PVs"
+	echo "    -s gather system info and context"
+	echo "    -u gather udev info and context"
+	echo ""
+
+	exit 1
+}
+
+advanced=0
+clustered=0
+metadata=0
+sysreport=0
+udev=0
+while getopts :acd:hlpmus opt; do
+	case $opt in 
+		a)	advanced=1 ;;
+		c)	clustered=1 ;;
+		d)	userdir=$OPTARG ;;
+		h)	usage ;;
+		l)	lvmetad=1 ;;
+		p)	lvmpolld=1 ;;
+		m)	metadata=1 ;;
+		s)      sysreport=1 ;;
+		u)	udev=1 ;;
+		:)	echo "$0: $OPTARG requires a value:"; usage ;;
+		\?)     echo "$0: unknown option $OPTARG"; usage ;;
+		*)	usage ;;
+	esac
+done
+
+NOW=`$DATE -u +%G%m%d%k%M%S | $TR -d ' '`
+if test -n "$userdir"; then
+	dir="$userdir"
+else
+	dirbase="lvmdump-$HOSTNAME-$NOW"
+	dir="$HOME/$dirbase"
+fi
+
+if test -d $dir ; then
+	(shopt -s nullglob dotglob; test -r $dir -a -w $dir -a -x $dir && cd $dir && files=(*) && ((! ${#files[@]}))) || \
+		die 5 "Fatal: directory $dir already exists and is not empty or inaccessible"
+else
+	test -e $dir && die 3 "Fatal: $dir already exists"
+	$MKDIR -p $dir || die 4 "Fatal: could not create $dir"
+fi
+
+log="$dir/lvmdump.log"
+
+myecho() {
+	echo "$@"
+	echo "$@" >> "$log"
+}
+
+log() {
+	echo "$@" >> "$log"
+	eval "$@"
+}
+
+warnings() {
+	if test "$UID" != "0" && test "$EUID" != "0"; then
+		myecho "WARNING! Running as non-privileged user, dump is likely incomplete!"
+	elif test "$DMSETUP" = ":"; then
+		myecho "WARNING! Could not run dmsetup, dump is likely incomplete."
+	fi
+}
+
+warnings
+
+myecho "Creating dump directory: $dir"
+echo " "
+
+if (( $advanced )); then
+	myecho "Gathering LVM volume info..."
+
+	myecho "  vgscan..."
+	log "\"$LVM\" vgscan -vvvv >> \"$dir/vgscan\" 2>&1"
+
+	myecho "  pvscan..."
+	log "\"$LVM\" pvscan -v >> \"$dir/pvscan\" 2>> \"$log\""
+
+	myecho "  lvs..."
+	log "\"$LVM\" lvs -a -H -o +devices,kernel_major,kernel_minor >> \"$dir/lvs\" 2>> \"$log\""
+
+	myecho "  pvs..."
+	log "\"$LVM\" pvs -a -o +major,minor -v >> \"$dir/pvs\" 2>> \"$log\""
+
+	myecho "  vgs..."
+	log "\"$LVM\" vgs -v >> \"$dir/vgs\" 2>> \"$log\""
+fi
+
+if (( $clustered )); then
+	myecho "Gathering cluster info..."
+
+	{
+	for i in nodes status services; do
+		cap_i=$(echo $i|tr a-z A-Z)
+		printf "$cap_i:\n----------------------------------\n"
+		log "cman_tool $i 2>> \"$log\""
+		echo
+	done
+
+	echo "LOCKS:"
+	echo "----------------------------------"
+	if [ -f /proc/cluster/dlm_locks ]
+	then
+		echo clvmd > /proc/cluster/dlm_locks
+		cat /proc/cluster/dlm_locks
+		echo
+		echo "RESOURCE DIR:"
+		cat /proc/cluster/dlm_dir
+		echo
+		echo "DEBUG LOG:"
+		cat /proc/cluster/dlm_debug
+		echo
+	fi
+	if [ -f /debug/dlm/clvmd ]
+	then
+		cat /debug/dlm/clvmd
+		echo
+		echo "WAITERS:"
+		cat /debug/dlm/clvmd_waiters
+		echo
+		echo "MASTER:"
+		cat /debug/dlm/clvmd_master
+	fi
+	} >> $dir/cluster_info
+fi
+
+myecho "Gathering LVM & device-mapper version info..."
+echo "LVM VERSION:" >> "$dir/versions"
+"$LVM" lvs --version >> "$dir/versions" 2>> "$log"
+echo "DEVICE MAPPER VERSION:" >> "$dir/versions"
+"$DMSETUP" --version >> "$dir/versions" 2>> "$log"
+echo "KERNEL VERSION:" >> "$dir/versions"
+"$UNAME" -a >> "$dir/versions" 2>> "$log"
+echo "DM TARGETS VERSIONS:" >> "$dir/versions"
+"$DMSETUP" targets >> "$dir/versions" 2>> "$log"
+
+myecho "Gathering dmsetup info..."
+log "\"$DMSETUP\" info -c >> \"$dir/dmsetup_info\" 2>> \"$log\""
+log "\"$DMSETUP\" table >> \"$dir/dmsetup_table\" 2>> \"$log\""
+log "\"$DMSETUP\" status >> \"$dir/dmsetup_status\" 2>> \"$log\""
+
+# cat as workaround to avoid tty ioctl (selinux)
+log "\"$DMSETUP\" ls --tree 2>> \"$log\" | cat >> \"$dir/dmsetup_ls_tree\""
+
+myecho "Gathering process info..."
+log "$PS alx >> \"$dir/ps_info\" 2>> \"$log\""
+
+myecho "Gathering console messages..."
+log "$TAIL -n 75 /var/log/messages >> \"$dir/messages\" 2>> \"$log\""
+
+myecho "Gathering /etc/lvm info..."
+log "$LS -laR /etc/lvm >> \"$dir/etc_lvm_listing\" 2>> \"$log\""
+log "$CP -RL --preserve=all /etc/lvm \"$dir/lvm\" 2>> \"$log\""
+log "$LVM dumpconfig --type diff --file \"$dir/config_diff\" 2>> \"$log\""
+log "$LVM dumpconfig --type missing --file \"$dir/config_missing\" 2>> \"$log\""
+
+myecho "Gathering /dev listing..."
+log "$LS -laR /dev >> \"$dir/dev_listing\" 2>> \"$log\""
+
+myecho "Gathering /sys/block listing..."
+log "$LS -laR /sys/block >> \"$dir/sysblock_listing\"  2>> \"$log\""
+log "$LS -laR /sys/devices/virtual/block >> \"$dir/sysblock_listing\"  2>> \"$log\""
+
+if (( $metadata )); then
+	myecho "Gathering LVM metadata from Physical Volumes..."
+
+	log "$MKDIR -p \"$dir/metadata\""
+
+	pvs="$("$LVM" pvs --separator , --noheadings --units s --nosuffix -o \
+	    name,pe_start 2>> "$log" | $SED -e 's/^ *//')"
+	for line in $pvs
+	do
+		test -z "$line" && continue
+		pv="$(echo $line | $CUT -d, -f1)"
+		pe_start="$(echo $line | $CUT -d, -f2)"
+		name="$($BASENAME "$pv")"
+		myecho "  $pv"
+		log "$DD if=$pv \"of=$dir/metadata/$name\" $DDFLAGS bs=512 count=$pe_start 2>> \"$log\""
+	done
+fi
+
+if (( $sysreport )); then
+	myecho "Gathering system info..."
+
+	sysreport_dir="$dir/sysreport"
+	log_lines=10000
+
+	SYSTEMCTL=$(which systemctl 2>> $log)
+	JOURNALCTL=$(which journalctl 2>> $log)
+	LSBLK=$(which lsblk 2>> $log)
+
+	log "$MKDIR -p \"$sysreport_dir\""
+
+	if test -z "LSBLK"; then
+		myecho "WARNING: lsblk not found"
+	else
+		if $LSBLK --help | $GREP -- --output-all >/dev/null; then
+			log "$LSBLK -O >> \"$sysreport_dir/lsblk_O\""
+		else
+			log "$LSBLK >> \"$sysreport_dir/lsblk\""
+		fi
+		if $LSBLK --help | $GREP -- --inverse >/dev/null; then
+			log "$LSBLK -s >> \"$sysreport_dir/lsblk_s\""
+		fi
+	fi
+
+	if test -z "$SYSTEMCTL"; then
+		myecho "WARNING: systemctl not found"
+	elif test -z "$JOURNALCTL"; then
+		myecho "WARNING: journalctl not found"
+	else
+		log "$JOURNALCTL -b --no-pager -o short-precise > \"$sysreport_dir/journal_content\" 2>> \"$log\""
+		log "$SYSTEMCTL status -l --no-pager -n $log_lines -o short-precise dm-event.socket dm-event.service \
+						   lvm2-monitor.service \
+						   lvm2-lvmetad.socket lvm2-lvmetad.service \
+						   lvm2-lvmpolld.socket lvm2-lvmpolld.service \
+						   lvm2-cluster-activation.service \
+						   lvm2-clvmd.service \
+						   lvm2-cmirrord.service \
+						   lvm2-activation-early.service \
+						   lvm2-activation.service \
+						   lvm2-activation-net.service \
+						   > \"$sysreport_dir/systemd_lvm2_services_status\" 2>> \"$log\""
+		log "$SYSTEMCTL list-units -l -a --no-legend --no-pager > \"$sysreport_dir/systemd_unit_list\" 2>> \"$log\""
+		for unit in $(cat $sysreport_dir/systemd_unit_list | $GREP lvm2-pvscan | cut -d " " -f 1); do
+			log "$SYSTEMCTL status -l --no-pager -n $log_lines -o short-precise $unit >> \"$sysreport_dir/systemd_lvm2_pvscan_service_status\""
+		done
+	fi
+fi
+
+if (( $udev )); then
+	myecho "Gathering udev info..."
+
+	udev_dir="$dir/udev"
+
+	log "$MKDIR -p \"$udev_dir\""
+	log "$UDEVADM info --version >> \"$udev_dir/version\" 2>> \"$log\""
+	log "$UDEVADM info --export-db >> \"$udev_dir/db\" 2>> \"$log\""
+	log "$CP -a /etc/udev/udev.conf \"$udev_dir/conf\" 2>> \"$log\""
+	log "$LS -la /lib/udev >> \"$udev_dir/lib_dir\" 2>> \"$log\""
+	log "$CP -RL --preserve=all /etc/udev/rules.d \"$udev_dir/rules_etc\" 2>> \"$log\""
+	log "$CP -RL --preserve=all /lib/udev/rules.d \"$udev_dir/rules_lib\" 2>> \"$log\""
+fi
+
+if (( $lvmetad )); then
+    (echo 'request="dump"'; echo '##') | {
+	if type -p $SOCAT >& /dev/null; then
+	    echo "$SOCAT unix-connect:$LVMETAD_SOCKET -" >> "$log"
+	    $SOCAT "unix-connect:$LVMETAD_SOCKET" - 2>> "$log"
+	elif echo | $NC -U "$LVMETAD_SOCKET"; then
+	    echo "$NC -U $LVMETAD_SOCKET" >> "$log"
+	    $NC -U "$LVMETAD_SOCKET" 2>> "$log"
+	else
+	    myecho "WARNING: Neither socat nor nc -U seems to be available." 1>&2
+	    echo "# DUMP FAILED"
+	    return 1
+	fi
+    } > "$dir/lvmetad.txt"
+fi
+
+if (( $lvmpolld )); then
+    (echo 'request="dump"'; echo '##') | {
+	if type -p $SOCAT >& /dev/null; then
+	    echo "$SOCAT unix-connect:$LVMPOLLD_SOCKET -" >> "$log"
+	    $SOCAT "unix-connect:$LVMPOLLD_SOCKET" - 2>> "$log"
+	elif echo | $NC -U "$LVMPOLLD_SOCKET"; then
+	    echo "$NC -U $LVMPOLLD_SOCKET" >> "$log"
+	    $NC -U "$LVMPOLLD_SOCKET" 2>> "$log"
+	else
+	    myecho "WARNING: Neither socat nor nc -U seems to be available." 1>&2
+	    echo "# DUMP FAILED"
+	    return 1
+	fi
+    } > "$dir/lvmpolld.txt"
+fi
+
+if test -z "$userdir"; then
+	lvm_dump="$dirbase.tgz"
+	myecho "Creating report tarball in $HOME/$lvm_dump..."
+fi
+
+warnings
+
+if test -z "$userdir"; then
+	cd "$HOME"
+	"$TAR" czf "$lvm_dump" "$dirbase" 2>/dev/null
+	"$RM" -rf "$dir"
+fi
+
+exit 0




More information about the lvm-devel mailing list