Add basic programmable early warning error injection to the sa(4) driver.

This will help application developers simulate end of tape conditions.

To inject an error in sa0:

sysctl kern.cam.sa.0.inject_eom=1

This will return the next read or write request queued with 0 bytes
written.  Any subsequent writes or reads will go along as usual.

This will also cause the early warning position flag to get set
for the next position query.  So, 'mt status' will show the BPEW
(Beyond Programmable Early Warning) flag on the first query after
an error injection.  After that, the position flags will be as they
are in the underlying tape drive.

Also, update the sa(4) man page to describe tape parameters,
which can be set via 'mt param'.

sys/cam/scsi/scsi_sa.c:
	In saregister(), create the inject_eom sysctl variable.

	In sastart(), check to see whether inject_eom is set.  If
	so, return the read or write with 0 bytes written to
	indicate EOM.  Set the set_pews_status flag so that we
	fake PEWS status in the next position call for reads, and the
	next 3 calls for writes.  This allows the user to see the BPEW
	flag one time via 'mt status'.

	In sagetpos(), check the set_pews_status flag and fake
	PEWS status and decrement the counter if it is set.

share/man/man4/sa.4:
	Document the inject_eom sysctl variable.

	Document all of the parameters currently supported via
	'mt param'.

usr.bin/mt/mt.1:
	Point the user to the sa(4) man page for more details on
	supported parameters.

MFC after:	3 days
Sponsored by:	Spectra Logic
This commit is contained in:
Kenneth D. Merry 2017-05-05 20:00:53 +00:00
parent 1dc02549c3
commit 64409eeee7
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=317848
3 changed files with 136 additions and 6 deletions

View File

@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd February 12, 2015
.Dd May 5, 2017
.Dt SA 4
.Os
.Sh NAME
@ -242,6 +242,87 @@ These devices include the QIC family of devices.
block devices.
This has not been determined yet, and they are treated
as separate behaviors by the driver at this time.)
.Sh PARAMETERS
The
.Nm
driver supports a number of parameters.
The user can query parameters using
.Dq mt param -l
(which uses the
.Dv MTIOCPARAMGET
ioctl) and the user can set parameters using
.Dq mt param -s
(which uses the
.Dv MTIOCPARAMSET
ioctl).
See
.Xr mt 1
and
.Xr mtio 4
for more details on the interface.
.Pp
Supported parameters:
.Bl -tag -width 5n
.It sili
The default is 0.
When set to 1, it sets the Suppress Incorrect Length Indicator (SILI) bit
on tape reads.
Tape drives normally return sense data (which contains the residual) when the
application reads a block that is not the same length as the amount of data
requested.
The SILI bit supresses that notification in most cases.
See the SSC-5 spec (available at t10.org), specifically the section on the
READ(6) command, for more information.
.It eot_warn
The default is 0.
By default, the
.Nm
driver reports entering Programmable Early Warning, Early Warning and End
of Media conditions by returning a write with 0 bytes written, and
.Dv errno
set to 0.
If
.Va eot_warn
is set to 1, the
.Nm
driver will set
.Dv errno
to
.Dv ENOSPC
when it enters any of the out of space conditions.
.It protection.protection_supported
This is a read-only parameter, and is set to 1 if the tape drive supports
protection information.
.It protection.prot_method
If protection is supported, set this to the desired protection method
supported by the tape drive.
As of SSC-5r03 (available at t10.org), the protection method values are:
.Bl -tag -width 3n
.It 0
No protection.
.It 1
Reed-Solomon CRC, 4 bytes in length.
.It 2
CRC32C, 4 bytes in length.
.El
.It protection.pi_length
Length of the protection information, see above for lengths.
.It protection.lbp_w
If set to 1, enable logical block protection on writes.
The CRC must be appended to the end of the block written to the tape driver.
The tape drive will verify the CRC when it receives the block.
.It protection.lbp_r
If set to 1, enable logical block protection on reads.
The CRC will be appended to the end of the block read from the tape driver.
The application should verify the CRC when it receives the block.
.It protection.rdbp
If set to 1, enable logical block protection on the RECOVER BUFFERED DATA
command.
The
.Nm
driver does not currently use the
RECOVER BUFFERED DATA command.
.El
.Sh IOCTLS
The
.Nm
@ -262,7 +343,26 @@ Control mode device (to examine state while another program is
accessing the device, e.g.).
.El
.Sh DIAGNOSTICS
None.
The
.Nm
driver supports injecting End Of Media (EOM) notification to aid
application development and testing.
EOM is indicated to the application by returning the read or write with 0
bytes written.
In addition, when EOM is injected, the tape position status will be updated
to temporarily show Beyond of the Programmable Early Warning (BPEW) status.
To see BPEW status, use the
.Dv MTIOCEXTGET
ioctl, which is used by the
.Dq mt status
command.
To inject an EOM notification, set the
.Pp
.Va kern.cam.sa.%d.inject_eom
.Pp
sysctl variable to 1.
One EOM notification will be sent, BPEW status will be set for one position
query, and then the driver state will be reset to normal.
.Sh SEE ALSO
.Xr mt 1 ,
.Xr cam 4

View File

@ -337,6 +337,8 @@ struct sa_softc {
u_int32_t maxio;
u_int32_t cpi_maxio;
int allow_io_split;
int inject_eom;
int set_pews_status;
u_int32_t comp_algorithm;
u_int32_t saved_comp_algorithm;
u_int32_t media_blksize;
@ -2323,6 +2325,9 @@ sasysctlinit(void *context, int pending)
SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
OID_AUTO, "cpi_maxio", CTLFLAG_RD,
&softc->cpi_maxio, 0, "Maximum Controller I/O size");
SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
OID_AUTO, "inject_eom", CTLFLAG_RW,
&softc->inject_eom, 0, "Queue EOM for the next write/read");
bailout:
/*
@ -2588,8 +2593,27 @@ sastart(struct cam_periph *periph, union ccb *start_ccb)
bp = bioq_first(&softc->bio_queue);
if (bp == NULL) {
xpt_release_ccb(start_ccb);
} else if ((softc->flags & SA_FLAG_ERR_PENDING) != 0) {
} else if (((softc->flags & SA_FLAG_ERR_PENDING) != 0)
|| (softc->inject_eom != 0)) {
struct bio *done_bp;
if (softc->inject_eom != 0) {
softc->flags |= SA_FLAG_EOM_PENDING;
softc->inject_eom = 0;
/*
* If we're injecting EOM for writes, we
* need to keep PEWS set for 3 queries
* to cover 2 position requests from the
* kernel via sagetpos(), and then allow
* for one for the user to see the BPEW
* flag (e.g. via mt status). After that,
* it will be cleared.
*/
if (bp->bio_cmd == BIO_WRITE)
softc->set_pews_status = 3;
else
softc->set_pews_status = 1;
}
again:
softc->queue_count--;
bioq_remove(&softc->bio_queue, bp);
@ -4842,9 +4866,12 @@ sagetpos(struct cam_periph *periph)
else
softc->eop = 0;
if (long_pos.flags & SA_RPOS_LONG_BPEW)
if ((long_pos.flags & SA_RPOS_LONG_BPEW)
|| (softc->set_pews_status != 0)) {
softc->bpew = 1;
else
if (softc->set_pews_status > 0)
softc->set_pews_status--;
} else
softc->bpew = 0;
} else if (error == EINVAL) {
/*

View File

@ -29,7 +29,7 @@
.\" @(#)mt.1 8.1 (Berkeley) 6/6/93
.\" $FreeBSD$
.\"
.Dd May 20, 2016
.Dd May 5, 2017
.Dt MT 1
.Os
.Sh NAME
@ -284,6 +284,9 @@ One of
or
.Fl x
must be specified to indicate which operation to perform.
See
.Xr sa 4
for more detailed information on the parameters.
.Bl -tag -width 8n
.It Fl l
List parameters, values and descriptions.