Re: [dm-devel] [PATCH 3/3] multipathd: Add 'sysfs' prioritizer
On 11/09/2016 07:49 AM, Hannes Reinecke wrote: > On 11/08/2016 07:52 PM, Xose Vazquez Perez wrote: >> On 07/15/2016 08:48 AM, Hannes Reinecke wrote: >> >>> Recent kernels have an 'access_state' attribute which allows >>> us to read the asymmetric access state directly from sysfs. >> >> Hi Hannes, >> >> with this patch it's impossible to select/autodetect ALUA. >> sysfs always takes precedence over alua. >> >> "detect_prio no" was added to overrides section, to make >> it work again. >> >> SLES 12-SP2 >> >> Thank you. >> > But this was precisely the idea. > (After all, it says 'auto-detect', right?) > > For ALUA-capable arrays we have a reliable priority detection with the ALUA > device-handler. > So it's far preferable to use the sysfs-provided information (as they are > populated by the ALUA device-handler); the ALUA prioritizer in > multipath-tools will be used as a fallback in case the device > handler isn't loaded or the sysfs files are not present. > Using the sysfs handler has the neat side effect that you don't need to do > I/O for detecting the priority, thereby eliminating one possible cause for > multipath being stuck during failover. Thanks for the explanation. As collateral effect, because the sysfs-handler output is too brief, the asymmetric access state(aas) was lost: Dec 07 19:26:51 | sda: prio = sysfs (detected setting) Dec 07 19:26:51 | sda: sysfs prio = 50 Dec 07 19:26:29 | sdc: prio = alua (detected setting) Dec 07 19:26:29 | reported target port group is 1 <- lost Dec 07 19:26:29 | aas = 80 [active/optimized] [preferred] <- lost Dec 07 19:26:29 | sdc: alua prio = 50 -- dm-devel mailing list dm-devel@redhat.com https://www.redhat.com/mailman/listinfo/dm-devel
Re: [dm-devel] [PATCH 3/3] multipathd: Add 'sysfs' prioritizer
On 11/08/2016 07:52 PM, Xose Vazquez Perez wrote: On 07/15/2016 08:48 AM, Hannes Reinecke wrote: Recent kernels have an 'access_state' attribute which allows us to read the asymmetric access state directly from sysfs. Hi Hannes, with this patch it's impossible to select/autodetect ALUA. sysfs always takes precedence over alua. "detect_prio no" was added to overrides section, to make it work again. SLES 12-SP2 Thank you. But this was precisely the idea. (After all, it says 'auto-detect', right?) For ALUA-capable arrays we have a reliable priority detection with the ALUA device-handler. So it's far preferable to use the sysfs-provided information (as they are populated by the ALUA device-handler); the ALUA prioritizer in multipath-tools will be used as a fallback in case the device handler isn't loaded or the sysfs files are not present. Using the sysfs handler has the neat side effect that you don't need to do I/O for detecting the priority, thereby eliminating one possible cause for multipath being stuck during failover. Cheers, Hannes -- Dr. Hannes ReineckeTeamlead Storage & Networking h...@suse.de +49 911 74053 688 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton HRB 21284 (AG Nürnberg) -- dm-devel mailing list dm-devel@redhat.com https://www.redhat.com/mailman/listinfo/dm-devel
Re: [dm-devel] [PATCH 3/3] multipathd: Add 'sysfs' prioritizer
On 07/15/2016 08:48 AM, Hannes Reinecke wrote: > Recent kernels have an 'access_state' attribute which allows > us to read the asymmetric access state directly from sysfs. Hi Hannes, with this patch it's impossible to select/autodetect ALUA. sysfs always takes precedence over alua. "detect_prio no" was added to overrides section, to make it work again. SLES 12-SP2 Thank you. > --- > libmultipath/discovery.c | 33 + > libmultipath/discovery.h | 2 ++ > libmultipath/prio.h| 1 + > libmultipath/prioritizers/Makefile | 3 +- > libmultipath/prioritizers/sysfs.c | 61 > ++ > libmultipath/propsel.c | 6 +++- > multipath/multipath.conf.5 | 19 ++-- > 7 files changed, 120 insertions(+), 5 deletions(-) > create mode 100644 libmultipath/prioritizers/sysfs.c > [ ...] > diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c > index beb0798..0caf269 100644 > --- a/libmultipath/propsel.c > +++ b/libmultipath/propsel.c > @@ -375,6 +375,8 @@ detect_prio(struct config *conf, struct path * pp) > struct prio *p = >prio; > int tpgs = 0; > unsigned int timeout = conf->checker_timeout; > + char buff[512]; > + char *default_prio = PRIO_ALUA; > > if ((tpgs = get_target_port_group_support(pp->fd, timeout)) <= 0) > return; > @@ -384,7 +386,9 @@ detect_prio(struct config *conf, struct path * pp) > return; > if (get_asymmetric_access_state(pp->fd, ret, timeout) < 0) > return; > - prio_get(conf->multipath_dir, p, PRIO_ALUA, DEFAULT_PRIO_ARGS); > + if (sysfs_get_asymmetric_access_state(pp, buff, 512) >= 0) > + default_prio = PRIO_SYSFS; > + prio_get(conf->multipath_dir, p, default_prio, DEFAULT_PRIO_ARGS); > } -- dm-devel mailing list dm-devel@redhat.com https://www.redhat.com/mailman/listinfo/dm-devel
[dm-devel] [PATCH 3/3] multipathd: Add 'sysfs' prioritizer
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 | 61 ++ libmultipath/propsel.c | 6 +++- multipath/multipath.conf.5 | 19 ++-- 7 files changed, 120 insertions(+), 5 deletions(-) create mode 100644 libmultipath/prioritizers/sysfs.c diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c index e9e0313..07c60cf 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c @@ -209,6 +209,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, @@ -484,6 +486,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, , 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 321d930..0f5b1e6 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 7195986..032028e 100644 --- a/libmultipath/prio.h +++ b/libmultipath/prio.h @@ -30,6 +30,7 @@ struct path; #define PRIO_RANDOM"random" #define PRIO_RDAC "rdac" #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 903a139..bb76700 100644 --- a/libmultipath/prioritizers/Makefile +++ b/libmultipath/prioritizers/Makefile @@ -15,7 +15,8 @@ LIBS = \ libprioontap.so \ libpriorandom.so \ libpriordac.so \ - libprioweightedpath.so + libprioweightedpath.so \ + libpriosysfs.so CFLAGS += -I.. diff --git a/libmultipath/prioritizers/sysfs.c b/libmultipath/prioritizers/sysfs.c new file mode 100644 index 000..ff567df --- /dev/null +++ b/libmultipath/prioritizers/sysfs.c @@ -0,0 +1,61 @@ +/* + * 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 get_exclusive_pref_arg(char *args) +{ + char *ptr; + + if (args == NULL) + return 0; + ptr = strstr(args, "exclusive_pref_bit"); + if (!ptr) + return 0; + if (ptr[18] != '\0' && ptr[18] != ' ' && ptr[18] != '\t') + return 0; + if (ptr != args && ptr[-1] != ' ' && ptr[-1] != '\t') + return 0; + return 1; +} + +int getprio (struct path * pp, char * args, unsigned int timeout) +{ + int prio = 0, rc, i; + char buff[512]; + int exclusive_pref; + + exclusive_pref = get_exclusive_pref_arg(args); + 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,