dm-devel.redhat.com archive mirror
 help / color / mirror / Atom feed
From: "Benjamin Marzinski" <bmarzins@redhat.com>
To: device-mapper development <dm-devel@redhat.com>
Cc: Christophe Varoqui <christophe.varoqui@gmail.com>
Subject: [PATCH 07/17] libmultipath: Cut down on alua prioritizer ioctls
Date: Mon, 28 Mar 2016 22:13:04 -0500	[thread overview]
Message-ID: <1459221194-23222-8-git-send-email-bmarzins@redhat.com> (raw)
In-Reply-To: <1459221194-23222-1-git-send-email-bmarzins@redhat.com>

Currently, running the alua prioritizer on a path causes 5 ioctls on
many devices.  get_target_port_group_support() returns whether alua is
supported. get_target_port_group() gets the TPG id. This often takes two
ioctls because 128 bytes is not a large enough buffer size on many
devices. Finally, get_asymmetric_access_state() also often takes two
ioctls because of the buffer size. This can get to be problematic when
there are thousands of paths.  The goal of this patch to to cut this
down to one call in the usual case.

In order to do this, get_target_port_group_support() is now only called
when get_target_port_group() fails, to provide a more useful error
message. Also, before doing an SGIO ioctl to get the vpd83 data,
multipath first tries to read it from sysfs.

Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
 libmultipath/discovery.h              |  2 +
 libmultipath/prioritizers/alua.c      | 24 ++++++------
 libmultipath/prioritizers/alua_rtpg.c | 69 ++++++++++++++++++++++++-----------
 libmultipath/prioritizers/alua_rtpg.h |  2 +-
 libmultipath/propsel.c                |  2 +-
 5 files changed, 63 insertions(+), 36 deletions(-)

diff --git a/libmultipath/discovery.h b/libmultipath/discovery.h
index da7652c..5931bc6 100644
--- a/libmultipath/discovery.h
+++ b/libmultipath/discovery.h
@@ -45,6 +45,8 @@ int sysfs_set_scsi_tmo (struct multipath *mpp);
 int sysfs_get_timeout(struct path *pp, unsigned int *timeout);
 int sysfs_get_host_pci_name(struct path *pp, char *pci_name);
 int sysfs_get_iscsi_ip_address(struct path *pp, char *ip_address);
+ssize_t sysfs_get_vpd (struct udev_device * udev, int pg, unsigned char * buff,
+		       size_t len);
 
 /*
  * discovery bitmask
diff --git a/libmultipath/prioritizers/alua.c b/libmultipath/prioritizers/alua.c
index 39ed1c8..0bd374f 100644
--- a/libmultipath/prioritizers/alua.c
+++ b/libmultipath/prioritizers/alua.c
@@ -51,24 +51,22 @@ static const char *aas_print_string(int rc)
 }
 
 int
-get_alua_info(int fd)
+get_alua_info(struct path * pp)
 {
 	int	rc;
 	int	tpg;
 
-	rc = get_target_port_group_support(fd);
-	if (rc < 0)
-		return -ALUA_PRIO_TPGS_FAILED;
-
-	if (rc == TPGS_NONE)
-		return -ALUA_PRIO_NOT_SUPPORTED;
-
-	tpg = get_target_port_group(fd);
-	if (tpg < 0)
+	tpg = get_target_port_group(pp);
+	if (tpg < 0) {
+		rc = get_target_port_group_support(pp->fd);
+		if (rc < 0)
+			return -ALUA_PRIO_TPGS_FAILED;
+		if (rc == TPGS_NONE)
+			return -ALUA_PRIO_NOT_SUPPORTED;
 		return -ALUA_PRIO_RTPG_FAILED;
-
+	}
 	condlog(3, "reported target port group is %i", tpg);
-	rc = get_asymmetric_access_state(fd, tpg);
+	rc = get_asymmetric_access_state(pp->fd, tpg);
 	if (rc < 0)
 		return -ALUA_PRIO_GETAAS_FAILED;
 
@@ -86,7 +84,7 @@ int getprio (struct path * pp, char * args)
 	if (pp->fd < 0)
 		return -ALUA_PRIO_NO_INFORMATION;
 
-	rc = get_alua_info(pp->fd);
+	rc = get_alua_info(pp);
 	if (rc >= 0) {
 		aas = (rc & 0x0f);
 		priopath = (rc & 0x80);
diff --git a/libmultipath/prioritizers/alua_rtpg.c b/libmultipath/prioritizers/alua_rtpg.c
index 6d04fc1..636aae5 100644
--- a/libmultipath/prioritizers/alua_rtpg.c
+++ b/libmultipath/prioritizers/alua_rtpg.c
@@ -17,15 +17,18 @@
 #include <string.h>
 #include <sys/ioctl.h>
 #include <inttypes.h>
+#include <libudev.h>
 
 #define __user
 #include <scsi/sg.h>
 
+#include "../structs.h"
 #include "../prio.h"
+#include "../discovery.h"
 #include "alua_rtpg.h"
 
 #define SENSE_BUFF_LEN  32
-#define DEF_TIMEOUT     60000
+#define SGIO_TIMEOUT     60000
 
 /*
  * Macro used to print debug messaged.
@@ -135,7 +138,7 @@ do_inquiry(int fd, int evpd, unsigned int codepage, void *resp, int resplen)
 	hdr.dxfer_len		= resplen;
 	hdr.sbp			= sense;
 	hdr.mx_sb_len		= sizeof(sense);
-	hdr.timeout		= get_prio_timeout(DEF_TIMEOUT);
+	hdr.timeout		= get_prio_timeout(SGIO_TIMEOUT);
 
 	if (ioctl(fd, SG_IO, &hdr) < 0) {
 		PRINT_DEBUG("do_inquiry: IOCTL failed!\n");
@@ -170,8 +173,27 @@ get_target_port_group_support(int fd)
 	return rc;
 }
 
+static int
+get_sysfs_pg83(struct path *pp, unsigned char *buff, int buflen)
+{
+	struct udev_device *parent = pp->udev;
+
+	while (parent) {
+		const char *subsys = udev_device_get_subsystem(parent);
+		if (subsys && !strncmp(subsys, "scsi", 4))
+			break;
+		parent = udev_device_get_parent(parent);
+	}
+
+	if (!parent || sysfs_get_vpd(parent, 0x83, buff, buflen) <= 0) {
+		PRINT_DEBUG("failed to read sysfs vpd pg83\n");
+		return -1;
+	}
+	return 0;
+}
+
 int
-get_target_port_group(int fd)
+get_target_port_group(struct path * pp)
 {
 	unsigned char		*buf;
 	struct vpd83_data *	vpd83;
@@ -179,7 +201,7 @@ get_target_port_group(int fd)
 	int			rc;
 	int			buflen, scsi_buflen;
 
-	buflen = 128; /* Lets start from 128 */
+	buflen = 4096;
 	buf = (unsigned char *)malloc(buflen);
 	if (!buf) {
 		PRINT_DEBUG("malloc failed: could not allocate"
@@ -188,24 +210,29 @@ get_target_port_group(int fd)
 	}
 
 	memset(buf, 0, buflen);
-	rc = do_inquiry(fd, 1, 0x83, buf, buflen);
-	if (rc < 0)
-		goto out;
 
-	scsi_buflen = (buf[2] << 8 | buf[3]) + 4;
-	if (buflen < scsi_buflen) {
-		free(buf);
-		buf = (unsigned char *)malloc(scsi_buflen);
-		if (!buf) {
-			PRINT_DEBUG("malloc failed: could not allocate"
-				     "%u bytes\n", scsi_buflen);
-			return -RTPG_RTPG_FAILED;
-		}
-		buflen = scsi_buflen;
-		memset(buf, 0, buflen);
-		rc = do_inquiry(fd, 1, 0x83, buf, buflen);
+	rc = get_sysfs_pg83(pp, buf, buflen);
+
+	if (rc < 0) {
+		rc = do_inquiry(pp->fd, 1, 0x83, buf, buflen);
 		if (rc < 0)
 			goto out;
+
+		scsi_buflen = (buf[2] << 8 | buf[3]) + 4;
+		if (buflen < scsi_buflen) {
+			free(buf);
+			buf = (unsigned char *)malloc(scsi_buflen);
+			if (!buf) {
+				PRINT_DEBUG("malloc failed: could not allocate"
+					    "%u bytes\n", scsi_buflen);
+				return -RTPG_RTPG_FAILED;
+			}
+			buflen = scsi_buflen;
+			memset(buf, 0, buflen);
+			rc = do_inquiry(pp->fd, 1, 0x83, buf, buflen);
+			if (rc < 0)
+				goto out;
+		}
 	}
 
 	vpd83 = (struct vpd83_data *) buf;
@@ -254,7 +281,7 @@ do_rtpg(int fd, void* resp, long resplen)
 	hdr.dxfer_len		= resplen;
 	hdr.mx_sb_len		= sizeof(sense);
 	hdr.sbp			= sense;
-	hdr.timeout		= get_prio_timeout(DEF_TIMEOUT);
+	hdr.timeout		= get_prio_timeout(SGIO_TIMEOUT);
 
 	if (ioctl(fd, SG_IO, &hdr) < 0)
 		return -RTPG_RTPG_FAILED;
@@ -278,7 +305,7 @@ get_asymmetric_access_state(int fd, unsigned int tpg)
 	int			buflen;
 	uint32_t		scsi_buflen;
 
-	buflen = 128; /* Initial value from old code */
+	buflen = 4096;
 	buf = (unsigned char *)malloc(buflen);
 	if (!buf) {
 		PRINT_DEBUG ("malloc failed: could not allocate"
diff --git a/libmultipath/prioritizers/alua_rtpg.h b/libmultipath/prioritizers/alua_rtpg.h
index c43e0a9..91a15a4 100644
--- a/libmultipath/prioritizers/alua_rtpg.h
+++ b/libmultipath/prioritizers/alua_rtpg.h
@@ -23,7 +23,7 @@
 #define RTPG_TPG_NOT_FOUND			4
 
 int get_target_port_group_support(int fd);
-int get_target_port_group(int fd);
+int get_target_port_group(struct path * pp);
 int get_asymmetric_access_state(int fd, unsigned int tpg);
 
 #endif /* __RTPG_H__ */
diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c
index 890d4b1..8abe360 100644
--- a/libmultipath/propsel.c
+++ b/libmultipath/propsel.c
@@ -378,7 +378,7 @@ detect_prio(struct path * pp)
 	if ((tpgs = get_target_port_group_support(pp->fd)) <= 0)
 		return;
 	pp->tpgs = tpgs;
-	ret = get_target_port_group(pp->fd);
+	ret = get_target_port_group(pp);
 	if (ret < 0)
 		return;
 	if (get_asymmetric_access_state(pp->fd, ret) < 0)
-- 
1.8.3.1

  parent reply	other threads:[~2016-03-29  3:13 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-03-29  3:12 [PATCH 00/17] Multipath patch sync Benjamin Marzinski
2016-03-29  3:12 ` [PATCH 01/17] multipathd: use /run instead of /var/run Benjamin Marzinski
2016-03-29 13:57   ` John Stoffel
2016-03-30  0:41     ` Benjamin Marzinski
2016-03-30 16:06       ` John Stoffel
2016-03-29  3:12 ` [PATCH 02/17] retrigger uevents to try and get the uid through udev Benjamin Marzinski
2016-03-29  3:13 ` [PATCH 03/17] Fix issues with user_friendly_names initramfs bindings Benjamin Marzinski
2016-03-29  3:13 ` [PATCH 04/17] Add libmpathcmd library and use it internally Benjamin Marzinski
2016-03-29  3:13 ` [PATCH 05/17] libmultipath: add ignore_new_boot_devs option Benjamin Marzinski
2016-03-29  3:13 ` [PATCH 06/17] libmultipath: fix PAD and PRINT macros Benjamin Marzinski
2016-03-29  3:13 ` Benjamin Marzinski [this message]
2016-03-29  3:13 ` [PATCH 08/17] multipathd: fail if pidfile can't be created Benjamin Marzinski
2016-03-29  3:13 ` [PATCH 09/17] libmultipath: check correct function for define Benjamin Marzinski
2016-03-29  3:13 ` [PATCH 10/17] multipathd: delay reloads during creation Benjamin Marzinski
2016-03-29 14:02   ` John Stoffel
2016-03-30  0:57     ` Benjamin Marzinski
2016-03-29  3:13 ` [PATCH 11/17] multipath: Fix minor text issues Benjamin Marzinski
2016-03-29  3:13 ` [PATCH 12/17] kpartx: verify partition devices Benjamin Marzinski
2016-03-29  3:13 ` [PATCH 13/17] multipath: add exclusive_pref_bit for alua prio Benjamin Marzinski
2016-03-29  3:13 ` [PATCH 14/17] multipathd: print "fail" when remove fails Benjamin Marzinski
2016-03-29  3:13 ` [PATCH 15/17] multipath: check partitions unused before removing Benjamin Marzinski
2016-03-29  3:13 ` [PATCH 16/17] multipathd.service: remove blk-availability Requires Benjamin Marzinski
2016-03-29  3:13 ` [PATCH 17/17] multipathd: use 64-bit int for command key Benjamin Marzinski
2016-04-07  2:10   ` multipathd: segfault in multipathd cli_add_map() Zhangguanghui

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1459221194-23222-8-git-send-email-bmarzins@redhat.com \
    --to=bmarzins@redhat.com \
    --cc=christophe.varoqui@gmail.com \
    --cc=dm-devel@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).