Add CTL support for REPORT IDENTIFYING INFORMATION command.

It allows to report to initiator LU identifying information, preset via
"ident_info" and "text_ident_info" options.

Unfortunately it is impossible to implement SET IDENTIFYING INFORMATION,
since we have no persistent storage it requires, so the information is
read-only for initiator and has to be set out-of-band.

MFC after:	1 week
Sponsored by:	iXsystems, Inc.
This commit is contained in:
Alexander Motin 2020-08-06 19:16:11 +00:00
parent e039e3d1d2
commit 8bdf81e4d1
5 changed files with 130 additions and 7 deletions

View File

@ -7129,6 +7129,88 @@ ctl_read_defect(struct ctl_scsiio *ctsio)
return (CTL_RETVAL_COMPLETE);
}
int
ctl_report_ident_info(struct ctl_scsiio *ctsio)
{
struct ctl_lun *lun = CTL_LUN(ctsio);
struct scsi_report_ident_info *cdb;
struct scsi_report_ident_info_data *rii_ptr;
struct scsi_report_ident_info_descr *riid_ptr;
const char *oii, *otii;
int retval, alloc_len, total_len = 0, len = 0;
CTL_DEBUG_PRINT(("ctl_report_ident_info\n"));
cdb = (struct scsi_report_ident_info *)ctsio->cdb;
retval = CTL_RETVAL_COMPLETE;
total_len = sizeof(struct scsi_report_ident_info_data);
switch (cdb->type) {
case RII_LUII:
oii = dnvlist_get_string(lun->be_lun->options,
"ident_info", NULL);
if (oii)
len = strlen(oii); /* Approximately */
break;
case RII_LUTII:
otii = dnvlist_get_string(lun->be_lun->options,
"text_ident_info", NULL);
if (otii)
len = strlen(otii) + 1; /* NULL-terminated */
break;
case RII_IIS:
len = 2 * sizeof(struct scsi_report_ident_info_descr);
break;
default:
ctl_set_invalid_field(/*ctsio*/ ctsio,
/*sks_valid*/ 1,
/*command*/ 1,
/*field*/ 11,
/*bit_valid*/ 1,
/*bit*/ 2);
ctl_done((union ctl_io *)ctsio);
return(retval);
}
total_len += len;
alloc_len = scsi_4btoul(cdb->length);
ctsio->kern_data_ptr = malloc(total_len, M_CTL, M_WAITOK | M_ZERO);
ctsio->kern_sg_entries = 0;
ctsio->kern_rel_offset = 0;
ctsio->kern_data_len = min(total_len, alloc_len);
ctsio->kern_total_len = ctsio->kern_data_len;
rii_ptr = (struct scsi_report_ident_info_data *)ctsio->kern_data_ptr;
switch (cdb->type) {
case RII_LUII:
if (oii) {
if (oii[0] == '0' && oii[1] == 'x')
len = hex2bin(oii, (uint8_t *)(rii_ptr + 1), len);
else
strncpy((uint8_t *)(rii_ptr + 1), oii, len);
}
break;
case RII_LUTII:
if (otii)
strlcpy((uint8_t *)(rii_ptr + 1), otii, len);
break;
case RII_IIS:
riid_ptr = (struct scsi_report_ident_info_descr *)(rii_ptr + 1);
riid_ptr->type = RII_LUII;
scsi_ulto2b(0xffff, riid_ptr->length);
riid_ptr++;
riid_ptr->type = RII_LUTII;
scsi_ulto2b(0xffff, riid_ptr->length);
}
scsi_ulto2b(len, rii_ptr->length);
ctl_set_success(ctsio);
ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED;
ctsio->be_move_done = ctl_config_move_done;
ctl_datamove((union ctl_io *)ctsio);
return(retval);
}
int
ctl_report_tagret_port_groups(struct ctl_scsiio *ctsio)
{

View File

@ -829,8 +829,15 @@ const struct ctl_cmd_entry ctl_cmd_table_a3[32] =
/* 04 */
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
/* 05 */
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
/* 05 REPORT IDENTIFYING INFORMATION */
{ctl_report_ident_info, CTL_SERIDX_INQ, CTL_CMD_FLAG_OK_ON_BOTH |
CTL_CMD_FLAG_OK_ON_NO_MEDIA |
CTL_CMD_FLAG_OK_ON_STANDBY |
CTL_CMD_FLAG_OK_ON_UNAVAIL |
CTL_FLAG_DATA_IN |
CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
CTL_LUN_PAT_NONE,
12, {0x0f, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x07}},
/* 06 */
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
@ -854,7 +861,7 @@ const struct ctl_cmd_entry ctl_cmd_table_a3[32] =
CTL_LUN_PAT_NONE,
12, {0xea, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0, 0x07}},
/* 0B */
/* 0B REPORT ALIASES */
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
/* 0C REPORT SUPPORTED_OPCODES */
@ -877,7 +884,7 @@ const struct ctl_cmd_entry ctl_cmd_table_a3[32] =
CTL_LUN_PAT_NONE,
12, {0x0d, 0x80, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0, 0x07}},
/* 0E */
/* 0E REPORT PRIORITY */
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
/* 0F REPORT TIMESTAMP */
@ -890,7 +897,10 @@ const struct ctl_cmd_entry ctl_cmd_table_a3[32] =
CTL_LUN_PAT_NONE,
12, {0x0f, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0, 0x07}},
/* 10-1f */
/* 10 MANAGEMENT PROTOCOL IN */
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
/* 11-1f */
};
const struct ctl_cmd_entry ctl_cmd_table[256] =

View File

@ -517,6 +517,7 @@ int ctl_get_event_status(struct ctl_scsiio *ctsio);
int ctl_mechanism_status(struct ctl_scsiio *ctsio);
int ctl_persistent_reserve_in(struct ctl_scsiio *ctsio);
int ctl_persistent_reserve_out(struct ctl_scsiio *ctsio);
int ctl_report_ident_info(struct ctl_scsiio *ctsio);
int ctl_report_tagret_port_groups(struct ctl_scsiio *ctsio);
int ctl_report_supported_opcodes(struct ctl_scsiio *ctsio);
int ctl_report_supported_tmf(struct ctl_scsiio *ctsio);

View File

@ -1484,6 +1484,32 @@ struct scsi_maintenance_in
uint8_t control;
};
struct scsi_report_ident_info
{
uint8_t opcode;
uint8_t service_action;
uint8_t reserved[4];
uint8_t length[4];
uint8_t type;
#define RII_LUII 0x00
#define RII_LUTII 0x04
#define RII_IIS 0xfc
uint8_t control;
};
struct scsi_report_ident_info_data
{
uint8_t reserved[2];
uint8_t length[2];
};
struct scsi_report_ident_info_descr
{
uint8_t type;
uint8_t reserved;
uint8_t length[2];
};
struct scsi_report_supported_opcodes
{
uint8_t opcode;

View File

@ -1,6 +1,6 @@
.\"
.\" Copyright (c) 2003 Silicon Graphics International Corp.
.\" Copyright (c) 2015 Alexander Motin <mav@FreeBSD.org>
.\" Copyright (c) 2015-2020 Alexander Motin <mav@FreeBSD.org>
.\" Copyright (c) 2018 Marcelo Araujo <araujo@FreeBSD.org>
.\" All rights reserved.
.\"
@ -36,7 +36,7 @@
.\" $Id: //depot/users/kenm/FreeBSD-test2/usr.sbin/ctladm/ctladm.8#3 $
.\" $FreeBSD$
.\"
.Dd July 25, 2019
.Dd August 6, 2020
.Dt CTLADM 8
.Os
.Sh NAME
@ -877,6 +877,10 @@ EUI, NAA or UUID identifier should be set to UNIQUE value to allow
EXTENDED COPY command access the LUN.
Non-unique LUN identifiers may lead to data corruption.
Some initiators may not support later introduced UUID identifiers.
.It Va ident_info
Specified LUN identification information (string or 0x + hex).
.It Va text_ident_info
Specified LUN text identification information (UTF-8 string).
.It Va ha_role
Setting to "primary" or "secondary" overrides default role of the node
in HA cluster, set by kern.cam.ctl.ha_role sysctl.