[stgt] read only access on 1 LUN for multiple initiators
ronnie sahlberg
ronniesahlberg at gmail.com
Tue Mar 2 22:05:34 CET 2010
On Mon, Mar 1, 2010 at 10:26 AM, Tomasz Chmielewski <tch at wpkg.org> wrote:
...
> Not sure if tgtd allows a target to be truly read only?
It does not.
>
> So that when the kernel detects a drive, it reports:
>
> sd 1:0:0:0: [sdx] Write Protect is on
Please see attached hack for discussion.
It is not tested but should/might work.
While it probably needs a bit of work, this might be one approach to
add a global read-only attribute for a LUN.
Use update an existing lun and use --params readonly=1 to activate.
Or should a readonly attribute be set initiator by initiator as part
of the ACL instead?
regards
ronnie sahlberg
-------------- next part --------------
diff --git a/usr/sbc.c b/usr/sbc.c
index a048d53..be8a0e1 100644
--- a/usr/sbc.c
+++ b/usr/sbc.c
@@ -77,11 +77,29 @@ static int sbc_rw(int host_no, struct scsi_cmd *cmd)
int ret;
unsigned char key = ILLEGAL_REQUEST;
uint16_t asc = ASC_LUN_NOT_SUPPORTED;
+ struct scsi_lu *lu = cmd->dev;
ret = device_reserved(cmd);
if (ret)
return SAM_STAT_RESERVATION_CONFLICT;
+ if (lu->attrs.readonly) {
+ switch (cmd->scb[0]) {
+ case WRITE_6:
+ case WRITE_10:
+ case WRITE_VERIFY:
+ case SYNCHRONIZE_CACHE:
+ case WRITE_12:
+ case WRITE_VERIFY_12:
+ case WRITE_16:
+ case WRITE_VERIFY_16:
+ case SYNCHRONIZE_CACHE_16:
+ key = DATA_PROTECT;
+ asc = ASC_WRITE_PROTECT;
+ goto check_condition;
+ break;
+ }
+ }
cmd->scsi_cmd_done = target_cmd_io_done;
cmd->offset = (scsi_rw_offset(cmd->scb) << BLK_SHIFT);
@@ -94,6 +112,7 @@ static int sbc_rw(int host_no, struct scsi_cmd *cmd)
return SAM_STAT_GOOD;
}
+check_condition:
cmd->offset = 0;
scsi_set_in_resid_by_actual(cmd, 0);
scsi_set_out_resid_by_actual(cmd, 0);
diff --git a/usr/spc.c b/usr/spc.c
index 14a3ee1..00d5189 100644
--- a/usr/spc.c
+++ b/usr/spc.c
@@ -455,6 +455,22 @@ int set_mode_page_changeable_mask(struct scsi_lu *lu, uint8_t pcode,
return 1;
}
+static int set_mode_page_control_readonly(struct scsi_lu *lu, uint8_t readonly)
+{
+ struct mode_pg *pg = lu->mode_pgs[0x0a];
+
+ if (pg) {
+ if (readonly) {
+ pg->mode_data[2] |= 0x08;
+ } else {
+ pg->mode_data[2] &= 0xf7;
+ }
+
+ return 0;
+ }
+ return 1;
+}
+
/**
* build_mode_page - static routine used by spc_mode_sense()
* @data: destination pointer
@@ -482,7 +498,7 @@ static int build_mode_page(uint8_t *data, struct mode_pg *pg,
p = &data[2];
len += 2;
if (*alloc_len >= pg->pcode_size) {
- if (pc == 1)
+ if (pc == 1)
mode_data = pg->mode_data + pg->pcode_size;
else
mode_data = pg->mode_data;
@@ -1578,7 +1594,7 @@ enum {
Opt_scsi_id, Opt_scsi_sn,
Opt_vendor_id, Opt_product_id,
Opt_product_rev, Opt_sense_format,
- Opt_removable, Opt_online,
+ Opt_removable, Opt_readonly, Opt_online,
Opt_mode_page,
Opt_path,
Opt_err,
@@ -1592,6 +1608,7 @@ static match_table_t tokens = {
{Opt_product_rev, "product_rev=%s"},
{Opt_sense_format, "sense_format=%s"},
{Opt_removable, "removable=%s"},
+ {Opt_readonly, "readonly=%s"},
{Opt_online, "online=%s"},
{Opt_mode_page, "mode_page=%s"},
{Opt_path, "path=%s"},
@@ -1661,6 +1678,11 @@ int lu_config(struct scsi_lu *lu, char *params, match_fn_t *fn)
match_strncpy(buf, &args[0], sizeof(buf));
attrs->removable = atoi(buf);
break;
+ case Opt_readonly:
+ match_strncpy(buf, &args[0], sizeof(buf));
+ attrs->readonly = atoi(buf);
+ set_mode_page_control_readonly(lu, attrs->readonly);
+ break;
case Opt_online:
match_strncpy(buf, &args[0], sizeof(buf));
if (atoi(buf))
@@ -1719,6 +1741,7 @@ int spc_lu_init(struct scsi_lu *lu)
lu_vpd[pg]->vpd_update(lu, lu->attrs.scsi_id);
lu->attrs.removable = 0;
+ lu->attrs.readonly = 0;
lu->attrs.sense_format = 0;
lu->dev_type_template.lu_offline(lu);
diff --git a/usr/tgtd.h b/usr/tgtd.h
index 3323a9b..1e87a64 100644
--- a/usr/tgtd.h
+++ b/usr/tgtd.h
@@ -63,6 +63,7 @@ struct lu_phy_attr {
char device_type; /* Peripheral device type */
char qualifier; /* Peripheral Qualifier */
char removable; /* Removable media */
+ char readonly; /* Read-Only media */
char online; /* Logical Unit online */
char sense_format; /* Descrptor format sense data supported */
More information about the stgt
mailing list