iscsi: Query and save device designator when opening

The device designator data returned in INQUIRY command will be useful to
fill in source/target fields during copy offloading. Do this when
connecting to the target and save the data for later use.

Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 20180601092648.24614-7-famz@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
Fam Zheng 2018-06-01 17:26:44 +08:00 committed by Stefan Hajnoczi
parent 1efad060d7
commit cc9743c236

View file

@ -68,6 +68,7 @@ typedef struct IscsiLun {
QemuMutex mutex; QemuMutex mutex;
struct scsi_inquiry_logical_block_provisioning lbp; struct scsi_inquiry_logical_block_provisioning lbp;
struct scsi_inquiry_block_limits bl; struct scsi_inquiry_block_limits bl;
struct scsi_inquiry_device_designator *dd;
unsigned char *zeroblock; unsigned char *zeroblock;
/* The allocmap tracks which clusters (pages) on the iSCSI target are /* The allocmap tracks which clusters (pages) on the iSCSI target are
* allocated and which are not. In case a target returns zeros for * allocated and which are not. In case a target returns zeros for
@ -1740,6 +1741,30 @@ static QemuOptsList runtime_opts = {
}, },
}; };
static void iscsi_save_designator(IscsiLun *lun,
struct scsi_inquiry_device_identification *inq_di)
{
struct scsi_inquiry_device_designator *desig, *copy = NULL;
for (desig = inq_di->designators; desig; desig = desig->next) {
if (desig->association ||
desig->designator_type > SCSI_DESIGNATOR_TYPE_NAA) {
continue;
}
/* NAA works better than T10 vendor ID based designator. */
if (!copy || copy->designator_type < desig->designator_type) {
copy = desig;
}
}
if (copy) {
lun->dd = g_new(struct scsi_inquiry_device_designator, 1);
*lun->dd = *copy;
lun->dd->next = NULL;
lun->dd->designator = g_malloc(copy->designator_length);
memcpy(lun->dd->designator, copy->designator, copy->designator_length);
}
}
static int iscsi_open(BlockDriverState *bs, QDict *options, int flags, static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
Error **errp) Error **errp)
{ {
@ -1922,6 +1947,7 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
struct scsi_task *inq_task; struct scsi_task *inq_task;
struct scsi_inquiry_logical_block_provisioning *inq_lbp; struct scsi_inquiry_logical_block_provisioning *inq_lbp;
struct scsi_inquiry_block_limits *inq_bl; struct scsi_inquiry_block_limits *inq_bl;
struct scsi_inquiry_device_identification *inq_di;
switch (inq_vpd->pages[i]) { switch (inq_vpd->pages[i]) {
case SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING: case SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING:
inq_task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1, inq_task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
@ -1947,6 +1973,17 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
sizeof(struct scsi_inquiry_block_limits)); sizeof(struct scsi_inquiry_block_limits));
scsi_free_scsi_task(inq_task); scsi_free_scsi_task(inq_task);
break; break;
case SCSI_INQUIRY_PAGECODE_DEVICE_IDENTIFICATION:
inq_task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
SCSI_INQUIRY_PAGECODE_DEVICE_IDENTIFICATION,
(void **) &inq_di, errp);
if (inq_task == NULL) {
ret = -EINVAL;
goto out;
}
iscsi_save_designator(iscsilun, inq_di);
scsi_free_scsi_task(inq_task);
break;
default: default:
break; break;
} }
@ -2003,6 +2040,10 @@ static void iscsi_close(BlockDriverState *bs)
iscsi_logout_sync(iscsi); iscsi_logout_sync(iscsi);
} }
iscsi_destroy_context(iscsi); iscsi_destroy_context(iscsi);
if (iscsilun->dd) {
g_free(iscsilun->dd->designator);
g_free(iscsilun->dd);
}
g_free(iscsilun->zeroblock); g_free(iscsilun->zeroblock);
iscsi_allocmap_free(iscsilun); iscsi_allocmap_free(iscsilun);
qemu_mutex_destroy(&iscsilun->mutex); qemu_mutex_destroy(&iscsilun->mutex);