1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-25 11:37:56 +00:00

Implement software (mode page) and hardware (config) write protection.

This commit is contained in:
Alexander Motin 2014-10-08 12:24:24 +00:00
parent a62c8c6a99
commit 5396f4d279
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=272748
3 changed files with 50 additions and 6 deletions

View File

@ -293,7 +293,7 @@ static struct scsi_control_page control_page_changeable = {
/*page_length*/sizeof(struct scsi_control_page) - 2, /*page_length*/sizeof(struct scsi_control_page) - 2,
/*rlec*/SCP_DSENSE, /*rlec*/SCP_DSENSE,
/*queue_flags*/SCP_QUEUE_ALG_MASK, /*queue_flags*/SCP_QUEUE_ALG_MASK,
/*eca_and_aen*/0, /*eca_and_aen*/SCP_SWP,
/*flags4*/0, /*flags4*/0,
/*aen_holdoff_period*/{0, 0}, /*aen_holdoff_period*/{0, 0},
/*busy_timeout_period*/{0, 0}, /*busy_timeout_period*/{0, 0},
@ -4447,7 +4447,7 @@ ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *ctl_lun,
struct ctl_port *port; struct ctl_port *port;
struct scsi_vpd_id_descriptor *desc; struct scsi_vpd_id_descriptor *desc;
struct scsi_vpd_id_t10 *t10id; 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 lun_number, i, lun_malloced;
int devidlen, idlen1, idlen2 = 0, len; int devidlen, idlen1, idlen2 = 0, len;
@ -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) if (be_lun->flags & CTL_LUN_FLAG_PRIMARY)
lun->flags |= CTL_LUN_PRIMARY_SC; 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; lun->ctl_softc = ctl_softc;
TAILQ_INIT(&lun->ooa_queue); TAILQ_INIT(&lun->ooa_queue);
TAILQ_INIT(&lun->blocked_queue); TAILQ_INIT(&lun->blocked_queue);
@ -6219,6 +6223,14 @@ ctl_control_page_handler(struct ctl_scsiio *ctsio,
saved_cp->queue_flags |= user_cp->queue_flags & SCP_QUEUE_ALG_MASK; saved_cp->queue_flags |= user_cp->queue_flags & SCP_QUEUE_ALG_MASK;
set_ua = 1; 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) { if (set_ua != 0) {
int i; int i;
/* /*
@ -7045,8 +7057,13 @@ ctl_mode_sense(struct ctl_scsiio *ctsio)
header = (struct scsi_mode_hdr_6 *)ctsio->kern_data_ptr; header = (struct scsi_mode_hdr_6 *)ctsio->kern_data_ptr;
header->datalen = ctl_min(total_len - 1, 254); header->datalen = ctl_min(total_len - 1, 254);
if (control_dev == 0) if (control_dev == 0) {
header->dev_specific = 0x10; /* DPOFUA */ 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) if (dbd)
header->block_descr_len = 0; header->block_descr_len = 0;
else else
@ -7063,8 +7080,13 @@ ctl_mode_sense(struct ctl_scsiio *ctsio)
datalen = ctl_min(total_len - 2, 65533); datalen = ctl_min(total_len - 2, 65533);
scsi_ulto2b(datalen, header->datalen); scsi_ulto2b(datalen, header->datalen);
if (control_dev == 0) if (control_dev == 0) {
header->dev_specific = 0x10; /* DPOFUA */ 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) if (dbd)
scsi_ulto2b(0, header->block_descr_len); scsi_ulto2b(0, header->block_descr_len);
else else
@ -11313,6 +11335,24 @@ ctl_scsiio_lun_check(struct ctl_softc *ctl_softc, struct ctl_lun *lun,
} }
#endif #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 * Check for a reservation conflict. If this command isn't allowed
* even on reserved LUNs, and if this initiator isn't the one who * even on reserved LUNs, and if this initiator isn't the one who

View File

@ -198,7 +198,8 @@ typedef enum {
CTL_LUN_OFFLINE = 0x080, CTL_LUN_OFFLINE = 0x080,
CTL_LUN_PR_RESERVED = 0x100, CTL_LUN_PR_RESERVED = 0x100,
CTL_LUN_PRIMARY_SC = 0x200, CTL_LUN_PRIMARY_SC = 0x200,
CTL_LUN_SENSE_DESC = 0x400 CTL_LUN_SENSE_DESC = 0x400,
CTL_LUN_READONLY = 0x800
} ctl_lun_flags; } ctl_lun_flags;
typedef enum { typedef enum {

View File

@ -34,7 +34,7 @@
.\" $Id: //depot/users/kenm/FreeBSD-test2/usr.sbin/ctladm/ctladm.8#3 $ .\" $Id: //depot/users/kenm/FreeBSD-test2/usr.sbin/ctladm/ctladm.8#3 $
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd September 13, 2014 .Dd October 8, 2014
.Dt CTLADM 8 .Dt CTLADM 8
.Os .Os
.Sh NAME .Sh NAME
@ -961,6 +961,9 @@ This allows to offload copying between different iSCSI targets residing
on the same host in trusted environments. on the same host in trusted environments.
.It Va readcache .It Va readcache
Set to "off", disables read caching for the LUN, if supported by the backend. 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 .It Va reordering
Set to "unrestricted", allows target to process commands with SIMPLE task Set to "unrestricted", allows target to process commands with SIMPLE task
attribute in arbitrary order. Any data integrity exposures related to attribute in arbitrary order. Any data integrity exposures related to