List, Tomo Please find attached a small patch for SMC. It now prevents the media changer commands from loading/unloading media to a data transfer device IF that data transfer device has the media removal prevention set via PreventAllowMediumRemoval. Initiators set this when they mount a device that is removable. For example if you have a removable SBC device like the sbc jukebox example, Linux for example will set the PreventAllowMediumRemoval when you: mount -o ro,noload <device> <mountpoint> just so that no one will eject the media while the filesystem is mounted. Similarly this also happens for MMC devices, and I belive also on SSC devices, but I cant check SSC devices. (Mark, If I assume that backup applocations do use PreventAllowMediumRemoval when they have loaded a tape into the dt device?) regards ronnie sahlberg
Attachment:
0001-SMC-Do-not-allow-load-unload-on-the-data-transfer-de.patch.gz
Description: GNU Zip compressed data
From 4571387ed76a34cf34eedebd5f15d021669907fe Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg <ronniesahlberg@xxxxxxxxx> Date: Sun, 5 Feb 2012 10:27:02 +1100 Subject: [PATCH] SMC: Do not allow load/unload on the data transfer device is prevent removal; is set Update the smc move media command. Do not allow loading or unloading media to the data transfer device if an initiator has locked the media with prevent-allow-medium-removal Initiators such as linux open-iscsi sets the media prevention when mounting a SBC/MMC (and probably also SSC) device that has the RMB bit set in the standard inquiry page. Signed-off-by: Ronnie Sahlberg <ronniesahlberg@xxxxxxxxx> --- usr/smc.c | 21 +++++++++++++++++++++ usr/target.c | 31 ++++++++++++++++++++++++++++++- usr/tgtd.h | 1 + 3 files changed, 52 insertions(+), 1 deletions(-) diff --git a/usr/smc.c b/usr/smc.c index 3e77f2a..47a5179 100644 --- a/usr/smc.c +++ b/usr/smc.c @@ -5,6 +5,7 @@ * (C) 2004-2007 FUJITA Tomonori <tomof@xxxxxxx> * (C) 2005-2007 Mike Christie <michaelc@xxxxxxxxxxx> * (C) 2007 Mark Harvey <markh794@xxxxxxxxx> + * (C) 2012 Ronnie Sahlberg <ronniesahlberg@xxxxxxxxx> * * SCSI target emulation code is based on Ardis's iSCSI implementation. * http://www.ardistech.com/iscsi/ @@ -47,6 +48,11 @@ #include "smc.h" #include "media.h" +static int check_slot_removable(struct slot *s) +{ + return dtd_check_removable(s->drive_tid, s->drive_lun); +} + static int set_slot_full(struct slot *s, uint16_t src, char *path) { int err = 0; @@ -443,6 +449,21 @@ static int smc_move_medium(int host_no, struct scsi_cmd *cmd) if (invert && (s->sides == 1)) /* Use default INVALID FIELD IN CDB */ goto sense; + if (src_slot->element_type == ELEMENT_DATA_TRANSFER) { + if (check_slot_removable(src_slot)) { + key = ILLEGAL_REQUEST; + asc = ASC_MEDIUM_REMOVAL_PREVENTED; + goto sense; + } + } + if (dest_slot->element_type == ELEMENT_DATA_TRANSFER) { + if (check_slot_removable(dest_slot)) { + key = ILLEGAL_REQUEST; + asc = ASC_MEDIUM_REMOVAL_PREVENTED; + goto sense; + } + } + memcpy(&dest_slot->barcode, &src_slot->barcode, sizeof(s->barcode)); if (dest_slot->element_type == ELEMENT_DATA_TRANSFER) { char path[128]; diff --git a/usr/target.c b/usr/target.c index daa115b..42a3a09 100644 --- a/usr/target.c +++ b/usr/target.c @@ -442,7 +442,9 @@ __device_lookup(int tid, uint64_t lun, struct target **t) if (!lu) return NULL; - *t = target; + if (t) + *t = target; + return lu; } @@ -748,6 +750,30 @@ struct lu_phy_attr *lu_attr_lookup(int tid, uint64_t lun) } /** + * dtd_check_removable + * @tid: Target ID + * @lun: LUN + * + * check if a DT can have its media reoved or not + */ +int dtd_check_removable(int tid, uint64_t lun) +{ + struct scsi_lu *lu; + + lu = __device_lookup(tid, lun, NULL); + if (!lu) + return TGTADM_NO_LUN; + + if (lu_prevent_removal(lu)) + return TGTADM_PREVENT_REMOVAL; + + if (!lu->attrs.removable) + return TGTADM_INVALID_REQUEST; + + return TGTADM_SUCCESS; +} + +/** * dtd_load_unload -- Load / unload media * @tid: Target ID * @lun: LUN @@ -766,6 +792,9 @@ int dtd_load_unload(int tid, uint64_t lun, int load, char *file) if (!lu) return TGTADM_NO_LUN; + if (lu_prevent_removal(lu)) + return TGTADM_PREVENT_REMOVAL; + if (!lu->attrs.removable) return TGTADM_INVALID_REQUEST; diff --git a/usr/tgtd.h b/usr/tgtd.h index b50a887..49d0699 100644 --- a/usr/tgtd.h +++ b/usr/tgtd.h @@ -318,6 +318,7 @@ extern int device_type_register(struct device_type_template *); extern struct lu_phy_attr *lu_attr_lookup(int tid, uint64_t lun); extern int dtd_load_unload(int tid, uint64_t lun, int load, char *file); +extern int dtd_check_removable(int tid, uint64_t lun); extern int register_backingstore_template(struct backingstore_template *bst); extern struct backingstore_template *get_backingstore_template(const char *name); -- 1.7.3.1