dm-devel.redhat.com archive mirror
 help / color / mirror / Atom feed
* [PATCH] libmultipath: Extract the LUN number for peripheral, flat, and logical unit address methods
@ 2020-09-28 23:14 Brian Bunker
  2020-09-30 11:09 ` Steffen Maier
  0 siblings, 1 reply; 3+ messages in thread
From: Brian Bunker @ 2020-09-28 23:14 UTC (permalink / raw)
  To: device-mapper development

For LUNs between 0 and 255 peripheral addressing is used. For LUNs higher than 255 the LUN addressing
should switch to flat according to the specification. Instead of printing out the LUN number without regard to
the shifting of address method, display the LUN as it was intended to be the user connecting the LUN. The
current display leaves a non-obvious 16384 offset.

In short, a LUN connected as 258 will show up in multipath output as 16642. Instead display it as the
expected 258. This is for display only and doesn’t change the actual contents of the LUN variable.

Signed-off-by: Brian Bunker <brian@purestorage.com>
___
diff -Naur a/multipath-tools-0.8.3/libmultipath/print.c b/multipath-tools-0.8.3/libmultipath/print.c
--- a/libmultipath/print.c      2020-09-24 13:52:18.661828011 -0600
+++ b/libmultipath/print.c      2020-09-28 16:57:37.956222258 -0600
@@ -29,6 +29,7 @@
 #include "uevent.h"
 #include "debug.h"
 #include "discovery.h"
+#include "util.h"
 
 #define MAX(x,y) (((x) > (y)) ? (x) : (y))
 #define MIN(x,y) (((x) > (y)) ? (y) : (x))
@@ -390,11 +391,12 @@
        if (!pp || pp->sg_id.host_no < 0)
                return snprintf(buff, len, "#:#:#:#");
 
+       int display_lun = extract_lun_number(pp->sg_id.lun);
        return snprintf(buff, len, "%i:%i:%i:%i",
                        pp->sg_id.host_no,
                        pp->sg_id.channel,
                        pp->sg_id.scsi_id,
-                       pp->sg_id.lun);
+                       display_lun);
 }
 
 static int
diff -Naur a/multipath-tools-0.8.3/libmultipath/util.c b/multipath-tools-0.8.3/libmultipath/util.c
--- a/multipath-tools-0.8.3/libmultipath/util.c 2019-10-02 01:15:03.000000000 -0600
+++ b/multipath-tools-0.8.3/libmultipath/util.c 2020-09-28 16:56:00.851169070 -0600
@@ -470,3 +470,25 @@
 {
        close((long)arg);
 }
+
+/* Extracts the LUN number from the addressing method for
+   peripheral, flat, and LUN addressing methods.
+ */
+int extract_lun_number(int lun)
+{
+       if (lun > UINT16_MAX)
+               return lun;
+
+       uint8_t address_method = ((lun >> 8) & 0xC0) >> 6; /* first two bits of the 16 byte LUN */
+       switch (address_method) {
+               case 1: /* Flat Addressing method (01b) */
+                       return lun - 0x4000;
+               case 2: /* Logical unit addressing (02b) */
+                       return lun & 0x001F;
+               case 0: /* Peripheral addressing method (00b) */
+                       if (lun > 255)
+                               condlog(3, "Peripheral addressing supports up to 256 LUNs");
+               default:
+                       return lun;
+       }
+}
diff -Naur a/multipath-tools-0.8.3/libmultipath/util.h b/multipath-tools-0.8.3/libmultipath/util.h
--- a/multipath-tools-0.8.3/libmultipath/util.h 2019-10-02 01:15:03.000000000 -0600
+++ b/multipath-tools-0.8.3/libmultipath/util.h 2020-09-28 16:43:32.632879763 -0600
@@ -22,6 +22,7 @@
 int parse_prkey_flags(char *ptr, uint64_t *prkey, uint8_t *flags);
 int safe_write(int fd, const void *buf, size_t count);
 void set_max_fds(int max_fds);
+int extract_lun_number(int lun);
 
 #define KERNEL_VERSION(maj, min, ptc) ((((maj) * 256) + (min)) * 256 + (ptc))
 #define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))

Brian Bunker
SW Eng
brian@purestorage.com




--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] libmultipath: Extract the LUN number for peripheral, flat, and logical unit address methods
  2020-09-28 23:14 [PATCH] libmultipath: Extract the LUN number for peripheral, flat, and logical unit address methods Brian Bunker
@ 2020-09-30 11:09 ` Steffen Maier
  2020-09-30 12:08   ` Hannes Reinecke
  0 siblings, 1 reply; 3+ messages in thread
From: Steffen Maier @ 2020-09-30 11:09 UTC (permalink / raw)
  To: Brian Bunker, device-mapper development; +Cc: Benjamin Block

On 9/29/20 1:14 AM, Brian Bunker wrote:
> For LUNs between 0 and 255 peripheral addressing is used. For LUNs higher than 255 the LUN addressing
> should switch to flat according to the specification. Instead of printing out the LUN number without regard to
> the shifting of address method, display the LUN as it was intended to be the user connecting the LUN. The
> current display leaves a non-obvious 16384 offset.
> 
> In short, a LUN connected as 258 will show up in multipath output as 16642. Instead display it as the
> expected 258. This is for display only and doesn’t change the actual contents of the LUN variable.

[this is kind of a continuation of the discussion that started with the 1st 
version of the path in 
https://www.redhat.com/archives/dm-devel/2020-September/msg00592.html]

Users and tools such as 
https://github.com/ibm-s390-tools/s390-tools/blob/master/ziomon/ziomon parse 
the hcil output of multipath(d) to find the corresponding Linux SCSI device by 
its well-defined name.
I think this change would break those.

IIRC, tools such as rescan-scsi-bus.sh [sg3_utils] were intentionally changed 
from decoding the LUN format to working with an opaque 64-bit LUN.
[https://lore.kernel.org/linux-scsi/51288C5F.1080802@suse.de/T/#maba954fc50efa24e4c0544506d4c4025269d6c60]

Using target-internal volume "names", such as the pure LUN number, for 
communication between initiator (Linux admin) and target (storage admin) can 
indeed be confusing.
The target decides how it exports a volume using a T10 SAM 64-bit LUN that both 
initator and target understand (report luns etc.). That's what Linux encodes in 
the scsi lun part of a SCSI device name [with a bijective mapping swapping the 
order of T10 SAM LUN levels].

Here's a real-life example making use of the SCSI device name to map different 
related objects [similar to what the above-mentioned ziomon tool does]:

# multipathd -k'show topo'
36005076309ffd43000000000000015f8 dm-1 IBM,2107900
size=10G features='1 queue_if_no_path' hwhandler='1 alua' wp=rw
`-+- policy='service-time 0' prio=50 status=active
   |- 0:0:0:1090011157 sdh 8:112 active ready running
   `- 1:0:0:1090011157 sda 8:0   active ready running

E.g. find the correspondig SCSI generic device:
# lsscsi -g 0:0:0:1090011157
[0:0:0:1090011157] disk    IBM      2107900          2.88  /dev/sdh    /dev/sg7

Decode the LUN format:
# lsscsi -x -g 0:0:0:1090011157
[0:0:0:0x4015]              disk    IBM      2107900          2.88  /dev/sdh 
/dev/sg7

Just use the full 64-bit LUN as an opaque value:
# lsscsi -xx -g 0:0:0:1090011157
[0:0:0:0x401540f800000000]  disk    IBM      2107900          2.88  /dev/sdh 
/dev/sg7

> 
> Signed-off-by: Brian Bunker <brian@purestorage.com>
> ___
> diff -Naur a/multipath-tools-0.8.3/libmultipath/print.c b/multipath-tools-0.8.3/libmultipath/print.c
> --- a/libmultipath/print.c      2020-09-24 13:52:18.661828011 -0600
> +++ b/libmultipath/print.c      2020-09-28 16:57:37.956222258 -0600
> @@ -29,6 +29,7 @@
>   #include "uevent.h"
>   #include "debug.h"
>   #include "discovery.h"
> +#include "util.h"
>   
>   #define MAX(x,y) (((x) > (y)) ? (x) : (y))
>   #define MIN(x,y) (((x) > (y)) ? (y) : (x))
> @@ -390,11 +391,12 @@
>          if (!pp || pp->sg_id.host_no < 0)
>                  return snprintf(buff, len, "#:#:#:#");
>   
> +       int display_lun = extract_lun_number(pp->sg_id.lun);
>          return snprintf(buff, len, "%i:%i:%i:%i",
>                          pp->sg_id.host_no,
>                          pp->sg_id.channel,
>                          pp->sg_id.scsi_id,
> -                       pp->sg_id.lun);
> +                       display_lun);
>   }
>   
>   static int
> diff -Naur a/multipath-tools-0.8.3/libmultipath/util.c b/multipath-tools-0.8.3/libmultipath/util.c
> --- a/multipath-tools-0.8.3/libmultipath/util.c 2019-10-02 01:15:03.000000000 -0600
> +++ b/multipath-tools-0.8.3/libmultipath/util.c 2020-09-28 16:56:00.851169070 -0600
> @@ -470,3 +470,25 @@
>   {
>          close((long)arg);
>   }
> +
> +/* Extracts the LUN number from the addressing method for
> +   peripheral, flat, and LUN addressing methods.
> + */
> +int extract_lun_number(int lun)
> +{
> +       if (lun > UINT16_MAX)
> +               return lun;
> +
> +       uint8_t address_method = ((lun >> 8) & 0xC0) >> 6; /* first two bits of the 16 byte LUN */
> +       switch (address_method) {
> +               case 1: /* Flat Addressing method (01b) */
> +                       return lun - 0x4000;
> +               case 2: /* Logical unit addressing (02b) */
> +                       return lun & 0x001F;
> +               case 0: /* Peripheral addressing method (00b) */
> +                       if (lun > 255)
> +                               condlog(3, "Peripheral addressing supports up to 256 LUNs");
> +               default:
> +                       return lun;
> +       }
> +}
> diff -Naur a/multipath-tools-0.8.3/libmultipath/util.h b/multipath-tools-0.8.3/libmultipath/util.h
> --- a/multipath-tools-0.8.3/libmultipath/util.h 2019-10-02 01:15:03.000000000 -0600
> +++ b/multipath-tools-0.8.3/libmultipath/util.h 2020-09-28 16:43:32.632879763 -0600
> @@ -22,6 +22,7 @@
>   int parse_prkey_flags(char *ptr, uint64_t *prkey, uint8_t *flags);
>   int safe_write(int fd, const void *buf, size_t count);
>   void set_max_fds(int max_fds);
> +int extract_lun_number(int lun);
>   
>   #define KERNEL_VERSION(maj, min, ptc) ((((maj) * 256) + (min)) * 256 + (ptc))
>   #define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
> 
> Brian Bunker
> SW Eng
> brian@purestorage.com
> 
> 
> 
> 
> --
> dm-devel mailing list
> dm-devel@redhat.com
> https://www.redhat.com/mailman/listinfo/dm-devel
> 


-- 
Mit freundlichen Gruessen / Kind regards
Steffen Maier

Linux on IBM Z Development

https://www.ibm.com/privacy/us/en/
IBM Deutschland Research & Development GmbH
Vorsitzender des Aufsichtsrats: Matthias Hartmann
Geschaeftsfuehrung: Dirk Wittkopp
Sitz der Gesellschaft: Boeblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294


--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] libmultipath: Extract the LUN number for peripheral, flat, and logical unit address methods
  2020-09-30 11:09 ` Steffen Maier
@ 2020-09-30 12:08   ` Hannes Reinecke
  0 siblings, 0 replies; 3+ messages in thread
From: Hannes Reinecke @ 2020-09-30 12:08 UTC (permalink / raw)
  To: Steffen Maier, Brian Bunker, device-mapper development; +Cc: Benjamin Block

On 9/30/20 1:09 PM, Steffen Maier wrote:
> On 9/29/20 1:14 AM, Brian Bunker wrote:
>> For LUNs between 0 and 255 peripheral addressing is used. For LUNs 
>> higher than 255 the LUN addressing
>> should switch to flat according to the specification. Instead of 
>> printing out the LUN number without regard to
>> the shifting of address method, display the LUN as it was intended to 
>> be the user connecting the LUN. The
>> current display leaves a non-obvious 16384 offset.
>>
>> In short, a LUN connected as 258 will show up in multipath output as 
>> 16642. Instead display it as the
>> expected 258. This is for display only and doesn’t change the actual 
>> contents of the LUN variable.
> 
> [this is kind of a continuation of the discussion that started with the 
> 1st version of the path in 
> https://www.redhat.com/archives/dm-devel/2020-September/msg00592.html]
> 
> Users and tools such as 
> https://github.com/ibm-s390-tools/s390-tools/blob/master/ziomon/ziomon 
> parse the hcil output of multipath(d) to find the corresponding Linux 
> SCSI device by its well-defined name.
> I think this change would break those.
> 
> IIRC, tools such as rescan-scsi-bus.sh [sg3_utils] were intentionally 
> changed from decoding the LUN format to working with an opaque 64-bit LUN.
> [https://lore.kernel.org/linux-scsi/51288C5F.1080802@suse.de/T/#maba954fc50efa24e4c0544506d4c4025269d6c60] 
> 
I can not agree more.
The principal problem is that there was a shift in the definition of the 
LUN number between SCSI-3/SAM and SAM-2; prior to SAM-2 _any_ 64-bit 
number was a valid LUN, whereas SAM-2 introduced the LUN number structure.
So any meaning a LUN might have depends on the claimed standard.
Additionally, quite some arrays operate in 'legacy' mode, trying to 
preserve backwards compability with the original SCSI-2 standard.
Hence figuring out which standard is actually used by the implementation 
is challenging at times.

But it also means that LUN 0x4100 could refer to LUN 16640 (for SCSI-3), 
or to LUN 256 (for SAM-2).
Or the device might choose to use hierarchical LUN addressing, which 
makes it pretty hard to extract a valid (and unique!) LUN number.

So in the end we decided to _not_ decode the LUN number, as the internal 
structure is only ever useful for the target, not the initiator.

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		           Kernel Storage Architect
hare@suse.de			                  +49 911 74053 688
SUSE Software Solutions Germany GmbH, Maxfeldstr. 5, 90409 Nürnberg
HRB 36809 (AG Nürnberg), GF: Felix Imendörffer


--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2020-09-30 12:08 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-28 23:14 [PATCH] libmultipath: Extract the LUN number for peripheral, flat, and logical unit address methods Brian Bunker
2020-09-30 11:09 ` Steffen Maier
2020-09-30 12:08   ` Hannes Reinecke

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).