Change in vdsm[master]: storage: Add multipath-resize command line tool

nsoffer at redhat.com nsoffer at redhat.com
Mon Mar 9 00:08:39 UTC 2015


Nir Soffer has uploaded a new change for review.

Change subject: storage: Add multipath-resize command line tool
......................................................................

storage: Add multipath-resize command line tool

multipath-resize resizes online multipath device after a LUN was resized
on the storage server.

Since this operation requires SCSI scanning all device paths, and SCSI
scan may block for long time when a storage server is inaccessible, this
must be performed out of Vdsm process.

Having a separate command line tool is also useful for debugging and
administration.

Vdsm is expected to use this tool without options, logging stderr on
errors. For debugging, it is useful to use the -v option to get verbose
logging.

Unfinished:
- Run as root from multipath.resize(guid) using sudoers rule. When
  supervdsm is fixed to reap zombies, we can move this into supervdsm.
- Use same scsi timeouts as hba.rescan()?

Change-Id: I229ef55555fa757989329939a9267041785f2c0f
Signed-off-by: Nir Soffer <nsoffer at redhat.com>
---
M Makefile.am
M debian/vdsm.install
M vdsm.spec.in
M vdsm/storage/Makefile.am
A vdsm/storage/multipath-resize
5 files changed, 154 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/67/38467/1

diff --git a/Makefile.am b/Makefile.am
index 34885a1..69b62ca 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -88,6 +88,7 @@
 	vdsm/vdsm-restore-net-config \
 	vdsm/storage/curl-img-wrap \
 	vdsm/storage/fc-scan \
+	vdsm/storage/multipath-resize \
 	vdsm-tool/vdsm-tool \
 	vds_bootstrap/setup \
 	vdsm_reg/vdsm-reg-setup.in \
diff --git a/debian/vdsm.install b/debian/vdsm.install
index 16a17ed..f3e15b6 100644
--- a/debian/vdsm.install
+++ b/debian/vdsm.install
@@ -26,6 +26,7 @@
 ./var/lib/vdsm/bonding-defaults.json
 ./usr/libexec/vdsm/curl-img-wrap
 ./usr/libexec/vdsm/fc-scan
+./usr/libexec/vdsm/multipath-resize
 ./usr/libexec/vdsm/ovirt_functions.sh
 ./usr/libexec/vdsm/persist-vdsm-hooks
 ./usr/libexec/vdsm/safelease
diff --git a/vdsm.spec.in b/vdsm.spec.in
index 65fda22..4d557c3 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -1103,6 +1103,7 @@
 %{_datadir}/%{vdsm_name}/dsaversion.py*
 %{_libexecdir}/%{vdsm_name}/curl-img-wrap
 %{_libexecdir}/%{vdsm_name}/fc-scan
+%{_libexecdir}/%{vdsm_name}/multipath-resize
 %{_libexecdir}/%{vdsm_name}/persist-vdsm-hooks
 %{_libexecdir}/%{vdsm_name}/unpersist-vdsm-hook
 %{_libexecdir}/%{vdsm_name}/ovirt_functions.sh
diff --git a/vdsm/storage/Makefile.am b/vdsm/storage/Makefile.am
index 4ebe0a2..a6007dd 100644
--- a/vdsm/storage/Makefile.am
+++ b/vdsm/storage/Makefile.am
@@ -74,6 +74,7 @@
 dist_vdsmexec_SCRIPTS = \
 	curl-img-wrap \
 	fc-scan \
+	multipath-resize \
 	$(NULL)
 
 nodist_vdsmstorage_DATA = \
diff --git a/vdsm/storage/multipath-resize b/vdsm/storage/multipath-resize
new file mode 100755
index 0000000..6cc7354
--- /dev/null
+++ b/vdsm/storage/multipath-resize
@@ -0,0 +1,150 @@
+#!/usr/bin/python
+#
+# Copyright 2015 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# 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
+#
+# Refer to the README and COPYING files for full details of the license
+#
+
+"""
+Usage: multipath-resize [-v|-h] device-name
+
+Resize online multipath device. Perform SCSI rescan for each path and resize
+the multipath map.
+
+Options:
+  -v        enable verbose logging
+  -h        display this help and exit
+
+Exit codes:
+  0         device resized successfuly
+  1         operation failed
+  2         usage error
+
+Examples:
+
+  Find multipath devices:
+
+    # multipath -l
+    360060160f4a0300063f640056066e411 dm-3 DGC     ,VRAID
+    size=50G features='0' hwhandler='1 emc' wp=rw
+    |-+- policy='service-time 0' prio=0 status=active
+    | |- 27:0:0:1  sdt 65:48  active undef running
+    | `- 29:0:0:1  sdx 65:112 active undef running
+    `-+- policy='service-time 0' prio=0 status=enabled
+      |- 23:0:0:1  sdd 8:48   active undef running
+      `- 30:0:0:1  sdb 8:16   active undef running
+
+  Resize device 360060160f4a0300063f640056066e411:
+
+    # multipath-resize 360060160f4a0300063f640056066e411
+"""
+
+import logging
+import os
+import subprocess
+import sys
+
+from vdsm import concurrent
+from vdsm import utils
+
+MULTIPATHD = utils.CommandPath("multipathd",
+                               "/usr/sbin/multipathd",
+                               "/sbin/multipathd")
+
+log = logging.getLogger("multipath-resize")
+
+
+class Error(Exception):
+    """ multipath-resize error """
+
+
+def main(args):
+    if "-h" in args:
+        print __doc__
+        return 0
+
+    if "-v" in args:
+        loglevel = logging.DEBUG
+        args.remove("-v")
+    else:
+        loglevel = logging.INFO
+
+    logging.basicConfig(level=loglevel, format="%(name)s: %(message)s")
+
+    if not args:
+        log.error("No device name specified")
+        return 2
+
+    guid = args[0]
+    log.debug("Resizing device %s", guid)
+    try:
+        scans = concurrent.tmap(rescan_path, list_paths(guid))
+
+        if not all(s.succeeded for s in scans):
+            raise Error("Scanning paths failed")
+
+        resize_map(guid)
+    except Error as e:
+        log.error("Resizing device %s failed: %s", guid, e)
+        return 1
+    except Exception:
+        log.exception("Unexpected error")
+        return 1
+
+    return 0
+
+
+def list_paths(guid):
+    st = os.stat("/dev/mapper/%s" % guid)
+    minor = os.minor(st.st_rdev)
+    return os.listdir("/sys/block/dm-%d/slaves" % minor)
+
+
+def rescan_path(name):
+    try:
+        log.debug("Rescanning path %s", name)
+        path = "/sys/block/%s/device/rescan" % name
+        start = utils.monotonic_time()
+        fd = os.open(path, os.O_WRONLY)
+        try:
+            os.write(fd, "1")
+        finally:
+            os.close(fd)
+        elapsed = utils.monotonic_time() - start
+        log.debug("Scanned path %s in %.2f seconds", name, elapsed)
+    except OSError as e:
+        log.error("Rescanning path %s failed: %s", name, e)
+        raise
+    except Exception:
+        log.exception("Unexpected error")
+        raise
+
+
+def resize_map(guid):
+    log.debug("Resizing map %s", guid)
+    cmd = [MULTIPATHD.cmd, "-k'resize map %s'" % guid]
+    start = utils.monotonic_time()
+    p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+    out, err = p.communicate()
+    if p.returncode != 0:
+        raise Error("Resizing map %s failed: %s" % (guid, err))
+    elapsed = utils.monotonic_time() - start
+    log.debug("Resized map %s in %.2f seconds", guid, elapsed)
+
+
+if __name__ == '__main__':
+    sys.exit(main(sys.argv[1:]))


-- 
To view, visit https://gerrit.ovirt.org/38467
To unsubscribe, visit https://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I229ef55555fa757989329939a9267041785f2c0f
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Nir Soffer <nsoffer at redhat.com>


More information about the vdsm-patches mailing list