libmultipath: detect_prio: try ANA for NVMe
authorMartin Wilck <mwilck@suse.com>
Sun, 23 Dec 2018 22:21:22 +0000 (23:21 +0100)
committerChristophe Varoqui <christophe.varoqui@opensvc.com>
Mon, 7 Jan 2019 10:46:40 +0000 (11:46 +0100)
Check NVMe devices support ANA, and if yes, use ANA
for priority checks. The patch moves the ANA detection
functionality from the ANA prioritizer into generic code,
and uses it.

Cc: lijie <lijie34@huawei.com>
Signed-off-by: Martin Wilck <mwilck@suse.com>
libmultipath/Makefile
libmultipath/nvme-lib.c
libmultipath/nvme-lib.h
libmultipath/prioritizers/ana.c
libmultipath/propsel.c

index 7d27ea7..78cca5a 100644 (file)
@@ -47,6 +47,7 @@ OBJS = memory.o parser.o vector.o devmapper.o callout.o \
 
 ifneq ($(call check_file,/usr/include/linux/nvme_ioctl.h),0)
        OBJS += nvme-lib.o
+       CFLAGS += -Invme
 endif
 
 all: $(LIBS)
index 9c32f36..f30e769 100644 (file)
@@ -34,3 +34,16 @@ int libmp_nvme_ana_log(int fd, void *ana_log, size_t ana_log_len, int rgo)
 {
        return nvme_ana_log(fd, ana_log, ana_log_len, rgo);
 }
+
+int nvme_id_ctrl_ana(int fd, struct nvme_id_ctrl *ctrl)
+{
+       int rc;
+       struct nvme_id_ctrl c;
+
+       rc = nvme_identify_ctrl(fd, &c);
+       if (rc < 0)
+               return rc;
+       if (ctrl)
+               *ctrl = c;
+       return c.cmic & (1 << 3) ? 1 : 0;
+}
index 445c4f4..448dd99 100644 (file)
@@ -9,6 +9,12 @@ int libmp_nvme_identify_ctrl(int fd, struct nvme_id_ctrl *ctrl);
 int libmp_nvme_identify_ns(int fd, __u32 nsid, bool present,
                           struct nvme_id_ns *ns);
 int libmp_nvme_ana_log(int fd, void *ana_log, size_t ana_log_len, int rgo);
+/*
+ * Identify controller, and return true if ANA is supported
+ * ctrl will be filled in if controller is identified, even w/o ANA
+ * ctrl may be NULL
+ */
+int nvme_id_ctrl_ana(int fd, struct nvme_id_ctrl *ctrl);
 
 #ifndef _NVME_LIB_C
 /*
index 6000d54..990d935 100644 (file)
@@ -116,13 +116,11 @@ int get_ana_info(struct path * pp, unsigned int timeout)
        size_t ana_log_len;
        bool is_anagrpid_const;
 
-       rc = nvme_identify_ctrl(pp->fd, &ctrl);
+       rc = nvme_id_ctrl_ana(pp->fd, &ctrl);
        if (rc < 0) {
                log_nvme_errcode(rc, pp->dev, "nvme_identify_ctrl");
                return -ANA_ERR_GETCTRL_FAILED;
-       }
-
-       if(!(ctrl.cmic & (1 << 3)))
+       } else if (rc == 0)
                return -ANA_ERR_NOT_SUPPORTED;
 
        nsid = nvme_get_nsid(pp->fd);
index f5d8778..98068f3 100644 (file)
@@ -5,6 +5,7 @@
  */
 #include <stdio.h>
 
+#include "nvme-lib.h"
 #include "checkers.h"
 #include "memory.h"
 #include "vector.h"
@@ -550,13 +551,25 @@ detect_prio(struct config *conf, struct path * pp)
 {
        struct prio *p = &pp->prio;
        char buff[512];
-       char *default_prio = PRIO_ALUA;
-
-       if (pp->tpgs <= 0)
-               return;
-       if (pp->tpgs == 2 || !check_rdac(pp)) {
-               if (sysfs_get_asymmetric_access_state(pp, buff, 512) >= 0)
+       char *default_prio;
+
+       switch(pp->bus) {
+       case SYSFS_BUS_NVME:
+               if (nvme_id_ctrl_ana(pp->fd, NULL) == 0)
+                       return;
+               default_prio = PRIO_ANA;
+               break;
+       case SYSFS_BUS_SCSI:
+               if (pp->tpgs <= 0)
+                       return;
+               if ((pp->tpgs == 2 || !check_rdac(pp)) &&
+                   sysfs_get_asymmetric_access_state(pp, buff, 512) >= 0)
                        default_prio = PRIO_SYSFS;
+               else
+                       default_prio = PRIO_ALUA;
+               break;
+       default:
+               return;
        }
        prio_get(conf->multipath_dir, p, default_prio, DEFAULT_PRIO_ARGS);
 }