[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