Skip to content

Commit

Permalink
Implement software (mode page) and hardware (config) write protection.
Browse files Browse the repository at this point in the history
  • Loading branch information
amotin committed Oct 8, 2014
1 parent a62c8c6 commit 5396f4d
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 6 deletions.
48 changes: 44 additions & 4 deletions sys/cam/ctl/ctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ static struct scsi_control_page control_page_changeable = {
/*page_length*/sizeof(struct scsi_control_page) - 2,
/*rlec*/SCP_DSENSE,
/*queue_flags*/SCP_QUEUE_ALG_MASK,
/*eca_and_aen*/0,
/*eca_and_aen*/SCP_SWP,
/*flags4*/0,
/*aen_holdoff_period*/{0, 0},
/*busy_timeout_period*/{0, 0},
Expand Down Expand Up @@ -4447,7 +4447,7 @@ ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *ctl_lun,
struct ctl_port *port;
struct scsi_vpd_id_descriptor *desc;
struct scsi_vpd_id_t10 *t10id;
const char *eui, *naa, *scsiname, *vendor;
const char *eui, *naa, *scsiname, *vendor, *value;
int lun_number, i, lun_malloced;
int devidlen, idlen1, idlen2 = 0, len;

Expand Down Expand Up @@ -4609,6 +4609,10 @@ ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *ctl_lun,
if (be_lun->flags & CTL_LUN_FLAG_PRIMARY)
lun->flags |= CTL_LUN_PRIMARY_SC;

value = ctl_get_opt(&be_lun->options, "readonly");
if (value != NULL && strcmp(value, "on") == 0)
lun->flags |= CTL_LUN_READONLY;

lun->ctl_softc = ctl_softc;
TAILQ_INIT(&lun->ooa_queue);
TAILQ_INIT(&lun->blocked_queue);
Expand Down Expand Up @@ -6219,6 +6223,14 @@ ctl_control_page_handler(struct ctl_scsiio *ctsio,
saved_cp->queue_flags |= user_cp->queue_flags & SCP_QUEUE_ALG_MASK;
set_ua = 1;
}
if ((current_cp->eca_and_aen & SCP_SWP) !=
(user_cp->eca_and_aen & SCP_SWP)) {
current_cp->eca_and_aen &= ~SCP_SWP;
current_cp->eca_and_aen |= user_cp->eca_and_aen & SCP_SWP;
saved_cp->eca_and_aen &= ~SCP_SWP;
saved_cp->eca_and_aen |= user_cp->eca_and_aen & SCP_SWP;
set_ua = 1;
}
if (set_ua != 0) {
int i;
/*
Expand Down Expand Up @@ -7045,8 +7057,13 @@ ctl_mode_sense(struct ctl_scsiio *ctsio)
header = (struct scsi_mode_hdr_6 *)ctsio->kern_data_ptr;

header->datalen = ctl_min(total_len - 1, 254);
if (control_dev == 0)
if (control_dev == 0) {
header->dev_specific = 0x10; /* DPOFUA */
if ((lun->flags & CTL_LUN_READONLY) ||
(lun->mode_pages.control_page[CTL_PAGE_CURRENT]
.eca_and_aen & SCP_SWP) != 0)
header->dev_specific |= 0x80; /* WP */
}
if (dbd)
header->block_descr_len = 0;
else
Expand All @@ -7063,8 +7080,13 @@ ctl_mode_sense(struct ctl_scsiio *ctsio)

datalen = ctl_min(total_len - 2, 65533);
scsi_ulto2b(datalen, header->datalen);
if (control_dev == 0)
if (control_dev == 0) {
header->dev_specific = 0x10; /* DPOFUA */
if ((lun->flags & CTL_LUN_READONLY) ||
(lun->mode_pages.control_page[CTL_PAGE_CURRENT]
.eca_and_aen & SCP_SWP) != 0)
header->dev_specific |= 0x80; /* WP */
}
if (dbd)
scsi_ulto2b(0, header->block_descr_len);
else
Expand Down Expand Up @@ -11313,6 +11335,24 @@ ctl_scsiio_lun_check(struct ctl_softc *ctl_softc, struct ctl_lun *lun,
}
#endif

if (entry->pattern & CTL_LUN_PAT_WRITE) {
if (lun->flags & CTL_LUN_READONLY) {
ctl_set_sense(ctsio, /*current_error*/ 1,
/*sense_key*/ SSD_KEY_DATA_PROTECT,
/*asc*/ 0x27, /*ascq*/ 0x01, SSD_ELEM_NONE);
retval = 1;
goto bailout;
}
if ((lun->mode_pages.control_page[CTL_PAGE_CURRENT]
.eca_and_aen & SCP_SWP) != 0) {
ctl_set_sense(ctsio, /*current_error*/ 1,
/*sense_key*/ SSD_KEY_DATA_PROTECT,
/*asc*/ 0x27, /*ascq*/ 0x02, SSD_ELEM_NONE);
retval = 1;
goto bailout;
}
}

/*
* Check for a reservation conflict. If this command isn't allowed
* even on reserved LUNs, and if this initiator isn't the one who
Expand Down
3 changes: 2 additions & 1 deletion sys/cam/ctl/ctl_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,8 @@ typedef enum {
CTL_LUN_OFFLINE = 0x080,
CTL_LUN_PR_RESERVED = 0x100,
CTL_LUN_PRIMARY_SC = 0x200,
CTL_LUN_SENSE_DESC = 0x400
CTL_LUN_SENSE_DESC = 0x400,
CTL_LUN_READONLY = 0x800
} ctl_lun_flags;

typedef enum {
Expand Down
5 changes: 4 additions & 1 deletion usr.sbin/ctladm/ctladm.8
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
.\" $Id: //depot/users/kenm/FreeBSD-test2/usr.sbin/ctladm/ctladm.8#3 $
.\" $FreeBSD$
.\"
.Dd September 13, 2014
.Dd October 8, 2014
.Dt CTLADM 8
.Os
.Sh NAME
Expand Down Expand Up @@ -961,6 +961,9 @@ This allows to offload copying between different iSCSI targets residing
on the same host in trusted environments.
.It Va readcache
Set to "off", disables read caching for the LUN, if supported by the backend.
.It Va readonly
Set to "on", blocks all media write operations to the LUN, reporting it
as write protected.
.It Va reordering
Set to "unrestricted", allows target to process commands with SIMPLE task
attribute in arbitrary order. Any data integrity exposures related to
Expand Down

0 comments on commit 5396f4d

Please sign in to comment.