Add -c to zpool iostat & status to run command

This patch adds a command (-c) option to zpool status and zpool iostat.  The
-c option allows you to run an arbitrary command on each vdev and display
the first line of output in zpool status/iostat.  The environment vars
VDEV_PATH and VDEV_UPATH are set to the vdev's path and "underlying path"
before running the command.  For device mapper, multipath, or partitioned
vdevs, VDEV_UPATH is the actual underlying /dev/sd* disk.  This can be useful
if the command you're running requires a /dev/sd* device.

The patch also uses /sys/block/<dev>/slaves/ to lookup the underlying device
instead of using libdevmapper.  This not only removes the libdevmapper
requirement at build time, but also allows you to resolve device mapper
devices without being root.  This means that UDEV_UPATH get set correctly
when running zpool status/iostat as an unprivileged user.

Example:

$ zpool status -c 'echo I am $VDEV_PATH, $VDEV_UPATH'

NAME        STATE     READ WRITE CKSUM
mypool      ONLINE       0     0     0
  mirror-0  ONLINE       0     0     0
    mpatha  ONLINE       0     0     0  I am /dev/mapper/mpatha, /dev/sdc
    sdb     ONLINE       0     0     0  I am /dev/sdb1, /dev/sdb

Reviewed-by: Giuseppe Di Natale <dinatale2@llnl.gov>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Tony Hutter <hutter2@llnl.gov>
Closes #5368
This commit is contained in:
Tony Hutter
2016-11-29 13:45:38 -08:00
committed by Brian Behlendorf
parent 2f71caf2d9
commit 8720e9e748
16 changed files with 486 additions and 136 deletions
@@ -69,6 +69,21 @@ check_pool_status
log_must eval "$ZPOOL status -v $TESTPOOL > /tmp/pool-status.$$"
check_pool_status
# Make sure -c option works, and that VDEV_PATH and VDEV_UPATH get set.
#
# grep for '^\s+/' to just get the vdevs (not pools). All vdevs will start with
# a '/' when we specify the path (-P) flag. We check for "{}" to see if one
# of the VDEV variables isn't set.
C1=$($ZPOOL status -P | $GREP -E '^\s+/' | $WC -l)
C2=$($ZPOOL status -P -c 'echo vdev_test{$VDEV_PATH}{$VDEV_UPATH}' | \
$GREP -E '^\s+/' | $GREP -v '{}' | $WC -l)
if [ "$C1" != "$C2" ] ; then
log_fail "zpool status -c option failed. Expected $C1 vdevs, got $C2"
else
log_pass "zpool status -c option passed. Expected $C1 vdevs, got $C2"
fi
# $TESTPOOL.virt has an offline device, so -x will show it
log_must eval "$ZPOOL status -x $TESTPOOL.virt > /tmp/pool-status.$$"
check_pool_status