support different type in one target.
all of the logical units at same target must same type. this patch extend current tgt to support different type in one target.
./tgtadm --lld iscsi --op new --mode target --tid 1 -T iqn.2001-04.com.example:storage.disk2.amiens.sys1.xyz
./tgtadm --lld iscsi --op new --mode logicalunit --tid 1 --lun 0 -b /p/ref/ubuntu-7.04-beta-alternate-i386.iso --target-type cd
./tgtadm --lld iscsi --op new --mode logicalunit --tid 1 --lun 1 -b /tmp/100M --target-type disk
./tgtadm --lld iscsi --op bind --mode target --tid 1 -I ALL
./tgtadm --lld iscsi --op show --mode target
From: <hugang at soulinfo.com>
---
usr/mgmt.c | 5 ++--
usr/mmc.c | 2 +-
usr/osd.c | 2 +-
usr/sbc.c | 4 ++-
usr/scsi.c | 2 +-
usr/spc.c | 4 ++-
usr/spt.c | 2 +-
usr/target.c | 70 ++++++++++++++++++++++++++++++----------------------------
usr/target.h | 5 ----
usr/tgtd.h | 38 +++++++++++++++++++------------
10 files changed, 69 insertions(+), 65 deletions(-)
diff --git a/usr/mgmt.c b/usr/mgmt.c
index c2dfa98..7725896 100644
--- a/usr/mgmt.c
+++ b/usr/mgmt.c
@@ -77,8 +77,7 @@ static int target_mgmt(int lld_no, struc
switch (req->op) {
case OP_NEW:
- err = tgt_target_create(lld_no, req->tid, mtask->buf,
- req->target_type);
+ err = tgt_target_create(lld_no, req->tid, mtask->buf);
break;
case OP_DELETE:
err = tgt_target_destroy(req->tid);
@@ -169,7 +168,7 @@ static int device_mgmt(int lld_no, struc
switch (req->op) {
case OP_NEW:
- err = tgt_device_create(req->tid, req->lun, params);
+ err = tgt_device_create(req->tid, req->lun, req->target_type, params);
break;
case OP_DELETE:
err = tgt_device_destroy(req->tid, req->lun);
diff --git a/usr/mmc.c b/usr/mmc.c
index e9cc479..ba3a395 100644
--- a/usr/mmc.c
+++ b/usr/mmc.c
@@ -49,7 +49,7 @@ static int mmc_rw(int host_no, struct sc
int ret;
cmd->offset = (scsi_rw_offset(cmd->scb) << MMC_BLK_SHIFT);
- ret = cmd->c_target->bst->bs_cmd_submit(cmd);
+ ret = cmd->dev->bst->bs_cmd_submit(cmd);
if (ret) {
cmd->offset = 0;
cmd->len = 0;
diff --git a/usr/osd.c b/usr/osd.c
index 46bf0a0..894d4b4 100644
--- a/usr/osd.c
+++ b/usr/osd.c
@@ -142,7 +142,7 @@ static int osd_varlen_cdb(int host_no, s
}
/* return SAM_STAT_GOOD; */
- return cmd->c_target->bst->bs_cmd_submit(cmd);
+ return cmd->dev->bst->bs_cmd_submit(cmd);
}
static void device_osd_init(struct scsi_lu *lu)
diff --git a/usr/sbc.c b/usr/sbc.c
index a22d3b0..abcc8e6 100644
--- a/usr/sbc.c
+++ b/usr/sbc.c
@@ -67,7 +67,7 @@ static int sbc_rw(int host_no, struct sc
}
cmd->offset = (scsi_rw_offset(cmd->scb) << BLK_SHIFT);
- ret = cmd->c_target->bst->bs_cmd_submit(cmd);
+ ret = cmd->dev->bst->bs_cmd_submit(cmd);
if (ret) {
key = HARDWARE_ERROR;
asc = 0;
@@ -173,7 +173,7 @@ static int sbc_sync_cache(int host_no, s
goto sense;
}
- ret = cmd->c_target->bst->bs_cmd_submit(cmd);
+ ret = cmd->dev->bst->bs_cmd_submit(cmd);
switch (ret) {
case EROFS:
case EINVAL:
diff --git a/usr/scsi.c b/usr/scsi.c
index 1a6929f..4ec7a1a 100644
--- a/usr/scsi.c
+++ b/usr/scsi.c
@@ -119,5 +119,5 @@ uint64_t scsi_rw_offset(uint8_t *scb)
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);
+ return cmd->dev->dev_type_template.ops[op].cmd_perform(host_no, cmd);
}
diff --git a/usr/spc.c b/usr/spc.c
index b922a45..09b8bf1 100644
--- a/usr/spc.c
+++ b/usr/spc.c
@@ -39,8 +39,8 @@ int spc_inquiry(int host_no, struct scsi
int len, ret = SAM_STAT_CHECK_CONDITION;
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;
+ unsigned char device_type = cmd->dev->dev_type_template.type;
+ char *product_id = cmd->dev->dev_type_template.pid;
unsigned char key = ILLEGAL_REQUEST, asc = 0x24;
if (((scb[1] & 0x3) == 0x3) || (!(scb[1] & 0x3) && scb[2]))
diff --git a/usr/spt.c b/usr/spt.c
index fe2a848..3d1413f 100644
--- a/usr/spt.c
+++ b/usr/spt.c
@@ -67,7 +67,7 @@ static int spt_cmd_perform(int host_no,
struct device_type_operations *ops;
if (!cmd->dev) {
- ops = cmd->c_target->dev_type_template.ops;
+ ops = cmd->dev->dev_type_template.ops;
return ops[cmd->scb[0]].cmd_perform(host_no, cmd);
}
diff --git a/usr/target.c b/usr/target.c
index 1a9fe68..a9da5e0 100644
--- a/usr/target.c
+++ b/usr/target.c
@@ -174,7 +174,7 @@ static int tgt_device_path_update(struct
if (!path)
return TGTADM_NOMEM;
- err = target->bst->bs_open(lu, path, &dev_fd, &size);
+ err = lu->bst->bs_open(lu, path, &dev_fd, &size);
if (err) {
free(path);
return TGTADM_INVALID_REQUEST;
@@ -206,12 +206,13 @@ __device_lookup(int tid, uint64_t lun, s
return lu;
}
-int tgt_device_create(int tid, uint64_t lun, char *args)
+int tgt_device_create(int tid, uint64_t lun, uint32_t t_type, char *args)
{
char *p;
int err;
struct target *target;
struct scsi_lu *lu, *pos;
+ struct backingstore_template *bst;
dprintf("%d %" PRIu64 "\n", tid, lun);
@@ -233,9 +234,34 @@ int tgt_device_create(int tid, uint64_t
return TGTADM_INVALID_REQUEST;
p++;
- lu = zalloc(sizeof(*lu) + target->bst->bs_datasize);
+ /* FIXME */
+ if (t_type == TYPE_SPT)
+ bst = &sg_bst;
+ else
+ bst = tgt_drivers[target->lid]->default_bst;
+
+ lu = zalloc(sizeof(*lu) + bst->bs_datasize);
if (!lu)
return TGTADM_NOMEM;
+ lu->bst = bst;
+
+ switch (t_type) {
+ case TYPE_DISK:
+ lu->dev_type_template = sbc_template;
+ break;
+ case TYPE_ROM:
+ lu->dev_type_template = mmc_template;
+ break;
+ case TYPE_OSD:
+ lu->dev_type_template = osd_template;
+ break;
+ case TYPE_SPT:
+ lu->dev_type_template = spt_template;
+ break;
+ default:
+ free(lu);
+ return TGTADM_INVALID_REQUEST;
+ }
err = tgt_device_path_update(target, lu, p);
if (err) {
@@ -251,8 +277,8 @@ int tgt_device_create(int tid, uint64_t
tgt_cmd_queue_init(&lu->cmd_queue);
- if (target->dev_type_template.device_init)
- target->dev_type_template.device_init(lu);
+ if (lu->dev_type_template.device_init)
+ lu->dev_type_template.device_init(lu);
list_for_each_entry(pos, &target->device_list, device_siblings) {
if (lu->lun < pos->lun)
@@ -283,7 +309,7 @@ int tgt_device_destroy(int tid, uint64_t
free(lu->path);
list_del(&lu->device_siblings);
- target->bst->bs_close(lu);
+ lu->bst->bs_close(lu);
free(lu);
return 0;
}
@@ -508,7 +534,7 @@ static void __cmd_done(struct target *ta
cmd_hlist_remove(cmd);
- err = target->bst->bs_cmd_done(cmd);
+ err = cmd->dev->bst->bs_cmd_done(cmd);
dprintf("%d %" PRIx64 " %u %d\n", cmd->mmapped, cmd->uaddr, cmd->len, err);
@@ -1095,12 +1121,10 @@ int tgt_target_show_all(char *buf, int r
shprintf(total, buf, rest,
"Target %d: %s\n"
_TAB1 "System information:\n"
- _TAB2 "Type: %s\n"
_TAB2 "Driver: %s\n"
_TAB2 "Status: %s\n",
target->tid,
target->name,
- target->dev_type_template.name,
tgt_drivers[target->lid]->name,
target_state_name(target->target_state));
@@ -1117,11 +1141,13 @@ int tgt_target_show_all(char *buf, int r
list_for_each_entry(lu, &target->device_list, device_siblings)
shprintf(total, buf, rest,
_TAB2 "LUN: %" PRIu64 "\n"
+ _TAB3 "Dev Type: %d\n"
_TAB3 "SCSI ID: %s\n"
_TAB3 "SCSI SN: %s\n"
_TAB3 "Size: %s\n"
_TAB3 "Backing store: %s\n",
lu->lun,
+ lu->dev_type_template.type,
lu->scsi_id,
lu->scsi_sn,
print_disksize(lu->size),
@@ -1167,7 +1193,7 @@ char *tgt_targetname(int tid)
#define DEFAULT_NR_ACCOUNT 16
-int tgt_target_create(int lld, int tid, char *args, int t_type)
+int tgt_target_create(int lld, int tid, char *args)
{
struct target *target, *pos;
char *p, *q, *targetname = NULL;
@@ -1200,24 +1226,6 @@ int tgt_target_create(int lld, int tid,
if (!target)
return TGTADM_NOMEM;
- switch (t_type) {
- case TYPE_DISK:
- target->dev_type_template = sbc_template;
- break;
- case TYPE_ROM:
- target->dev_type_template = mmc_template;
- break;
- case TYPE_OSD:
- target->dev_type_template = osd_template;
- break;
- case TYPE_SPT:
- target->dev_type_template = spt_template;
- break;
- default:
- free(target);
- return TGTADM_INVALID_REQUEST;
- }
-
target->name = strdup(targetname);
if (!target->name) {
free(target);
@@ -1236,12 +1244,6 @@ int tgt_target_create(int lld, int tid,
INIT_LIST_HEAD(&target->device_list);
- /* FIXME */
- if (t_type == TYPE_SPT)
- target->bst = &sg_bst;
- else
- target->bst = tgt_drivers[lld]->default_bst;
-
target->target_state = SCSI_TARGET_RUNNING;
target->lid = lld;
diff --git a/usr/target.h b/usr/target.h
index a5f1faa..481769d 100644
--- a/usr/target.h
+++ b/usr/target.h
@@ -36,14 +36,9 @@ struct target {
struct tgt_cmd_queue cmd_queue;
- struct backingstore_template *bst;
-
struct list_head acl_list;
struct tgt_account account;
-
- /* we don't use a pointer because a lld could change this. */
- struct device_type_template dev_type_template;
};
struct it_nexus {
diff --git a/usr/tgtd.h b/usr/tgtd.h
index e0ead9b..e0bebaa 100644
--- a/usr/tgtd.h
+++ b/usr/tgtd.h
@@ -29,6 +29,23 @@ struct tgt_cmd_queue {
struct list_head queue;
};
+struct scsi_lu;
+struct scsi_cmd;
+
+struct device_type_operations {
+ int (*cmd_perform)(int host_no, struct scsi_cmd *cmd);
+};
+
+struct device_type_template {
+ unsigned char type;
+ char *name;
+ char *pid;
+
+ void (*device_init)(struct scsi_lu *dev);
+
+ struct device_type_operations ops[256];
+};
+
struct scsi_lu {
int fd;
uint64_t addr; /* persistent mapped address */
@@ -49,6 +66,10 @@ struct scsi_lu {
/* TODO: needs a structure for lots of device parameters */
uint8_t d_sense;
+
+ struct device_type_template dev_type_template;
+ struct backingstore_template *bst;
+ void *private;
};
struct scsi_cmd {
@@ -112,32 +133,19 @@ static inline int kreq_init(void) \
}
#endif
-struct device_type_operations {
- int (*cmd_perform)(int host_no, struct scsi_cmd *cmd);
-};
-
-struct device_type_template {
- unsigned char type;
- char *name;
- char *pid;
-
- void (*device_init)(struct scsi_lu *dev);
-
- struct device_type_operations ops[256];
-};
extern int kspace_send_tsk_mgmt_res(struct mgmt_req *mreq);
extern int kspace_send_cmd_res(uint64_t nid, int result, struct scsi_cmd *);
extern int ipc_init(void);
-extern int tgt_device_create(int tid, uint64_t lun, char *args);
+extern int tgt_device_create(int tid, uint64_t lun, uint32_t type, char *args);
extern int tgt_device_destroy(int tid, uint64_t lun);
extern int tgt_device_update(int tid, uint64_t dev_id, char *name);
extern int device_reserve(struct scsi_cmd *cmd);
extern int device_release(int tid, uint64_t itn_id, uint64_t lun, int force);
extern int device_reserved(struct scsi_cmd *cmd);
-extern int tgt_target_create(int lld, int tid, char *args, int t_type);
+extern int tgt_target_create(int lld, int tid, char *args);
extern int tgt_target_destroy(int tid);
extern char *tgt_targetname(int tid);
extern int tgt_target_show_all(char *buf, int rest);
|
|