[stgt] [PATCH] Implement Prevent/AllowMediumRemoval for MMC devices

FUJITA Tomonori fujita.tomonori at lab.ntt.co.jp
Mon Jan 23 08:48:36 CET 2012


On Fri, 20 Jan 2012 08:58:28 +1100
ronnie sahlberg <ronniesahlberg at gmail.com> wrote:

> From c3547d370e4f7258db1ffe6c5c1cc233923d6dac Mon Sep 17 00:00:00 2001
> From: Ronnie Sahlberg <ronniesahlberg at gmail.com>
> 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 at gmail.com>
> ---
>  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 at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html



More information about the stgt mailing list