From patchwork Mon May 23 10:20:28 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hannes Reinecke X-Patchwork-Id: 9131423 X-Patchwork-Delegate: snitzer@redhat.com Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 7DA79607D3 for ; Mon, 23 May 2016 10:24:39 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 654C528220 for ; Mon, 23 May 2016 10:24:39 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 58C4B2822B; Mon, 23 May 2016 10:24:39 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from mx6-phx2.redhat.com (mx6-phx2.redhat.com [209.132.183.39]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id C459028220 for ; Mon, 23 May 2016 10:24:38 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by mx6-phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u4NAKYA1052513; Mon, 23 May 2016 06:20:35 -0400 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id u4NAKWPk011029 for ; Mon, 23 May 2016 06:20:32 -0400 Received: from mx1.redhat.com (ext-mx10.extmail.prod.ext.phx2.redhat.com [10.5.110.39]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u4NAKWUV012016 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Mon, 23 May 2016 06:20:32 -0400 Received: from mx2.suse.de (mx2.suse.de [195.135.220.15]) (using TLSv1 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 23E8F63311; Mon, 23 May 2016 10:20:31 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id C44A8AC61; Mon, 23 May 2016 10:20:29 +0000 (UTC) From: Hannes Reinecke To: Christophe Varoqui Date: Mon, 23 May 2016 12:20:28 +0200 Message-Id: <1463998828-28133-1-git-send-email-hare@suse.de> X-Greylist: Sender IP whitelisted by DNSRBL, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Mon, 23 May 2016 10:20:31 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Mon, 23 May 2016 10:20:31 +0000 (UTC) for IP:'195.135.220.15' DOMAIN:'mx2.suse.de' HELO:'mx2.suse.de' FROM:'hare@suse.de' RCPT:'' X-RedHat-Spam-Score: -3.327 (BAYES_50, DCC_REPUT_00_12, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, SPF_PASS) 195.135.220.15 mx2.suse.de 195.135.220.15 mx2.suse.de X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Scanned-By: MIMEDefang 2.78 on 10.5.110.39 X-loop: dm-devel@redhat.com Cc: dm-devel@redhat.com Subject: [dm-devel] multipathd: Add 'sysfs' prioritizer X-BeenThere: dm-devel@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: device-mapper development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: dm-devel-bounces@redhat.com Errors-To: dm-devel-bounces@redhat.com X-Virus-Scanned: ClamAV using ClamSMTP Recent kernels have an 'access_state' attribute which allows us to read the asymmetric access state directly from sysfs. Signed-off-by: Hannes Reinecke --- libmultipath/discovery.c | 33 +++++++++++++++++++++++++++++ libmultipath/discovery.h | 2 ++ libmultipath/prio.h | 1 + libmultipath/prioritizers/Makefile | 3 ++- libmultipath/prioritizers/sysfs.c | 43 ++++++++++++++++++++++++++++++++++++++ libmultipath/propsel.c | 6 +++++- multipath/multipath.conf.5 | 14 ++++++++++++- 7 files changed, 99 insertions(+), 3 deletions(-) create mode 100644 libmultipath/prioritizers/sysfs.c diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c index a364056..4a4b828 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c @@ -208,6 +208,8 @@ declare_sysfs_get_str(devtype); declare_sysfs_get_str(vendor); declare_sysfs_get_str(model); declare_sysfs_get_str(rev); +declare_sysfs_get_str(access_state); +declare_sysfs_get_str(preferred_path); ssize_t sysfs_get_vpd (struct udev_device * udev, int pg, @@ -483,6 +485,37 @@ int sysfs_get_iscsi_ip_address(struct path *pp, char *ip_address) return 1; } +int +sysfs_get_asymmetric_access_state(struct path *pp, char *buff, int buflen) +{ + struct udev_device *parent = pp->udev; + char value[16], *eptr; + unsigned int preferred; + + 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) + return -1; + + if (sysfs_get_access_state(parent, buff, buflen) <= 0) + return -1; + + if (sysfs_get_preferred_path(parent, value, 16) <= 0) + return 0; + + preferred = strtoul(value, &eptr, 0); + if (value == eptr || preferred == ULONG_MAX) { + /* Parse error, ignore */ + return 0; + } + return preferred; +} + static void sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp) { diff --git a/libmultipath/discovery.h b/libmultipath/discovery.h index 5931bc6..b45c802 100644 --- a/libmultipath/discovery.h +++ b/libmultipath/discovery.h @@ -47,6 +47,8 @@ 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); +int sysfs_get_asymmetric_access_state(struct path *pp, + char *buff, int buflen); /* * discovery bitmask diff --git a/libmultipath/prio.h b/libmultipath/prio.h index 495688f..65abf54 100644 --- a/libmultipath/prio.h +++ b/libmultipath/prio.h @@ -29,6 +29,7 @@ struct path; #define PRIO_RDAC "rdac" #define PRIO_DATACORE "datacore" #define PRIO_WEIGHTED_PATH "weightedpath" +#define PRIO_SYSFS "sysfs" /* * Value used to mark the fact prio was not defined diff --git a/libmultipath/prioritizers/Makefile b/libmultipath/prioritizers/Makefile index 6cfac88..0d1857f 100644 --- a/libmultipath/prioritizers/Makefile +++ b/libmultipath/prioritizers/Makefile @@ -15,7 +15,8 @@ LIBS = \ libpriodatacore.so \ libpriohds.so \ libprioweightedpath.so \ - libprioiet.so + libprioiet.so \ + libpriosysfs.so CFLAGS += -I.. diff --git a/libmultipath/prioritizers/sysfs.c b/libmultipath/prioritizers/sysfs.c new file mode 100644 index 0000000..35a5c83 --- /dev/null +++ b/libmultipath/prioritizers/sysfs.c @@ -0,0 +1,43 @@ +/* + * sysfs.c + * + * Copyright(c) 2016 Hannes Reinecke, SUSE Linux GmbH + */ + +#include + +#include "structs.h" +#include "discovery.h" +#include "prio.h" + +static const struct { + unsigned char value; + char *name; +} sysfs_access_state_map[] = { + { 50, "active/optimized" }, + { 10, "active/non-optimized" }, + { 5, "lba-dependent" }, + { 1, "standby" }, +}; + +int getprio (struct path * pp, char * args) +{ + int prio = 0, rc, i; + char buff[512]; + + rc = sysfs_get_asymmetric_access_state(pp, buff, 512); + if (rc < 0) + return PRIO_UNDEF; + prio = 0; + for (i = 0; i < 4; i++) { + if (!strncmp(buff, sysfs_access_state_map[i].name, + strlen(sysfs_access_state_map[i].name))) { + prio = sysfs_access_state_map[i].value; + break; + } + } + if (rc > 0) + prio += 80; + + return prio; +} diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c index 8abe360..b0182de 100644 --- a/libmultipath/propsel.c +++ b/libmultipath/propsel.c @@ -374,6 +374,7 @@ detect_prio(struct path * pp) int ret; struct prio *p = &pp->prio; int tpgs = 0; + char buff[512]; if ((tpgs = get_target_port_group_support(pp->fd)) <= 0) return; @@ -383,7 +384,10 @@ detect_prio(struct path * pp) return; if (get_asymmetric_access_state(pp->fd, ret) < 0) return; - prio_get(p, PRIO_ALUA, DEFAULT_PRIO_ARGS); + if (sysfs_get_asymmetric_access_state(pp, buff, 512) < 0) + prio_get(p, PRIO_ALUA, DEFAULT_PRIO_ARGS); + else + prio_get(p, PRIO_SYSFS, DEFAULT_PRIO_ARGS); } #define set_prio(src, msg) \ diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 index 2ff88c4..aaaa01b 100644 --- a/multipath/multipath.conf.5 +++ b/multipath/multipath.conf.5 @@ -203,6 +203,10 @@ Generate the path priority for NetApp arrays. .B rdac Generate the path priority for LSI/Engenio/NetApp E-Series RDAC controller. .TP +.B sysfs +Use the sysfs attributes access_state and preferred_path to generate the +path priority. +.TP .B hp_sw Generate the path priority for Compaq/HP controller in active/standby mode. @@ -449,8 +453,16 @@ If set to .I yes , multipath will try to detect if the device supports ALUA. If so, the device will automatically use the +.I sysfs +prioritizer if the required sysfs attributes +.I access_state +and +.I preferred_path +are supported, or the .I alua -prioritizer. If not, the prioritizer will be selected as usual. Default is +prioritizer if not. If set to +.I no +, the prioritizer will be selected as usual. Default is .I no .TP .B force_sync