[PATCH] Add new module entry points for configuration
Mark Harvey
markh794
Thu May 31 22:00:43 CEST 2007
Add new module entry points.
<module>_lu_init(struct scsi_lu *lu) - called at setup time.
<module>_lu_exit(struct scsi_lu *lu) - called at shutdown time.
<module>_lu_config(struct scsi_lu *lu) - Any module unique configuration.
Moved logical unit configuration from target -> <module>
Along with above entry point <module>_lu_config(), will allow module
specific configuration.
No new functionality added yet.
Add a dump_cdb(struct scsi_cmd *cmd) - Called from spc_illegal_op()
Update - All modules use common INQUIRY routine.
Signed-off-by: Mark Harvey <markh794 at gmail.com>
diff --git a/usr/mmc.c b/usr/mmc.c
index e9cc479..ae0a0ca 100644
--- a/usr/mmc.c
+++ b/usr/mmc.c
@@ -121,11 +121,32 @@ static int mmc_read_capacity(int host_no, struct
scsi_cmd *cmd)
return SAM_STAT_GOOD;
}
+static int mmc_lu_init(struct scsi_lu *lu)
+{
+ if (spc_lu_init(lu))
+ return -ENOMEM;
+
+ memcpy(lu->attributes->ProductIdent, "VIRTUAL-CDROM", 16);
+ lu->attributes->sense_format = 1;
+ lu->attributes->version_desc[0] = 0x02A0; /* MMC3, no version claimed */
+ lu->attributes->version_desc[1] = 0x0960; /* iSCSI */
+ lu->attributes->version_desc[2] = 0x0300; /* SPC-3 */
+
+ return 0;
+}
+
+static int mmc_lu_exit(struct scsi_lu *lu)
+{
+ return 0;
+}
+
struct device_type_template mmc_template = {
- .type = TYPE_ROM,
- .name = "cdrom/dvd",
- .pid = "VIRTUAL-CDROM",
- .ops = {
+ .type = TYPE_ROM,
+ .name = "cdrom/dvd",
+ .lu_init = mmc_lu_init,
+ .lu_exit = mmc_lu_exit,
+ .lu_config = spc_lu_config,
+ .ops = {
{spc_test_unit,},
{spc_illegal_op,},
{spc_illegal_op,},
diff --git a/usr/osd.c b/usr/osd.c
index 46bf0a0..0ce8fde 100644
--- a/usr/osd.c
+++ b/usr/osd.c
@@ -20,6 +20,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
+#include <errno.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
@@ -33,101 +34,6 @@
#include "scsi.h"
#include "spc.h"
-#define PRODUCT_ID "OSD"
-#define PRODUCT_REV "0"
-
-static int osd_inquiry(int host_no, struct scsi_cmd *cmd)
-{
- uint8_t *data, *scb = cmd->scb;
- int len, ret = SAM_STAT_CHECK_CONDITION;
- unsigned char key = ILLEGAL_REQUEST, asc = 0x25;
-
- /* EVPD means need a page code */
- if ((scb[1] & 0x3) == 0 && scb[2] != 0)
- goto sense;
-
- data = valloc(pagesize);
- if (!data) {
- key = HARDWARE_ERROR;
- asc = 0;
- goto sense;
- }
- memset(data, 0, pagesize);
-
- dprintf("%x %x\n", scb[1], scb[2]);
-
- data[0] = TYPE_OSD;
- if (!cmd->dev)
- data[0] = TYPE_NO_LUN;
-
- if ((scb[1] & 0x1) == 0) {
- data[2] = 5; /* modern version */
- data[3] = 0x02; /* modern response format */
- data[7] = 0x02; /* support command queueing */
- memset(data + 8, 0x20, 28);
- memcpy(data + 8,
- VENDOR_ID, min_t(size_t, strlen(VENDOR_ID), 8));
- memcpy(data + 16,
- PRODUCT_ID, min_t(size_t, strlen(PRODUCT_ID), 16));
- memcpy(data + 32,
- PRODUCT_REV, min_t(size_t, strlen(PRODUCT_REV), 4));
- len = 36;
- if (cmd->dev) {
- data[58] = 0x03;
- data[59] = 0x40; /* osd */
- data[60] = 0x09;
- data[61] = 0x60; /* iscsi */
- data[62] = 0x03;
- data[63] = 0x00; /* spc3 */
- len = 64;
- }
- data[4] = len - 5; /* additional length */
- ret = SAM_STAT_GOOD;
- } else {
- if (!cmd->dev)
- goto sense;
-
- data[1] = scb[2];
- if (scb[2] == 0x0) {
- /* supported VPD pages */
- data[3] = 3;
- data[4] = 0x0;
- data[5] = 0x80;
- data[6] = 0x83;
- len = 7;
- ret = SAM_STAT_GOOD;
- } else if (scb[2] == 0x80) {
- /* unit serial number " " */
- data[3] = 4;
- memset(data + 4, 0x20, 4);
- len = 8;
- ret = SAM_STAT_GOOD;
- } else if (scb[2] == 0x83) {
- /* device identification */
- data[3] = SCSI_ID_LEN + 4;
- data[4] = 0x1;
- data[5] = 0x1;
- data[7] = SCSI_ID_LEN;
- if (cmd->dev)
- memcpy(data + 8, cmd->dev->scsi_id,
SCSI_ID_LEN);
- len = SCSI_ID_LEN + 8;
- ret = SAM_STAT_GOOD;
- }
- }
-
- if (ret != SAM_STAT_GOOD)
- goto sense;
-
- cmd->len = min_t(int, len, scb[4]);
- cmd->uaddr = (unsigned long) data;
-
- return SAM_STAT_GOOD;
-sense:
- sense_data_build(cmd, key, asc, 0);
- cmd->len = 0;
- return SAM_STAT_CHECK_CONDITION;
-}
-
static int osd_varlen_cdb(int host_no, struct scsi_cmd *cmd)
{
unsigned char key = ILLEGAL_REQUEST, asc = 0x25;
@@ -145,22 +51,37 @@ static int osd_varlen_cdb(int host_no, struct
scsi_cmd *cmd)
return cmd->c_target->bst->bs_cmd_submit(cmd);
}
-static void device_osd_init(struct scsi_lu *lu)
+static int osd_lu_init(struct scsi_lu *lu)
+{
+ if (spc_lu_init(lu))
+ return -ENOMEM;
+
+ memcpy(lu->attributes->ProductIdent, "OSD", 16);
+ lu->attributes->sense_format = 1;
+ lu->attributes->version_desc[0] = 0x0340; /* OSD */
+ lu->attributes->version_desc[1] = 0x0960; /* iSCSI */
+ lu->attributes->version_desc[2] = 0x0300; /* SPC-3 */
+
+ return 0;
+}
+
+static int osd_lu_exit(struct scsi_lu *lu)
{
- lu->d_sense = 1;
+ return 0;
}
struct device_type_template osd_template = {
.type = TYPE_OSD,
.name = "osd",
- .device_init = device_osd_init,
+ .lu_init = osd_lu_init,
+ .lu_exit = osd_lu_exit,
.ops = {
[0x00 ... 0x0f] = {spc_illegal_op},
/* 0x10 */
{spc_illegal_op,},
{spc_illegal_op,},
- {osd_inquiry,},
+ {spc_inquiry,},
{spc_illegal_op,},
{spc_illegal_op,},
{spc_illegal_op,},
diff --git a/usr/parser.h b/usr/parser.h
index 1ff6016..bf210bf 100644
--- a/usr/parser.h
+++ b/usr/parser.h
@@ -17,7 +17,7 @@ struct match_token {
typedef struct match_token match_table_t[];
/* Maximum number of arguments that match_token will find in a pattern */
-enum {MAX_OPT_ARGS = 3};
+enum {MAX_OPT_ARGS = 17};
/* Describe the location within a string of a substring */
typedef struct {
diff --git a/usr/sbc.c b/usr/sbc.c
index a22d3b0..5357087 100644
--- a/usr/sbc.c
+++ b/usr/sbc.c
@@ -337,11 +337,31 @@ sense:
return SAM_STAT_CHECK_CONDITION;
}
+static int sbc_lu_init(struct scsi_lu *lu)
+{
+ if (spc_lu_init(lu))
+ return -ENOMEM;
+
+ memcpy(lu->attributes->ProductIdent, "VIRTUAL-DISK", 16);
+ lu->attributes->version_desc[0] = 0x04C0; /* SBC-3 no version claimed */
+ lu->attributes->version_desc[1] = 0x0960; /* iSCSI */
+ lu->attributes->version_desc[2] = 0x0300; /* SPC-3 */
+
+ return 0;
+}
+
+static int sbc_lu_exit(struct scsi_lu *lu)
+{
+ return 0;
+}
+
struct device_type_template sbc_template = {
- .type = TYPE_DISK,
- .name = "disk",
- .pid = "VIRTUAL-DISK",
- .ops = {
+ .type = TYPE_DISK,
+ .name = "disk",
+ .lu_init = sbc_lu_init,
+ .lu_exit = sbc_lu_exit,
+ .lu_config = spc_lu_config,
+ .ops = {
{spc_test_unit,},
{spc_illegal_op,},
{spc_illegal_op,},
diff --git a/usr/scsi.c b/usr/scsi.c
index 1a6929f..728dfe9 100644
--- a/usr/scsi.c
+++ b/usr/scsi.c
@@ -40,7 +40,7 @@
void sense_data_build(struct scsi_cmd *cmd, uint8_t key, uint8_t asc,
uint8_t asq)
{
- if (cmd->dev && cmd->dev->d_sense) {
+ if (cmd->dev && cmd->dev->attributes->sense_format) {
/* descriptor format */
cmd->sense_buffer[0] = 0x72; /* current, not deferred */
@@ -121,3 +121,4 @@ int scsi_cmd_perform(int host_no, struct scsi_cmd *cmd)
unsigned char op = cmd->scb[0];
return cmd->c_target->dev_type_template.ops[op].cmd_perform(host_no,
cmd);
}
+
diff --git a/usr/spc.c b/usr/spc.c
index b922a45..e9a74d9 100644
--- a/usr/spc.c
+++ b/usr/spc.c
@@ -19,6 +19,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
+#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -27,12 +28,15 @@
#include "list.h"
#include "util.h"
#include "tgtd.h"
+#include "parser.h"
#include "target.h"
#include "driver.h"
+#include "tgtadm_error.h"
#include "scsi.h"
#include "spc.h"
#define PRODUCT_REV "0"
+#define BLK_SHIFT 9
int spc_inquiry(int host_no, struct scsi_cmd *cmd)
{
@@ -40,7 +44,7 @@ int spc_inquiry(int host_no, struct scsi_cmd *cmd)
uint8_t *data;
uint8_t *scb = cmd->scb;
unsigned char device_type = cmd->c_target->dev_type_template.type;
- char *product_id = cmd->c_target->dev_type_template.pid;
+ struct physicalAttributes * attributes = cmd->dev->attributes;
unsigned char key = ILLEGAL_REQUEST, asc = 0x24;
if (((scb[1] & 0x3) == 0x3) || (!(scb[1] & 0x3) && scb[2]))
@@ -57,22 +61,21 @@ int spc_inquiry(int host_no, struct scsi_cmd *cmd)
dprintf("%x %x\n", scb[1], scb[2]);
if (!(scb[1] & 0x3)) {
+ int i;
data[0] = device_type;
- data[2] = 4;
+ data[1] = (attributes->isRemovable) ? 0x80 : 0;
+ data[2] = 5; /* SPC-3 */
data[3] = 0x42;
- data[4] = 59;
data[7] = 0x02;
memset(data + 8, 0x20, 28);
- strncpy((char *)data + 8, VENDOR_ID, 8);
- strncpy((char *)data + 16, product_id, 16);
- strncpy((char *)data + 32, PRODUCT_REV, 4);
- data[58] = 0x03;
- data[59] = 0x20;
- data[60] = 0x09;
- data[61] = 0x60;
- data[62] = 0x03;
- data[63] = 0x00;
- len = 64;
+ strncpy((char *)data + 8, attributes->VendorIdent, 8);
+ strncpy((char *)data + 16, attributes->ProductIdent, 16);
+ strncpy((char *)data + 32, attributes->ProductRev, 4);
+ for (i=0, len=58; i < VERSION_DESCRIPTOR_LEN; i++, len += 2) {
+ data[len] = (attributes->version_desc[i] >> 8) & 0xff;
+ data[len+1] = attributes->version_desc[i] & 0xff;
+ }
+ data[4] = len - 5; /* Additional Length */
ret = SAM_STAT_GOOD;
} else if (scb[1] & 0x2) {
/* CmdDt bit is set */
@@ -101,13 +104,13 @@ int spc_inquiry(int host_no, struct scsi_cmd *cmd)
len = 4 + SCSI_SN_LEN;
ret = SAM_STAT_GOOD;
- if (cmd->dev && strlen(cmd->dev->scsi_sn)) {
+ if (cmd->dev && strlen(cmd->dev->attributes->scsi_sn)) {
uint8_t *p;
char *q;
p = data + 4 + tmp - 1;
- q = cmd->dev->scsi_sn + SCSI_SN_LEN - 1;
-
+ q = cmd->dev->attributes->scsi_sn +
+ SCSI_SN_LEN - 1;
for (; tmp > 0; tmp--, q)
*(p--) = *(q--);
}
@@ -120,7 +123,8 @@ int spc_inquiry(int host_no, struct scsi_cmd *cmd)
data[5] = 0x1;
data[7] = tmp;
if (cmd->dev)
- strncpy((char *) data + 8, cmd->dev->scsi_id,
+ strncpy((char *) data + 8,
+ cmd->dev->attributes->scsi_id,
SCSI_ID_LEN);
len = tmp + 8;
ret = SAM_STAT_GOOD;
@@ -238,9 +242,98 @@ int spc_request_sense(int host_no, struct scsi_cmd *cmd)
return SAM_STAT_GOOD;
}
+void dump_cdb(struct scsi_cmd *cmd)
+{
+ uint8_t * cdb = cmd->scb;
+
+ switch(cmd->scb_len) {
+ case 6:
+ dprintf("SCSI CMD: %02x %02x %02x %02x %02d %02x",
+ cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5]);
+ break;
+ case 10:
+ dprintf("SCSI CMD: %02x %02x %02x %02x %02d %02x"
+ " %02x %02x %02x %02x",
+ cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5],
+ cdb[6], cdb[7], cdb[8], cdb[9]);
+ break;
+ case 12:
+ dprintf("SCSI CMD: %02x %02x %02x %02x %02d %02x"
+ " %02x %02x %02x %02x %02x %02x",
+ cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5],
+ cdb[6], cdb[7], cdb[8], cdb[9], cdb[10], cdb[11]);
+ break;
+ case 16:
+ dprintf("SCSI CMD: %02x %02x %02x %02x %02d %02x"
+ " %02x %02x %02x %02x %02x %02x"
+ " %02x %02x %02x %02x",
+ cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5],
+ cdb[6], cdb[7], cdb[8], cdb[9], cdb[10], cdb[11],
+ cdb[12], cdb[13], cdb[14], cdb[15]);
+ break;
+ }
+}
+
int spc_illegal_op(int host_no, struct scsi_cmd *cmd)
{
+ dump_cdb(cmd);
cmd->len = 0;
sense_data_build(cmd, ILLEGAL_REQUEST, 0x20, 0);
return SAM_STAT_CHECK_CONDITION;
}
+
+enum {
+ Opt_scsiid, Opt_scsisn, Opt_err,
+};
+
+static match_table_t tokens = {
+ {Opt_scsiid, "scsi_id=%s"},
+ {Opt_scsisn, "scsi_sn=%s"},
+ {Opt_err, NULL},
+};
+
+int spc_lu_config(struct scsi_lu *lu, char * params) {
+ int err = 0;
+ char *p;
+
+ if (!strncmp("targetOps", params, 9))
+ params = params + 10;
+
+ while ((p = strsep(¶ms, ",")) != NULL) {
+ substring_t args[MAX_OPT_ARGS];
+ int token;
+ if (!*p)
+ continue;
+ dprintf("*p : %s\n", p);
+ token = match_token(p, tokens, args);
+ switch (token) {
+ case Opt_scsiid:
+ match_strncpy(lu->attributes->scsi_id, &args[0],
+ sizeof(lu->attributes->scsi_id) - 1);
+ break;
+ case Opt_scsisn:
+ match_strncpy(lu->attributes->scsi_sn, &args[0],
+ sizeof(lu->attributes->scsi_sn) - 1);
+ break;
+ default:
+ err = TGTADM_INVALID_REQUEST;
+ }
+ }
+ return err;
+}
+
+int spc_lu_init(struct scsi_lu * lu)
+{
+ lu->attributes = zalloc(sizeof(struct physicalAttributes));
+ if(!lu->attributes)
+ return -ENOMEM;
+
+ memcpy(lu->attributes->VendorIdent, VENDOR_ID, 8);
+ memcpy(lu->attributes->ProductRev, "0001", 4);
+ lu->attributes->isRemovable = 0;
+ lu->attributes->sense_format = 0;
+ lu->attributes->onLine = 0;
+ lu->attributes->reset = 1;
+
+ return 0;
+}
diff --git a/usr/spc.h b/usr/spc.h
index f81e74c..1036b70 100644
--- a/usr/spc.h
+++ b/usr/spc.h
@@ -7,5 +7,8 @@ extern int spc_start_stop(int host_no, struct scsi_cmd *cmd);
extern int spc_test_unit(int host_no, struct scsi_cmd *cmd);
extern int spc_request_sense(int host_no, struct scsi_cmd *cmd);
extern int spc_illegal_op(int host_no, struct scsi_cmd *cmd);
+extern int spc_lu_init(struct scsi_lu *lu);
+extern int spc_lu_config(struct scsi_lu *lu, char * params);
+extern void dump_cdb(struct scsi_cmd *cmd);
#endif
diff --git a/usr/target.c b/usr/target.c
index 23f450f..e3fa1e0 100644
--- a/usr/target.c
+++ b/usr/target.c
@@ -29,7 +29,6 @@
#include <sys/socket.h>
#include "list.h"
-#include "parser.h"
#include "util.h"
#include "tgtd.h"
#include "driver.h"
@@ -247,13 +246,19 @@ int tgt_device_create(int tid, uint64_t lun, char *args)
lu->lun = lun;
lu->lu_state = SCSI_LU_RUNNING;
- snprintf(lu->scsi_id, sizeof(lu->scsi_id),
- "deadbeaf%d:%" PRIu64, tid, lun);
-
tgt_cmd_queue_init(&lu->cmd_queue);
- if (target->dev_type_template.device_init)
- target->dev_type_template.device_init(lu);
+ if (target->dev_type_template.lu_init)
+ err = target->dev_type_template.lu_init(lu);
+
+ if(!err) {
+ snprintf(lu->attributes->scsi_id,
+ sizeof(lu->attributes->scsi_id),
+ "deadbeaf%d:%" PRIu64, tid, lun);
+ snprintf(lu->attributes->scsi_sn,
+ sizeof(lu->attributes->scsi_sn),
+ "beaf%d%" PRIu64, tid, lun);
+ }
list_for_each_entry(pos, &target->device_list, device_siblings) {
if (lu->lun < pos->lun)
@@ -262,13 +267,14 @@ int tgt_device_create(int tid, uint64_t lun, char *args)
list_add_tail(&lu->device_siblings, &pos->device_siblings);
dprintf("Add a logical unit %" PRIu64 " to the target %d\n", lun, tid);
- return 0;
+ return err;
}
int tgt_device_destroy(int tid, uint64_t lun)
{
struct target *target;
struct scsi_lu *lu;
+ int err;
dprintf("%u %" PRIu64 "\n", tid, lun);
@@ -281,12 +287,14 @@ int tgt_device_destroy(int tid, uint64_t lun)
if (!list_empty(&lu->cmd_queue.queue) || lu->cmd_queue.active_cmd)
return TGTADM_LUN_ACTIVE;
+ err = target->dev_type_template.lu_exit(lu);
+
free(lu->path);
list_del(&lu->device_siblings);
target->bst->bs_close(lu);
free(lu);
- return 0;
+ return err;
}
int device_reserve(struct scsi_cmd *cmd)
@@ -339,20 +347,9 @@ int device_reserved(struct scsi_cmd *cmd)
return -EBUSY;
}
-enum {
- Opt_scsiid, Opt_scsisn, Opt_err,
-};
-
-static match_table_t tokens = {
- {Opt_scsiid, "scsi_id=%s"},
- {Opt_scsisn, "scsi_sn=%s"},
- {Opt_err, NULL},
-};
-
int tgt_device_update(int tid, uint64_t dev_id, char *params)
{
- int err = 0;
- char *p;
+ int err = TGTADM_INVALID_REQUEST;
struct target *target;
struct scsi_lu *lu;
@@ -366,26 +363,8 @@ int tgt_device_update(int tid, uint64_t dev_id,
char *params)
return TGTADM_NO_LUN;
}
- while ((p = strsep(¶ms, ",")) != NULL) {
- substring_t args[MAX_OPT_ARGS];
- int token;
- if (!*p)
- continue;
- token = match_token(p, tokens, args);
-
- switch (token) {
- case Opt_scsiid:
- match_strncpy(lu->scsi_id, &args[0],
- sizeof(lu->scsi_id) - 1);
- break;
- case Opt_scsisn:
- match_strncpy(lu->scsi_sn, &args[0],
- sizeof(lu->scsi_sn) - 1);
- break;
- default:
- err = TGTADM_INVALID_REQUEST;
- }
- }
+ if (target->dev_type_template.lu_config)
+ err = target->dev_type_template.lu_config(lu, params);
return err;
}
@@ -474,8 +453,8 @@ int target_cmd_queue(int tid, struct scsi_cmd *cmd)
cmd_post_perform(q, cmd);
dprintf("%" PRIx64 " %x %" PRIx64 " %" PRIu64 " %u %d %d\n",
- cmd->tag, cmd->scb[0], cmd->uaddr,
cmd->offset, cmd->len,
- result, cmd->async);
+ cmd->tag, cmd->scb[0], cmd->uaddr, cmd->offset,
+ cmd->len, result, cmd->async);
set_cmd_processed(cmd);
if (!cmd->async)
@@ -483,7 +462,8 @@ int target_cmd_queue(int tid, struct scsi_cmd *cmd)
} else {
set_cmd_queued(cmd);
dprintf("blocked %" PRIx64 " %x %" PRIu64 " %d\n",
- cmd->tag, cmd->scb[0], cmd->dev ?
cmd->dev->lun : UINT64_MAX,
+ cmd->tag, cmd->scb[0],
+ cmd->dev ? cmd->dev->lun : UINT64_MAX,
q->active_cmd);
list_add_tail(&cmd->qlist, &q->queue);
@@ -1148,8 +1128,8 @@ int tgt_target_show_all(char *buf, int rest)
_TAB3 "Size: %s\n"
_TAB3 "Backing store: %s\n",
lu->lun,
- lu->scsi_id,
- lu->scsi_sn,
+ lu->attributes->scsi_id,
+ lu->attributes->scsi_sn,
print_disksize(lu->size),
lu->path);
diff --git a/usr/tgtadm.c b/usr/tgtadm.c
index e55a785..3d551cc 100644
--- a/usr/tgtadm.c
+++ b/usr/tgtadm.c
@@ -103,6 +103,7 @@ struct option const long_options[] = {
{"initiator-address", required_argument, NULL, 'I'},
{"user", required_argument, NULL, 'u'},
{"password", required_argument, NULL, 'p'},
+ {"params", required_argument, NULL, 'P'},
{"bus", required_argument, NULL, 'B'},
{"target-type", required_argument, NULL, 'Y'},
@@ -110,7 +111,7 @@ struct option const long_options[] = {
{NULL, 0, NULL, 0},
};
-static char *short_options = "dhL:o:m:t:s:c:l:n:v:b:T:I:u:p:B:Y:O";
+static char *short_options = "dhL:o:m:t:s:c:l:n:v:b:T:I:u:p:P:B:Y:O";
static void usage(int status)
{
@@ -355,7 +356,7 @@ int main(int argc, char **argv)
int op, total, tid, rest, mode, t_type, ac_dir;
uint32_t cid, hostno;
uint64_t sid, lun;
- char *name, *value, *path, *targetname, *params, *address;
+ char *name, *value, *path, *targetname, *params, *address, *targetOps;
char *user, *password;
char buf[BUFSIZE + sizeof(struct tgtadm_req)];
struct tgtadm_req *req;
@@ -365,7 +366,7 @@ int main(int argc, char **argv)
t_type = TYPE_DISK;
ac_dir = ACCOUNT_TYPE_INCOMING;
rest = BUFSIZE;
- name = value = path = targetname = address = NULL;
+ name = value = path = targetname = address = targetOps = NULL;
user = password = NULL;
memset(buf, 0, sizeof(buf));
@@ -396,6 +397,9 @@ int main(int argc, char **argv)
case 'l':
lun = strtoull(optarg, NULL, 10);
break;
+ case 'P':
+ targetOps = optarg;
+ break;
case 'n':
name = optarg;
break;
@@ -570,6 +574,10 @@ int main(int argc, char **argv)
if (password)
shprintf(total, params, rest, "%spassword=%s",
rest == BUFSIZE ? "" : ",", password);
+ // Trailing ',' makes parsing params in modules easier..
+ if (targetOps)
+ shprintf(total, params, rest, "%stargetOps %s,",
+ rest == BUFSIZE ? "" : ",", targetOps);
req->len = sizeof(*req) + total;
diff --git a/usr/tgtadm.h b/usr/tgtadm.h
index fb83753..d53cb40 100644
--- a/usr/tgtadm.h
+++ b/usr/tgtadm.h
@@ -4,31 +4,7 @@
#define TGT_IPC_NAMESPACE "TGT_IPC_ABSTRACT_NAMESPACE"
#define TGT_LLD_NAME_LEN 64
-enum tgtadm_errno {
- TGTADM_SUCCESS,
- TGTADM_UNKNOWN_ERR,
- TGTADM_NOMEM,
- TGTADM_NO_DRIVER,
- TGTADM_NO_TARGET,
-
- TGTADM_NO_LUN,
- TGTADM_NO_SESSION,
- TGTADM_NO_CONNECTION,
- TGTADM_TARGET_EXIST,
- TGTADM_LUN_EXIST,
-
- TGTADM_ACL_EXIST,
- TGTADM_USER_EXIST,
- TGTADM_NO_USER,
- TGTADM_TOO_MANY_USER,
- TGTADM_INVALID_REQUEST,
-
- TGTADM_OUTACCOUNT_EXIST,
- TGTADM_TARGET_ACTIVE,
- TGTADM_LUN_ACTIVE,
- TGTADM_UNSUPPORTED_OPERATION,
- TGTADM_UNKNOWN_PARAM,
-};
+#include "tgtadm_error.h"
enum tgtadm_op {
OP_NEW,
diff --git a/usr/tgtadm_error.h b/usr/tgtadm_error.h
new file mode 100644
index 0000000..319a4ad
--- /dev/null
+++ b/usr/tgtadm_error.h
@@ -0,0 +1,30 @@
+#ifndef TGTADM_ERROR_H
+#define TGTADM_ERROR_H
+
+enum tgtadm_errno {
+ TGTADM_SUCCESS,
+ TGTADM_UNKNOWN_ERR,
+ TGTADM_NOMEM,
+ TGTADM_NO_DRIVER,
+ TGTADM_NO_TARGET,
+
+ TGTADM_NO_LUN,
+ TGTADM_NO_SESSION,
+ TGTADM_NO_CONNECTION,
+ TGTADM_TARGET_EXIST,
+ TGTADM_LUN_EXIST,
+
+ TGTADM_ACL_EXIST,
+ TGTADM_USER_EXIST,
+ TGTADM_NO_USER,
+ TGTADM_TOO_MANY_USER,
+ TGTADM_INVALID_REQUEST,
+
+ TGTADM_OUTACCOUNT_EXIST,
+ TGTADM_TARGET_ACTIVE,
+ TGTADM_LUN_ACTIVE,
+ TGTADM_UNSUPPORTED_OPERATION,
+ TGTADM_UNKNOWN_PARAM,
+};
+
+#endif
diff --git a/usr/tgtd.h b/usr/tgtd.h
index 06e0dd9..8cda864 100644
--- a/usr/tgtd.h
+++ b/usr/tgtd.h
@@ -5,6 +5,7 @@
#define SCSI_ID_LEN 24
#define SCSI_SN_LEN 8
+#define VERSION_DESCRIPTOR_LEN 8
#define VENDOR_ID "IET"
@@ -29,13 +30,27 @@ struct tgt_cmd_queue {
struct list_head queue;
};
+struct physicalAttributes {
+ char scsi_id[SCSI_ID_LEN];
+ char scsi_sn[SCSI_SN_LEN];
+
+ /* SCSI Inquiry Params */
+ char VendorIdent[9];
+ char ProductIdent[17];
+ char ProductRev[5];
+ uint16_t version_desc[VERSION_DESCRIPTOR_LEN];
+
+ char isRemovable; /* Removable media */
+ char onLine;
+ char reset; /* Power-on or reset */
+ char sense_format; /* sense data format */
+};
+
struct scsi_lu {
int fd;
uint64_t addr; /* persistent mapped address */
uint64_t size;
uint64_t lun;
- char scsi_id[SCSI_ID_LEN];
- char scsi_sn[SCSI_SN_LEN];
char *path;
/* the list of devices belonging to a target */
@@ -48,7 +63,7 @@ struct scsi_lu {
uint64_t reserve_id;
/* TODO: needs a structure for lots of device parameters */
- uint8_t d_sense;
+ struct physicalAttributes * attributes;
};
struct scsi_cmd {
@@ -121,7 +136,9 @@ struct device_type_template {
char *name;
char *pid;
- void (*device_init)(struct scsi_lu *dev);
+ int (*lu_init)(struct scsi_lu *lu);
+ int (*lu_exit)(struct scsi_lu *lu);
+ int (*lu_config)(struct scsi_lu *lu, char *arg);
struct device_type_operations ops[256];
};
--
1.5.1.3
More information about the stgt
mailing list