For a scsi_device to support multipath, introduce structure
scsi_mpath_device to hold multipath-specific details.
Like NS structure for NVME, scsi_mpath_device holds the mpath_device
structure to device management and path selection.
Two module params are introduced to enable multipath:
- scsi_multipath
- scsi_multipath_always
SCSI multipath will only be available until the following conditions:
- scsi_multipath enabled and ALUA supported and unique ID available in
VPD page 83.
- scsi_multipath_always enabled and unique ID available in VPD page 83
The scsi_device structure contains a pointer to scsi_mpath_device, which
means whether multipath is enabled or disabled for the scsi_device.
Signed-off-by: John Garry <john.g.garry@oracle.com>
---
drivers/scsi/Kconfig | 10 +++
drivers/scsi/Makefile | 1 +
drivers/scsi/scsi.c | 8 +-
drivers/scsi/scsi_multipath.c | 158 ++++++++++++++++++++++++++++++++++
drivers/scsi/scsi_scan.c | 4 +
drivers/scsi/scsi_sysfs.c | 2 +
include/scsi/scsi_device.h | 2 +
include/scsi/scsi_multipath.h | 55 ++++++++++++
8 files changed, 239 insertions(+), 1 deletion(-)
create mode 100644 drivers/scsi/scsi_multipath.c
create mode 100644 include/scsi/scsi_multipath.h
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 19d0884479a24..cfab7ad1e3c2c 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -76,6 +76,16 @@ config SCSI_LIB_KUNIT_TEST
If unsure say N.
+config SCSI_MULTIPATH
+ bool "SCSI multipath support"
+ depends on SCSI_MOD
+ select LIBMULTIPATH
+ help
+ This option enables support for native SCSI multipath support for
+ SCSI host.
+
+ If unsure say N.
+
comment "SCSI support type (disk, tape, CD-ROM)"
depends on SCSI
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index 16de3e41f94c4..64b7a82828b81 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -168,6 +168,7 @@ scsi_mod-y += scsi_trace.o scsi_logging.o
scsi_mod-$(CONFIG_PM) += scsi_pm.o
scsi_mod-$(CONFIG_SCSI_DH) += scsi_dh.o
scsi_mod-$(CONFIG_BLK_DEV_BSG) += scsi_bsg.o
+scsi_mod-$(CONFIG_SCSI_MULTIPATH) += scsi_multipath.o
hv_storvsc-y := storvsc_drv.o
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 28c9bbf439db6..99920715a9896 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -64,6 +64,7 @@
#include <scsi/scsi_driver.h>
#include <scsi/scsi_eh.h>
#include <scsi/scsi_host.h>
+#include <scsi/scsi_multipath.h>
#include <scsi/scsi_tcq.h>
#include "scsi_priv.h"
@@ -1042,12 +1043,16 @@ static int __init init_scsi(void)
error = scsi_sysfs_register();
if (error)
goto cleanup_sysctl;
+ error = scsi_multipath_init();
+ if (error)
+ goto cleanup_sysfs;
scsi_netlink_init();
printk(KERN_NOTICE "SCSI subsystem initialized\n");
return 0;
-
+cleanup_sysfs:
+ scsi_sysfs_unregister();
cleanup_sysctl:
scsi_exit_sysctl();
cleanup_hosts:
@@ -1066,6 +1071,7 @@ static int __init init_scsi(void)
static void __exit exit_scsi(void)
{
scsi_netlink_exit();
+ scsi_multipath_exit();
scsi_sysfs_unregister();
scsi_exit_sysctl();
scsi_exit_hosts();
diff --git a/drivers/scsi/scsi_multipath.c b/drivers/scsi/scsi_multipath.c
new file mode 100644
index 0000000000000..04e0bad3d9204
--- /dev/null
+++ b/drivers/scsi/scsi_multipath.c
@@ -0,0 +1,158 @@
+// SPDX-License-Indentifier: GPL-2.0
+/*
+ * Copyright (c) 2026 Oracle Corp
+ *
+ */
+
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_driver.h>
+#include <scsi/scsi_proto.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_multipath.h>
+
+#include "scsi_priv.h"
+
+bool scsi_multipath;
+static bool scsi_multipath_always;
+
+static int multipath_param_set(const char *val, const struct kernel_param *kp)
+{
+ int ret;
+ bool *arg = kp->arg;
+
+ ret = param_set_bool(val, kp);
+ if (ret)
+ return ret;
+
+ if (scsi_multipath_always && !*arg) {
+ pr_err("Can't disable multipath when multipath_always_on is configured.\n");
+ *arg = true;
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static const struct kernel_param_ops multipath_param_ops = {
+ .set = multipath_param_set,
+ .get = param_get_bool,
+};
+
+module_param_cb(scsi_multipath, &multipath_param_ops, &scsi_multipath, 0444);
+MODULE_PARM_DESC(scsi_multipath, "turn on native multipath support");
+
+static int multipath_always_on_set(const char *val,
+ const struct kernel_param *kp)
+{
+ int ret;
+ bool *arg = kp->arg;
+
+ ret = param_set_bool(val, kp);
+ if (ret < 0)
+ return ret;
+
+ if (*arg)
+ scsi_multipath = true;
+
+ return 0;
+}
+
+static const struct kernel_param_ops multipath_always_on_ops = {
+ .set = multipath_always_on_set,
+ .get = param_get_bool,
+};
+
+module_param_cb(scsi_multipath_always, &multipath_always_on_ops,
+ &scsi_multipath_always, 0444);
+MODULE_PARM_DESC(scsi_multipath_always,
+ "create multipath node always even for no ALUA support");
+
+static int scsi_mpath_unique_lun_id(struct scsi_device *sdev)
+{
+ struct scsi_mpath_device *scsi_mpath_dev = sdev->scsi_mpath_dev;
+ int ret;
+
+ ret = scsi_vpd_lun_id(sdev, scsi_mpath_dev->device_id_str,
+ SCSI_MPATH_DEVICE_ID_LEN);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int scsi_multipath_sdev_init(struct scsi_device *sdev)
+{
+ struct Scsi_Host *shost = sdev->host;
+ struct scsi_mpath_device *scsi_mpath_dev;
+ struct mpath_device *mpath_device;
+
+ scsi_mpath_dev = kzalloc(sizeof(*scsi_mpath_dev), GFP_KERNEL);
+ if (!scsi_mpath_dev)
+ return -ENOMEM;
+ scsi_mpath_dev->sdev = sdev;
+ sdev->scsi_mpath_dev = scsi_mpath_dev;
+
+ mpath_device = &scsi_mpath_dev->mpath_device;
+ mpath_device->numa_node = dev_to_node(shost->dma_dev);
+
+ return 0;
+}
+
+static void scsi_multipath_sdev_uninit(struct scsi_device *sdev)
+{
+ kfree(sdev->scsi_mpath_dev);
+ sdev->scsi_mpath_dev = NULL;
+}
+
+int scsi_mpath_dev_alloc(struct scsi_device *sdev)
+{
+ int ret;
+
+ if (!scsi_multipath)
+ return 0;
+
+ if (!scsi_device_tpgs(sdev) && !scsi_multipath_always) {
+ sdev_printk(KERN_NOTICE, sdev, "tpgs are required for multipath support\n");
+ return 0;
+ }
+
+ ret = scsi_multipath_sdev_init(sdev);
+ if (ret)
+ return ret;
+
+ ret = scsi_mpath_unique_lun_id(sdev);
+ if (ret < 0) {
+ ret = 0;
+ goto out_uninit;
+ }
+
+ return 0;
+
+out_uninit:
+ scsi_multipath_sdev_uninit(sdev);
+ return ret;
+}
+
+void scsi_mpath_dev_release(struct scsi_device *sdev)
+{
+ struct scsi_mpath_device *scsi_mpath_dev = sdev->scsi_mpath_dev;
+
+ if (!scsi_mpath_dev)
+ return;
+
+ scsi_multipath_sdev_uninit(sdev);
+
+}
+
+int __init scsi_multipath_init(void)
+{
+ return 0;
+}
+
+void __exit scsi_multipath_exit(void)
+{
+}
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("scsi_multipath");
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 7acbfcfc2172e..e22d3245d4b65 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -46,6 +46,7 @@
#include <scsi/scsi_transport.h>
#include <scsi/scsi_dh.h>
#include <scsi/scsi_eh.h>
+#include <scsi/scsi_multipath.h>
#include "scsi_priv.h"
#include "scsi_logging.h"
@@ -1122,6 +1123,9 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,
sdev->max_queue_depth = sdev->queue_depth;
WARN_ON_ONCE(sdev->max_queue_depth > sdev->budget_map.depth);
+ if (scsi_mpath_dev_alloc(sdev))
+ return SCSI_SCAN_NO_RESPONSE;
+
/*
* Ok, the device is now all set up, we can
* register it and tell the rest of the kernel
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index 99eb0a30df615..0d69e27600a7a 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -23,6 +23,7 @@
#include <scsi/scsi_transport.h>
#include <scsi/scsi_driver.h>
#include <scsi/scsi_devinfo.h>
+#include <scsi/scsi_multipath.h>
#include "scsi_priv.h"
#include "scsi_logging.h"
@@ -455,6 +456,7 @@ static void scsi_device_dev_release(struct device *dev)
might_sleep();
scsi_dh_release_device(sdev);
+ scsi_mpath_dev_release(sdev);
parent = sdev->sdev_gendev.parent;
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index d32f5841f4f85..52974dba0a724 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -279,6 +279,8 @@ struct scsi_device {
struct device sdev_gendev,
sdev_dev;
+ struct scsi_mpath_device *scsi_mpath_dev;
+
struct work_struct requeue_work;
struct scsi_device_handler *handler;
diff --git a/include/scsi/scsi_multipath.h b/include/scsi/scsi_multipath.h
new file mode 100644
index 0000000000000..ca00ea10cd5db
--- /dev/null
+++ b/include/scsi/scsi_multipath.h
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _SCSI_SCSI_MULTIPATH_H
+#define _SCSI_SCSI_MULTIPATH_H
+
+#include <linux/list.h>
+#include <linux/types.h>
+#include <linux/rcupdate.h>
+#include <linux/workqueue.h>
+#include <linux/mutex.h>
+#include <linux/blk-mq.h>
+#include <linux/multipath.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_dbg.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_devinfo.h>
+#include <scsi/scsi_driver.h>
+
+#ifdef CONFIG_SCSI_MULTIPATH
+#define SCSI_MPATH_DEVICE_ID_LEN 40
+
+struct scsi_mpath_device {
+ struct mpath_device mpath_device;
+ struct scsi_device *sdev;
+
+ char device_id_str[SCSI_MPATH_DEVICE_ID_LEN];
+};
+#define to_scsi_mpath_device(d) \
+ container_of(d, struct scsi_mpath_device, mpath_device)
+
+int scsi_mpath_dev_alloc(struct scsi_device *sdev);
+void scsi_mpath_dev_release(struct scsi_device *sdev);
+int scsi_multipath_init(void);
+void scsi_multipath_exit(void);
+#else /* CONFIG_SCSI_MULTIPATH */
+
+struct scsi_mpath_device {
+};
+
+static inline int scsi_mpath_dev_alloc(struct scsi_device *sdev)
+{
+ return 0;
+}
+static inline void scsi_mpath_dev_release(struct scsi_device *sdev)
+{
+}
+static inline int scsi_multipath_init(void)
+{
+ return 0;
+}
+static inline void scsi_multipath_exit(void)
+{
+}
+#endif /* CONFIG_SCSI_MULTIPATH */
+#endif /* _SCSI_SCSI_MULTIPATH_H */
--
2.43.5
On 2/25/26 16:36, John Garry wrote: > For a scsi_device to support multipath, introduce structure > scsi_mpath_device to hold multipath-specific details. > > Like NS structure for NVME, scsi_mpath_device holds the mpath_device > structure to device management and path selection. > > Two module params are introduced to enable multipath: > - scsi_multipath > - scsi_multipath_always > > SCSI multipath will only be available until the following conditions: > - scsi_multipath enabled and ALUA supported and unique ID available in > VPD page 83. > - scsi_multipath_always enabled and unique ID available in VPD page 83 > Why don't you merge these two options, and have scsi_multipath=on and scsi_multipath=always ? Cheers, Hannes -- Dr. Hannes Reinecke Kernel Storage Architect hare@suse.com +49 911 74053 688 SUSE Software Solutions GmbH, Frankenstr. 146, 90461 Nürnberg HRB 36809 (AG Nürnberg), GF: I. Totev, A. McDonald, W. Knoblich
On 03/03/2026 06:57, Hannes Reinecke wrote: >> SCSI multipath will only be available until the following conditions: >> - scsi_multipath enabled and ALUA supported and unique ID available in >> VPD page 83. >> - scsi_multipath_always enabled and unique ID available in VPD page 83 >> > Why don't you merge these two options, and have > scsi_multipath=on > and > scsi_multipath=always that seems a reasonable idea. Thanks
On Wed, Feb 25, 2026 at 03:36:05PM +0000, John Garry wrote: > For a scsi_device to support multipath, introduce structure > scsi_mpath_device to hold multipath-specific details. > > Like NS structure for NVME, scsi_mpath_device holds the mpath_device > structure to device management and path selection. > > Two module params are introduced to enable multipath: > - scsi_multipath > - scsi_multipath_always > > SCSI multipath will only be available until the following conditions: > - scsi_multipath enabled and ALUA supported and unique ID available in > VPD page 83. > - scsi_multipath_always enabled and unique ID available in VPD page 83 > > The scsi_device structure contains a pointer to scsi_mpath_device, which > means whether multipath is enabled or disabled for the scsi_device. > > Signed-off-by: John Garry <john.g.garry@oracle.com> > --- > drivers/scsi/Kconfig | 10 +++ > drivers/scsi/Makefile | 1 + > drivers/scsi/scsi.c | 8 +- > drivers/scsi/scsi_multipath.c | 158 ++++++++++++++++++++++++++++++++++ > drivers/scsi/scsi_scan.c | 4 + > drivers/scsi/scsi_sysfs.c | 2 + > include/scsi/scsi_device.h | 2 + > include/scsi/scsi_multipath.h | 55 ++++++++++++ > 8 files changed, 239 insertions(+), 1 deletion(-) > create mode 100644 drivers/scsi/scsi_multipath.c > create mode 100644 include/scsi/scsi_multipath.h > > diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig > index 19d0884479a24..cfab7ad1e3c2c 100644 > --- a/drivers/scsi/Kconfig > +++ b/drivers/scsi/Kconfig > @@ -76,6 +76,16 @@ config SCSI_LIB_KUNIT_TEST > > If unsure say N. > > +config SCSI_MULTIPATH > + bool "SCSI multipath support" At least until this supports ALUA, it should probably be marked EXPERIMENTAL, just so people trying it out aren't surprised if it doesn't multipath their device in the way they expect. -Ben
On 02/03/2026 02:22, Benjamin Marzinski wrote: >> diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig >> index 19d0884479a24..cfab7ad1e3c2c 100644 >> --- a/drivers/scsi/Kconfig >> +++ b/drivers/scsi/Kconfig >> @@ -76,6 +76,16 @@ config SCSI_LIB_KUNIT_TEST >> >> If unsure say N. >> >> +config SCSI_MULTIPATH >> + bool "SCSI multipath support" > At least until this supports ALUA, it should probably be marked > EXPERIMENTAL, just so people trying it out aren't surprised if it > doesn't multipath their device in the way they expect. I think that ALUA support will be mainline acceptance criteria, and I am looking to add it now. BTW, Hannes suggested to not use the DH ALUA support, so that means to separate out the core ALUA support from the DH stuff. So you have any opinion on that approach? Thanks!
On Mon, Mar 02, 2026 at 11:39:28AM +0000, John Garry wrote: > On 02/03/2026 02:22, Benjamin Marzinski wrote: > > > diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig > > > index 19d0884479a24..cfab7ad1e3c2c 100644 > > > --- a/drivers/scsi/Kconfig > > > +++ b/drivers/scsi/Kconfig > > > @@ -76,6 +76,16 @@ config SCSI_LIB_KUNIT_TEST > > > If unsure say N. > > > +config SCSI_MULTIPATH > > > + bool "SCSI multipath support" > > At least until this supports ALUA, it should probably be marked > > EXPERIMENTAL, just so people trying it out aren't surprised if it > > doesn't multipath their device in the way they expect. > > I think that ALUA support will be mainline acceptance criteria, and I am > looking to add it now. > > BTW, Hannes suggested to not use the DH ALUA support, so that means to > separate out the core ALUA support from the DH stuff. So you have any > opinion on that approach? I would (perhaps naively) have thought that the device handlers would be a useful abstraction for dealing with ALUA devices. But, Hannes knows this code much better than me. like I said before, I'm no scsi expert. -Ben > > Thanks!
On 3/3/26 06:39, Benjamin Marzinski wrote: > On Mon, Mar 02, 2026 at 11:39:28AM +0000, John Garry wrote: >> On 02/03/2026 02:22, Benjamin Marzinski wrote: >>>> diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig >>>> index 19d0884479a24..cfab7ad1e3c2c 100644 >>>> --- a/drivers/scsi/Kconfig >>>> +++ b/drivers/scsi/Kconfig >>>> @@ -76,6 +76,16 @@ config SCSI_LIB_KUNIT_TEST >>>> If unsure say N. >>>> +config SCSI_MULTIPATH >>>> + bool "SCSI multipath support" >>> At least until this supports ALUA, it should probably be marked >>> EXPERIMENTAL, just so people trying it out aren't surprised if it >>> doesn't multipath their device in the way they expect. >> >> I think that ALUA support will be mainline acceptance criteria, and I am >> looking to add it now. >> >> BTW, Hannes suggested to not use the DH ALUA support, so that means to >> separate out the core ALUA support from the DH stuff. So you have any >> opinion on that approach? > > I would (perhaps naively) have thought that the device handlers would be > a useful abstraction for dealing with ALUA devices. But, Hannes knows > this code much better than me. like I said before, I'm no scsi expert. > The main point of the device handlers was to inject a 'start' command whenever paths needed to be switched (Like you need to do for some active/passive arrays). But that really caused quite some issues with complexity, as you easily can get into array path ping-pong on path failure with no I/O being transmitted. So for this implementation I would stick with implicit ALUA (most modern implementations have done so already anyway), and then there's no need using the device handlers. Cheers, Hannes -- Dr. Hannes Reinecke Kernel Storage Architect hare@suse.de +49 911 74053 688 SUSE Software Solutions GmbH, Frankenstr. 146, 90461 Nürnberg HRB 36809 (AG Nürnberg), GF: I. Totev, A. McDonald, W. Knoblich
On 03/03/2026 08:01, Hannes Reinecke wrote: >> I would (perhaps naively) have thought that the device handlers would be >> a useful abstraction for dealing with ALUA devices. But, Hannes knows >> this code much better than me. like I said before, I'm no scsi expert. >> > The main point of the device handlers was to inject a 'start' command > whenever paths needed to be switched (Like you need to do for some > active/passive arrays). > But that really caused quite some issues with complexity, as you easily > can get into array path ping-pong on path failure with no I/O being > transmitted. > > So for this implementation I would stick with implicit ALUA > (most modern implementations have done so already anyway), and > then there's no need using the device handlers. I want to mention the problems of trying to not use device handler-based code from scsi_dh_alua.c . I would like to have core ALUA code for both scsi_dh_alua.c and native scsi multipath, but it's easier said than done to achieve. I can easily extract the protocol-specific helper code, like alua_tur(), alua_check_tpgs(), and submit_rtpg(). But what about the port group management code, like in alua_rtpg() and alua_rtpg_work()? As far as I am concerned, we need that for native SCSI multipath support. All the port group management is intertwined with the DH stuff. Even stuff alua_port_group has DH stuff, like dh_list and rtpg_list members. And we also can't easily take code only relevant to implicit ALUA, either. Any suggestions?
On Tue, Mar 03, 2026 at 09:01:04AM +0100, Hannes Reinecke wrote: > On 3/3/26 06:39, Benjamin Marzinski wrote: > > On Mon, Mar 02, 2026 at 11:39:28AM +0000, John Garry wrote: > > > On 02/03/2026 02:22, Benjamin Marzinski wrote: > > > > > diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig > > > > > index 19d0884479a24..cfab7ad1e3c2c 100644 > > > > > --- a/drivers/scsi/Kconfig > > > > > +++ b/drivers/scsi/Kconfig > > > > > @@ -76,6 +76,16 @@ config SCSI_LIB_KUNIT_TEST > > > > > If unsure say N. > > > > > +config SCSI_MULTIPATH > > > > > + bool "SCSI multipath support" > > > > At least until this supports ALUA, it should probably be marked > > > > EXPERIMENTAL, just so people trying it out aren't surprised if it > > > > doesn't multipath their device in the way they expect. > > > > > > I think that ALUA support will be mainline acceptance criteria, and I am > > > looking to add it now. > > > > > > BTW, Hannes suggested to not use the DH ALUA support, so that means to > > > separate out the core ALUA support from the DH stuff. So you have any > > > opinion on that approach? > > > > I would (perhaps naively) have thought that the device handlers would be > > a useful abstraction for dealing with ALUA devices. But, Hannes knows > > this code much better than me. like I said before, I'm no scsi expert. > > > The main point of the device handlers was to inject a 'start' command > whenever paths needed to be switched (Like you need to do for some > active/passive arrays). > But that really caused quite some issues with complexity, as you easily > can get into array path ping-pong on path failure with no I/O being > transmitted. > > So for this implementation I would stick with implicit ALUA > (most modern implementations have done so already anyway), and > then there's no need using the device handlers. That makes sense. Limiting support to implicit ALUA significantly lowers the bar for getting ALUA working. AFAICS, It should just require getting the path selecting code right. -Ben > > Cheers, > > Hannes > -- > Dr. Hannes Reinecke Kernel Storage Architect > hare@suse.de +49 911 74053 688 > SUSE Software Solutions GmbH, Frankenstr. 146, 90461 Nürnberg > HRB 36809 (AG Nürnberg), GF: I. Totev, A. McDonald, W. Knoblich
On Wed, Feb 25, 2026 at 03:36:05PM +0000, John Garry wrote:
> For a scsi_device to support multipath, introduce structure
> scsi_mpath_device to hold multipath-specific details.
>
> Like NS structure for NVME, scsi_mpath_device holds the mpath_device
> structure to device management and path selection.
>
> Two module params are introduced to enable multipath:
> - scsi_multipath
> - scsi_multipath_always
>
> SCSI multipath will only be available until the following conditions:
> - scsi_multipath enabled and ALUA supported and unique ID available in
> VPD page 83.
> - scsi_multipath_always enabled and unique ID available in VPD page 83
>
> The scsi_device structure contains a pointer to scsi_mpath_device, which
> means whether multipath is enabled or disabled for the scsi_device.
>
> Signed-off-by: John Garry <john.g.garry@oracle.com>
>
> diff --git a/include/scsi/scsi_multipath.h b/include/scsi/scsi_multipath.h
> new file mode 100644
> index 0000000000000..ca00ea10cd5db
> --- /dev/null
> +++ b/include/scsi/scsi_multipath.h
> @@ -0,0 +1,55 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef _SCSI_SCSI_MULTIPATH_H
> +#define _SCSI_SCSI_MULTIPATH_H
> +
> +#include <linux/list.h>
> +#include <linux/types.h>
> +#include <linux/rcupdate.h>
> +#include <linux/workqueue.h>
> +#include <linux/mutex.h>
> +#include <linux/blk-mq.h>
> +#include <linux/multipath.h>
> +#include <scsi/scsi.h>
> +#include <scsi/scsi_cmnd.h>
> +#include <scsi/scsi_dbg.h>
> +#include <scsi/scsi_device.h>
> +#include <scsi/scsi_devinfo.h>
> +#include <scsi/scsi_driver.h>
> +
> +#ifdef CONFIG_SCSI_MULTIPATH
> +#define SCSI_MPATH_DEVICE_ID_LEN 40
Is there a reason that this is set to 40? scsi_vpd_lun_id() can return
ids larger than 40 (struct alua_port_group uses 256 bytes to hold the
response), and I don't know of any guarantee that the id will be unique
within the first 40 characters, although it certainly seems like only
pathological devices wouldn't.
-Ben
> +
> +struct scsi_mpath_device {
> + struct mpath_device mpath_device;
> + struct scsi_device *sdev;
> +
> + char device_id_str[SCSI_MPATH_DEVICE_ID_LEN];
> +};
> +#define to_scsi_mpath_device(d) \
> + container_of(d, struct scsi_mpath_device, mpath_device)
> +
> +int scsi_mpath_dev_alloc(struct scsi_device *sdev);
> +void scsi_mpath_dev_release(struct scsi_device *sdev);
> +int scsi_multipath_init(void);
> +void scsi_multipath_exit(void);
> +#else /* CONFIG_SCSI_MULTIPATH */
> +
> +struct scsi_mpath_device {
> +};
> +
> +static inline int scsi_mpath_dev_alloc(struct scsi_device *sdev)
> +{
> + return 0;
> +}
> +static inline void scsi_mpath_dev_release(struct scsi_device *sdev)
> +{
> +}
> +static inline int scsi_multipath_init(void)
> +{
> + return 0;
> +}
> +static inline void scsi_multipath_exit(void)
> +{
> +}
> +#endif /* CONFIG_SCSI_MULTIPATH */
> +#endif /* _SCSI_SCSI_MULTIPATH_H */
> --
> 2.43.5
On 02/03/2026 02:16, Benjamin Marzinski wrote: >> + >> +#ifdef CONFIG_SCSI_MULTIPATH >> +#define SCSI_MPATH_DEVICE_ID_LEN 40 > Is there a reason that this is set to 40? scsi_vpd_lun_id() can return > ids larger than 40 (struct alua_port_group uses 256 bytes to hold the > response), and I don't know of any guarantee that the id will be unique > within the first 40 characters, although it certainly seems like only > pathological devices wouldn't. Right, I will be increasing this to be aligned with what the spec allows. Thanks!
© 2016 - 2026 Red Hat, Inc.