Gitweb:
http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=5da35d879ad073...
Commit: 5da35d879ad073d9fb0d7ec8bfabe9ae39ac5bc1
Parent: d455300d7baff341f1c7fe5776d975369dd3a23a
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Thu Sep 15 13:59:52 2016 +0100
Committer: Alasdair G Kergon <agk(a)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@.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@.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@.service")
CONFIG_FILES="$CONFIG_FILES scripts/lvm2_pvscan_systemd_red_hat@.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@.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