Author: mav
Date: Mon Jun 17 14:52:39 2013
New Revision: 251849
URL: http://svnweb.freebsd.org/changeset/base/251849

Log:
  MFC r251654, r251664:
  Make CAM return and GEOM DISK pass through new GEOM::lunid attribute.
  
  SPC-4 specification states that serial number may be property of device,
  but not a specific logical unit.  People reported about FC storages using
  serial number in that way, making it unusable for purposes of LUN multipath
  detection.  SPC-4 states that designators associated with logical unit from
  the VPD page 83h "Device Identification" should be used for that purpose.
  Report first of them in the new attribute in such preference order: NAA,
  EUI-64, T10 and SCSI name string.
  
  While there, make GEOM DISK properly report GEOM::ident in XML output also
  using d_getattr() method, if available.  This fixes serial numbers reporting
  for SCSI disks in `geom disk list` output and confxml.

Modified:
  stable/9/sbin/camcontrol/camcontrol.c
  stable/9/sys/cam/cam_xpt.c
  stable/9/sys/cam/scsi/scsi_all.c
  stable/9/sys/cam/scsi/scsi_all.h
  stable/9/sys/cam/scsi/scsi_enc_ses.c
  stable/9/sys/geom/geom_disk.c
Directory Properties:
  stable/9/sbin/camcontrol/   (props changed)
  stable/9/sys/   (props changed)

Modified: stable/9/sbin/camcontrol/camcontrol.c
==============================================================================
--- stable/9/sbin/camcontrol/camcontrol.c       Mon Jun 17 14:46:54 2013        
(r251848)
+++ stable/9/sbin/camcontrol/camcontrol.c       Mon Jun 17 14:52:39 2013        
(r251849)
@@ -6946,18 +6946,18 @@ findsasdevice(struct cam_devlist *devlis
        struct cam_devitem *item;
 
        STAILQ_FOREACH(item, &devlist->dev_queue, links) {
-               uint8_t *item_addr;
+               struct scsi_vpd_id_descriptor *idd;
 
                /*
                 * XXX KDM look for LUN IDs as well?
                 */
-               item_addr = scsi_get_devid(item->device_id,
+               idd = scsi_get_devid(item->device_id,
                                           item->device_id_len,
                                           scsi_devid_is_sas_target);
-               if (item_addr == NULL)
+               if (idd == NULL)
                        continue;
 
-               if (scsi_8btou64(item_addr) == sasaddr)
+               if (scsi_8btou64(idd->identifier) == sasaddr)
                        return (item);
        }
 

Modified: stable/9/sys/cam/cam_xpt.c
==============================================================================
--- stable/9/sys/cam/cam_xpt.c  Mon Jun 17 14:46:54 2013        (r251848)
+++ stable/9/sys/cam/cam_xpt.c  Mon Jun 17 14:52:39 2013        (r251849)
@@ -1126,8 +1126,9 @@ xpt_announce_quirks(struct cam_periph *p
 int
 xpt_getattr(char *buf, size_t len, const char *attr, struct cam_path *path)
 {
-       int ret = -1;
+       int ret = -1, l;
        struct ccb_dev_advinfo cdai;
+       struct scsi_vpd_id_descriptor *idd;
 
        mtx_assert(path->bus->sim->mtx, MA_OWNED);
 
@@ -1140,7 +1141,10 @@ xpt_getattr(char *buf, size_t len, const
                cdai.buftype = CDAI_TYPE_SERIAL_NUM;
        else if (!strcmp(attr, "GEOM::physpath"))
                cdai.buftype = CDAI_TYPE_PHYS_PATH;
-       else
+       else if (!strcmp(attr, "GEOM::lunid")) {
+               cdai.buftype = CDAI_TYPE_SCSI_DEVID;
+               cdai.bufsiz = CAM_SCSI_DEVID_MAXLEN;
+       } else
                goto out;
 
        cdai.buf = malloc(cdai.bufsiz, M_CAMXPT, M_NOWAIT|M_ZERO);
@@ -1153,9 +1157,42 @@ xpt_getattr(char *buf, size_t len, const
                cam_release_devq(cdai.ccb_h.path, 0, 0, 0, FALSE);
        if (cdai.provsiz == 0)
                goto out;
-       ret = 0;
-       if (strlcpy(buf, cdai.buf, len) >= len)
-               ret = EFAULT;
+       if (cdai.buftype == CDAI_TYPE_SCSI_DEVID) {
+               idd = scsi_get_devid((struct scsi_vpd_device_id *)cdai.buf,
+                   cdai.provsiz, scsi_devid_is_lun_naa);
+               if (idd == NULL)
+                       idd = scsi_get_devid((struct scsi_vpd_device_id 
*)cdai.buf,
+                           cdai.provsiz, scsi_devid_is_lun_eui64);
+               if (idd == NULL)
+                       idd = scsi_get_devid((struct scsi_vpd_device_id 
*)cdai.buf,
+                           cdai.provsiz, scsi_devid_is_lun_t10);
+               if (idd == NULL)
+                       idd = scsi_get_devid((struct scsi_vpd_device_id 
*)cdai.buf,
+                           cdai.provsiz, scsi_devid_is_lun_name);
+               if (idd == NULL)
+                       goto out;
+               ret = 0;
+               if ((idd->proto_codeset & SVPD_ID_CODESET_MASK) == 
SVPD_ID_CODESET_ASCII ||
+                   (idd->proto_codeset & SVPD_ID_CODESET_MASK) == 
SVPD_ID_CODESET_UTF8) {
+                       l = strnlen(idd->identifier, idd->length);
+                       if (l < len) {
+                               bcopy(idd->identifier, buf, l);
+                               buf[l] = 0;
+                       } else
+                               ret = EFAULT;
+               } else {
+                       if (idd->length * 2 < len) {
+                               for (l = 0; l < idd->length; l++)
+                                       sprintf(buf + l * 2, "%02x",
+                                           idd->identifier[l]);
+                       } else
+                               ret = EFAULT;
+               }
+       } else {
+               ret = 0;
+               if (strlcpy(buf, cdai.buf, len) >= len)
+                       ret = EFAULT;
+       }
 
 out:
        if (cdai.buf != NULL)

Modified: stable/9/sys/cam/scsi/scsi_all.c
==============================================================================
--- stable/9/sys/cam/scsi/scsi_all.c    Mon Jun 17 14:46:54 2013        
(r251848)
+++ stable/9/sys/cam/scsi/scsi_all.c    Mon Jun 17 14:52:39 2013        
(r251849)
@@ -5173,7 +5173,59 @@ scsi_devid_is_sas_target(uint8_t *bufp)
        return 1;
 }
 
-uint8_t *
+int
+scsi_devid_is_lun_eui64(uint8_t *bufp)
+{
+       struct scsi_vpd_id_descriptor *descr;
+
+       descr = (struct scsi_vpd_id_descriptor *)bufp;
+       if ((descr->id_type & SVPD_ID_ASSOC_MASK) != SVPD_ID_ASSOC_LUN)
+               return 0;
+       if ((descr->id_type & SVPD_ID_TYPE_MASK) != SVPD_ID_TYPE_EUI64)
+               return 0;
+       return 1;
+}
+
+int
+scsi_devid_is_lun_naa(uint8_t *bufp)
+{
+       struct scsi_vpd_id_descriptor *descr;
+
+       descr = (struct scsi_vpd_id_descriptor *)bufp;
+       if ((descr->id_type & SVPD_ID_ASSOC_MASK) != SVPD_ID_ASSOC_LUN)
+               return 0;
+       if ((descr->id_type & SVPD_ID_TYPE_MASK) != SVPD_ID_TYPE_NAA)
+               return 0;
+       return 1;
+}
+
+int
+scsi_devid_is_lun_t10(uint8_t *bufp)
+{
+       struct scsi_vpd_id_descriptor *descr;
+
+       descr = (struct scsi_vpd_id_descriptor *)bufp;
+       if ((descr->id_type & SVPD_ID_ASSOC_MASK) != SVPD_ID_ASSOC_LUN)
+               return 0;
+       if ((descr->id_type & SVPD_ID_TYPE_MASK) != SVPD_ID_TYPE_T10)
+               return 0;
+       return 1;
+}
+
+int
+scsi_devid_is_lun_name(uint8_t *bufp)
+{
+       struct scsi_vpd_id_descriptor *descr;
+
+       descr = (struct scsi_vpd_id_descriptor *)bufp;
+       if ((descr->id_type & SVPD_ID_ASSOC_MASK) != SVPD_ID_ASSOC_LUN)
+               return 0;
+       if ((descr->id_type & SVPD_ID_TYPE_MASK) != SVPD_ID_TYPE_SCSI_NAME)
+               return 0;
+       return 1;
+}
+
+struct scsi_vpd_id_descriptor *
 scsi_get_devid(struct scsi_vpd_device_id *id, uint32_t page_len,
     scsi_devid_checkfn_t ck_fn)
 {
@@ -5194,7 +5246,7 @@ scsi_get_devid(struct scsi_vpd_device_id
                                                    + desc->length)) {
 
                if (ck_fn == NULL || ck_fn((uint8_t *)desc) != 0)
-                       return (desc->identifier);
+                       return (desc);
        }
 
        return (NULL);

Modified: stable/9/sys/cam/scsi/scsi_all.h
==============================================================================
--- stable/9/sys/cam/scsi/scsi_all.h    Mon Jun 17 14:46:54 2013        
(r251848)
+++ stable/9/sys/cam/scsi/scsi_all.h    Mon Jun 17 14:52:39 2013        
(r251849)
@@ -1292,6 +1292,7 @@ struct scsi_vpd_id_descriptor
 #define        SVPD_ID_PROTO_SHIFT     4
 #define        SVPD_ID_CODESET_BINARY  0x01
 #define        SVPD_ID_CODESET_ASCII   0x02
+#define        SVPD_ID_CODESET_UTF8    0x03
 #define        SVPD_ID_CODESET_MASK    0x0f
        u_int8_t        id_type;
 #define        SVPD_ID_PIV             0x80
@@ -2315,7 +2316,12 @@ u_int            scsi_calc_syncparam(u_int period)
 typedef int    (*scsi_devid_checkfn_t)(uint8_t *);
 int            scsi_devid_is_naa_ieee_reg(uint8_t *bufp);
 int            scsi_devid_is_sas_target(uint8_t *bufp);
-uint8_t *      scsi_get_devid(struct scsi_vpd_device_id *id, uint32_t len,
+int            scsi_devid_is_lun_eui64(uint8_t *bufp);
+int            scsi_devid_is_lun_naa(uint8_t *bufp);
+int            scsi_devid_is_lun_name(uint8_t *bufp);
+int            scsi_devid_is_lun_t10(uint8_t *bufp);
+struct scsi_vpd_id_descriptor *
+               scsi_get_devid(struct scsi_vpd_device_id *id, uint32_t len,
                               scsi_devid_checkfn_t ck_fn);
 
 void           scsi_test_unit_ready(struct ccb_scsiio *csio, u_int32_t retries,

Modified: stable/9/sys/cam/scsi/scsi_enc_ses.c
==============================================================================
--- stable/9/sys/cam/scsi/scsi_enc_ses.c        Mon Jun 17 14:46:54 2013        
(r251848)
+++ stable/9/sys/cam/scsi/scsi_enc_ses.c        Mon Jun 17 14:52:39 2013        
(r251849)
@@ -1056,7 +1056,8 @@ ses_set_physpath(enc_softc_t *enc, enc_e
        ses_setphyspath_callback_args_t args;
        int i, ret;
        struct sbuf sb;
-       uint8_t *devid, *elmaddr;
+       struct scsi_vpd_id_descriptor *idd;
+       uint8_t *devid;
        ses_element_t *elmpriv;
        const char *c;
 
@@ -1084,9 +1085,9 @@ ses_set_physpath(enc_softc_t *enc, enc_e
        if (cdai.ccb_h.status != CAM_REQ_CMP)
                goto out;
 
-       elmaddr = scsi_get_devid((struct scsi_vpd_device_id *)cdai.buf,
+       idd = scsi_get_devid((struct scsi_vpd_device_id *)cdai.buf,
            cdai.provsiz, scsi_devid_is_naa_ieee_reg);
-       if (elmaddr == NULL)
+       if (idd == NULL)
                goto out;
 
        if (sbuf_new(&sb, NULL, 128, SBUF_AUTOEXTEND) == NULL) {
@@ -1095,7 +1096,7 @@ ses_set_physpath(enc_softc_t *enc, enc_e
        }
        /* Next, generate the physical path string */
        sbuf_printf(&sb, "id1,enc@n%jx/type@%x/slot@%x",
-           scsi_8btou64(elmaddr), iter->type_index,
+           scsi_8btou64(idd->identifier), iter->type_index,
            iter->type_element_index);
        /* Append the element descriptor if one exists */
        elmpriv = elm->elm_private;

Modified: stable/9/sys/geom/geom_disk.c
==============================================================================
--- stable/9/sys/geom/geom_disk.c       Mon Jun 17 14:46:54 2013        
(r251848)
+++ stable/9/sys/geom/geom_disk.c       Mon Jun 17 14:52:39 2013        
(r251849)
@@ -398,8 +398,11 @@ g_disk_start(struct bio *bp)
 static void
 g_disk_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp, struct 
g_consumer *cp, struct g_provider *pp)
 {
+       struct bio *bp;
        struct disk *dp;
        struct g_disk_softc *sc;
+       char *buf;
+       int res = 0;
 
        sc = gp->softc;
        if (sc == NULL || (dp = sc->dp) == NULL)
@@ -414,7 +417,27 @@ g_disk_dumpconf(struct sbuf *sb, const c
                    indent, dp->d_fwheads);
                sbuf_printf(sb, "%s<fwsectors>%u</fwsectors>\n",
                    indent, dp->d_fwsectors);
-               sbuf_printf(sb, "%s<ident>%s</ident>\n", indent, dp->d_ident);
+               if (dp->d_getattr != NULL) {
+                       buf = g_malloc(DISK_IDENT_SIZE, M_WAITOK);
+                       bp = g_alloc_bio();
+                       bp->bio_disk = dp;
+                       bp->bio_attribute = "GEOM::ident";
+                       bp->bio_length = DISK_IDENT_SIZE;
+                       bp->bio_data = buf;
+                       res = dp->d_getattr(bp);
+                       sbuf_printf(sb, "%s<ident>%s</ident>\n", indent,
+                           res == 0 ? buf: dp->d_ident);
+                       bp->bio_attribute = "GEOM::lunid";
+                       bp->bio_length = DISK_IDENT_SIZE;
+                       bp->bio_data = buf;
+                       if (dp->d_getattr(bp) == 0)
+                               sbuf_printf(sb, "%s<lunid>%s</lunid>\n",
+                                   indent, buf);
+                       g_destroy_bio(bp);
+                       g_free(buf);
+               } else
+                       sbuf_printf(sb, "%s<ident>%s</ident>\n", indent,
+                           dp->d_ident);
                sbuf_printf(sb, "%s<descr>%s</descr>\n", indent, dp->d_descr);
        }
 }
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to