On Fri, 20 Jan 2012 08:58:28 +1100 ronnie sahlberg <ronniesahlberg@xxxxxxxxx> wrote: > From c3547d370e4f7258db1ffe6c5c1cc233923d6dac Mon Sep 17 00:00:00 2001 > From: Ronnie Sahlberg <ronniesahlberg@xxxxxxxxx> > Date: Fri, 20 Jan 2012 08:48:55 +1100 > Subject: [PATCH] Implement PREVENT/ALLOW MEDIUM REMOVAL for MMC Hmm, what are you try to do for sbc? > Add a new attribute for a lun to describe the prevent state. > A device that has the Prevent bit set can not be made offline > (offline == no media in drive for MMC emulation) > > Also update Start/Stop Unit to not allow "eject" of media when > Prevent is set. > > Signed-off-by: Ronnie Sahlberg <ronniesahlberg@xxxxxxxxx> > --- > doc/tgtadm.8.xml | 47 +++++++++++++++++++++++++++++++++++++++++++++++ > usr/mmc.c | 5 ++++- > usr/sbc.c | 2 +- > usr/spc.c | 39 ++++++++++++++++++++++++++++++++------- > usr/target.c | 15 +++++++++++++-- > usr/tgtadm.c | 4 +++- > usr/tgtadm_error.h | 2 ++ > usr/tgtd.h | 5 +++++ > 8 files changed, 107 insertions(+), 12 deletions(-) > > diff --git a/doc/tgtadm.8.xml b/doc/tgtadm.8.xml > index a2dd394..6eec214 100644 > --- a/doc/tgtadm.8.xml > +++ b/doc/tgtadm.8.xml > @@ -671,6 +671,53 @@ tgtadm --lld iscsi --op delete --mode conn --tid 1 --sid 2 --cid 0 > </refsect1> > > > + > + <refsect1><title>Online/Offline Status</title> > + <para> > + Tgtd LUNs can be in online or offline status. LUNs that are Offline behave slightly different > + depending on the device type. Offline devices behave as if there is no media available and any > + operations that access media will fail with an error. > + </para> > + <para> > + Devices can not be set to Offline mode while there are "PREVENT ALLOW MEDIUM REMOVAL" > + locks on the device. > + </para> > + <refsect2><title>Show Online/Offline status</title> > + <para> > + Finding the Online/Offline status of a LUN is done through the tgtd command. If "Prevent removal" > + is "Yes" this indicates that an application holds a "prevent media removal" lock on the device. > + </para> > + <screen format="linespecific"> > +tgtadm --lld iscsi --mode target --op show > +... > + LUN: 2 > + Type: cd/dvd > + SCSI ID: IET 00010002 > + SCSI SN: beaf12 > + Size: 3432 MB, Block size: 1 > + Online: Yes > + Removable media: Yes > + Prevent removal: Yes > +... > + </screen> > + </refsect2> > + <refsect2><title>Changing a LUN to Offline</title> > + <para> > + A LUN is changed to Offline status using the tgtadm command. > + When MMC (CD/DVD) devices are set Offline these devices will behave as if there is no media > + loaded into the drive. > + </para> > + <para> > + Change a LUN to become offline. (no disk in the drive) > + </para> > + <screen format="linespecific"> > +tgtadm --tid 1 --lun 2 --op update --mode logicalunit -P Online=No > + </screen> > + > + </refsect2> > + </refsect1> > + > + > <refsect1><title>iSNS PARAMETERS</title> > <para> > iSNS configuration for a target is by using the tgtadm command. > diff --git a/usr/mmc.c b/usr/mmc.c > index 3279c3d..5545743 100644 > --- a/usr/mmc.c > +++ b/usr/mmc.c > @@ -2296,6 +2296,9 @@ static int mmc_lu_online(struct scsi_lu *lu) > > static int mmc_lu_offline(struct scsi_lu *lu) > { > + if (lu->attrs.prevent & PREVENT_REMOVAL) > + return TGTADM_PREVENT_REMOVAL; > + > lu->attrs.online = 0; > return 0; > } > @@ -2342,7 +2345,7 @@ static struct device_type_template mmc_template = { > {spc_start_stop,}, > {spc_illegal_op,}, > {spc_illegal_op,}, > - {spc_start_stop,}, /* allow medium removal */ > + {spc_prevent_allow_media_removal,}, > {spc_illegal_op,}, > > /* 0x20 */ > diff --git a/usr/sbc.c b/usr/sbc.c > index 9666801..ee4b538 100644 > --- a/usr/sbc.c > +++ b/usr/sbc.c > @@ -380,7 +380,7 @@ static struct device_type_template sbc_template = { > {spc_start_stop, NULL, PR_SPECIAL}, > {spc_illegal_op,}, > {spc_illegal_op,}, > - {spc_illegal_op,}, > + {spc_prevent_allow_media_removal,}, > {spc_illegal_op,}, > > /* 0x20 */ > diff --git a/usr/spc.c b/usr/spc.c > index eba4857..86eef1a 100644 > --- a/usr/spc.c > +++ b/usr/spc.c > @@ -309,12 +309,32 @@ sense: > > int spc_start_stop(int host_no, struct scsi_cmd *cmd) > { > + uint8_t *scb = cmd->scb; > + int start, loej; > + > scsi_set_in_resid_by_actual(cmd, 0); > > if (device_reserved(cmd)) > return SAM_STAT_RESERVATION_CONFLICT; > - else > - return SAM_STAT_GOOD; > + > + loej = scb[4] & 0x02; > + start = scb[4] & 0x01; > + > + if (loej == 1 && start == 0 > + && (cmd->dev->attrs.prevent & PREVENT_REMOVAL)) { > + if (cmd->dev->attrs.online) { > + /* online == media is present */ > + sense_data_build(cmd, ILLEGAL_REQUEST, > + ASC_MEDIUM_REMOVAL_PREVENTED); > + } else { > + /* !online == media is not present */ > + sense_data_build(cmd, NOT_READY, > + ASC_MEDIUM_REMOVAL_PREVENTED); > + } > + return SAM_STAT_CHECK_CONDITION; > + } > + > + return SAM_STAT_GOOD; > } > > int spc_test_unit(int host_no, struct scsi_cmd *cmd) > @@ -335,12 +355,14 @@ int spc_test_unit(int host_no, struct scsi_cmd *cmd) > > int spc_prevent_allow_media_removal(int host_no, struct scsi_cmd *cmd) > { > - /* TODO: implement properly */ > + uint8_t *scb = cmd->scb; > > if (device_reserved(cmd)) > return SAM_STAT_RESERVATION_CONFLICT; > - else > - return SAM_STAT_GOOD; > + > + cmd->dev->attrs.prevent = scb[4] & PREVENT_MASK; > + > + return SAM_STAT_GOOD; > } > > int spc_mode_select(int host_no, struct scsi_cmd *cmd, > @@ -1649,6 +1671,9 @@ int spc_lu_online(struct scsi_lu *lu) > > int spc_lu_offline(struct scsi_lu *lu) > { > + if (lu->attrs.prevent & PREVENT_REMOVAL) > + return TGTADM_PREVENT_REMOVAL; > + > lu->attrs.online = 0; > return 0; > } > @@ -1728,9 +1753,9 @@ int lu_config(struct scsi_lu *lu, char *params, match_fn_t *fn) > case Opt_online: > match_strncpy(buf, &args[0], sizeof(buf)); > if (atoi(buf)) > - lu->dev_type_template.lu_online(lu); > + err |= lu->dev_type_template.lu_online(lu); > else > - lu->dev_type_template.lu_offline(lu); > + err |= lu->dev_type_template.lu_offline(lu); > break; > case Opt_mode_page: > match_strncpy(buf, &args[0], sizeof(buf)); > diff --git a/usr/target.c b/usr/target.c > index dd4b358..4411a01 100644 > --- a/usr/target.c > +++ b/usr/target.c > @@ -375,10 +375,15 @@ int tgt_device_path_update(struct target *target, struct scsi_lu *lu, char *path > uint64_t size; > > if (lu->path) { > + int ret; > + > if (lu->attrs.online) > return TGTADM_INVALID_REQUEST; > > - lu->dev_type_template.lu_offline(lu); > + ret = lu->dev_type_template.lu_offline(lu); > + if (ret) > + return ret; > + > lu->bst->bs_close(lu); > free(lu->path); > lu->fd = 0; > @@ -755,7 +760,10 @@ int dtd_load_unload(int tid, uint64_t lun, int load, char *file) > > lu->size = 0; > lu->fd = 0; > - lu->dev_type_template.lu_offline(lu); > + > + err = lu->dev_type_template.lu_offline(lu); > + if (err) > + return err; > > if (load) { > lu->path = strdup(file); > @@ -1798,6 +1806,7 @@ int tgt_target_show_all(char *buf, int rest) > _TAB3 "Size: %s, Block size: %d\n" > _TAB3 "Online: %s\n" > _TAB3 "Removable media: %s\n" > + _TAB3 "Prevent removal: %s\n" > _TAB3 "Readonly: %s\n" > _TAB3 "Backing store type: %s\n" > _TAB3 "Backing store path: %s\n" > @@ -1810,6 +1819,8 @@ int tgt_target_show_all(char *buf, int rest) > 1U << lu->blk_shift, > lu->attrs.online ? "Yes" : "No", > lu->attrs.removable ? "Yes" : "No", > + lu->attrs.prevent & PREVENT_REMOVAL ? > + "Yes" : "No", > lu->attrs.readonly ? "Yes" : "No", > lu->bst ? > (lu->bst->bs_name ? : "Unknown") : > diff --git a/usr/tgtadm.c b/usr/tgtadm.c > index 7dca0f8..d0147d9 100644 > --- a/usr/tgtadm.c > +++ b/usr/tgtadm.c > @@ -77,7 +77,9 @@ static const char * tgtadm_strerror(int err) > { TGTADM_LUN_ACTIVE, "this logical unit is still active" }, > { TGTADM_UNSUPPORTED_OPERATION, > "this operation isn't supported" }, > - { TGTADM_UNKNOWN_PARAM, "unknown parameter" } > + { TGTADM_UNKNOWN_PARAM, "unknown parameter" }, > + { TGTADM_PREVENT_REMOVAL, > + "this device has Prevent Removal set" } > }; > int i; > > diff --git a/usr/tgtadm_error.h b/usr/tgtadm_error.h > index 4cd8f81..3a37a69 100644 > --- a/usr/tgtadm_error.h > +++ b/usr/tgtadm_error.h > @@ -26,6 +26,8 @@ enum tgtadm_errno { > TGTADM_LUN_ACTIVE, > TGTADM_UNSUPPORTED_OPERATION, > TGTADM_UNKNOWN_PARAM, > + > + TGTADM_PREVENT_REMOVAL, > }; > > #endif > diff --git a/usr/tgtd.h b/usr/tgtd.h > index 1805f3e..8a0e511 100644 > --- a/usr/tgtd.h > +++ b/usr/tgtd.h > @@ -51,6 +51,10 @@ struct vpd { > uint8_t data[0]; > }; > > +#define PREVENT_REMOVAL 0x01 > +#define PREVENT_REMOVAL_PERSISTENT 0x02 > +#define PREVENT_MASK 0x03 > + > struct lu_phy_attr { > char scsi_id[SCSI_ID_LEN + 1]; > char scsi_sn[SCSI_SN_LEN + 1]; > @@ -64,6 +68,7 @@ struct lu_phy_attr { > unsigned char device_type; /* Peripheral device type */ > char qualifier; /* Peripheral Qualifier */ > char removable; /* Removable media */ > + char prevent; /* Prevent/Allow removal */ > char readonly; /* Read-Only media */ > char online; /* Logical Unit online */ > char sense_format; /* Descrptor format sense data supported */ > -- > 1.7.3.1 > -- To unsubscribe from this list: send the line "unsubscribe stgt" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html