Scsi_debug adapter
driver for lk 2.6
Introduction
The scsi_debug adapter driver simulates a variable number of SCSI
disks, each sharing a common amount of RAM allocated by the driver to
act as (volatile) storage. With one SCSI disk simulated, the scsi_debug
driver is
functionally equivalent to a RAM disk. When multiple SCSI disks
are simulated, they could be viewed as multiple paths to the same
storage
device or simply separate devices. The driver can also be used to
simulate very large disks, 2 terabytes or more in size by "wrapping"
its data access within the available ram.
A small but hopefully useful set of SCSI commands is supported along
with some crude error checking. The number of simulated devices and the
shared RAM size for storage can be given as module parameters or boot
time parameters if the scsi_debug driver is built into the kernel. The
number of simulated devices (and hosts) can be varied at run time via
sysfs. Various error conditions can be optionally generated to test the
reaction of upper levels of the kernel and applications to abnormal
situations.
The original scsi_debug driver found in the lk 2.4 series was
written by Eric Youngdale. Eric used it to test the "new" error
handling introduced originally in the lk 2.2 series and extended in
the lk 2.4 series. There are also hooks through to the user space
where nasty error situations could be tested without compromising the
kernel. See Eric's site
for more information.
This page describes version 1.81 (including what features were added
since version 1.76) of the
scsi_debug
driver. See downloads
section below. For information about the scsi_debug driver found
in the lk 2.4 production series see this
page.
Parameters
Here is a list of scsi_debug specific driver parameters:
Parameter name
|
default value
|
sysfs access
|
sysfs write effect
|
new
in version
|
notes
|
add_host
|
1
|
read-write
|
immediate
|
|
can add or remove hosts at runtime
|
delay
|
1
|
read-write
|
next command
|
|
units are jiffies (configurable: 1 to 10 ms)
[1.78: delay is ignored on most non data transfer commands]
|
dev_size_mb
|
8
|
read only
|
-
|
|
units are megabytes (2**20 bytes)
|
every_nth
|
0
|
read-write
|
n commands from now
|
|
for error injection: 0 -> off
|
fake_rw
|
0
|
read-write |
next command |
1.80
|
when set does no processing when
a READ or WRITE command (any cdb size) is received.
|
max_luns
|
1
|
read-write
|
next positive add_host or scan
|
|
responds to luns: 0 ... (max_luns-1) or 1 ...
(max_luns-1) if no_lun_0 is set
|
no_lun_0
|
0
|
read-write
|
next positive add_host or scan |
1.77
|
no lun 0
but responds to INQUIRY and REPORT LUNS as per SPC-2
|
num_parts
|
0
|
read only
|
- |
|
number of partitions
|
num_tgts
|
1
|
read-write
|
next positive add_host or scan
|
|
targets per host
|
opts
|
0
|
read-write
|
usually following commands
|
|
0 -> quiet and no error injection
(mask 16 to inject aborted_command new in 1.81)
|
ptype
|
0
|
read-write |
next positive add_host or scan |
|
peripheral device type (0==disk)
|
scsi_level
|
5
|
read only
|
-
|
|
from: 0 (no compliance), 1, 2 (SCSI-2), 3
(SPC), 4 (SPC-2), 5 (SPC-3), 6 (SPC-4)
|
virtual_gb
|
0
|
read-write
|
immediate, next READ CAPACITY
|
1.79
|
When 0 then device is
dev_size_mb sized ram disk. When n > 0, "virtual" n gigabyte size
disk, wrapping on dev_size_mb actual ram. The gigabyte unit is 2**30
bytes.
|
vpd_use_hostno
|
1
|
read-write |
next positive add_host or scan |
1.80
|
the driver generates serial
numbers and SAS naa-5 addresses based on host number ("hostno"), target
id and lun. When set to 0, the generated numbers ignore "hostno".
|
The parameter name given in the above table is the module parameter
name and the sysfs file name. The boot time parameter (if the
scsi_debug
driver is built into the kernel) has "scsi_debug." prepended to it.
Hence the boot time parameter corresponding to add_host is scsi_debug.add_host
.
When the scsi_debug module is loaded, two or more parameters can be
given, separated by spaces: for example to simulate 140 disks "modprobe
scsi_debug max_luns=2 num_tgts=7 add_host=10" could be used. This
will generate 140 devices: 10 hosts, each with 7 targets, each with 2
logical units.
Sysfs parameters can be read with the cat command and written with
the echo command.
Examples:
# cd /sys/bus/pseudo/drivers/scsi_debug
# cat dev_size_mb
8
# echo 1 > add_host
The add_host parameter is the number of hosts (HBAs) to
simulate. The default is 1. For boot time and module loads the
allowable values are 0 through to a large positive number. For sysfs
writes, a
value of 0 does nothing while a positive number adds that many hosts
and
a negative number removes that number of hosts. A sysfs read of this
parameter shows the current number of hosts scsi_debug is simulating.
No more than num_tgts target ids will be used per host. Target
ids are in ascending order from 0 excluding the target id that is used
by the initiator (i.e. HBA) if any. The default setting of num_tgts
is 1. The default setting for max_luns is 1. So the number of
pseudo disks simulated at driver initialization time is (add_host
* num_tgts * max_luns). Note that if any of these
three parameters is set to zero at kernel boot time or module load time
then no devices are created. Modifying the add_host parameter
in sysfs can be used to simulate hot plugging and unplugging of
hosts. See below for adding and deleting individual scsi devices.
The delay parameter is the number of jiffies by which the
driver will delay responses. The default is 1 jiffy. Setting this
parameter to 0 (or negative) will cause the response to be sent back to
the mid level before the request function is completed. Currently the
"jiffy" is a kernel space jiffy (i.e. HZ == 1 millisecond on i386)
rather than a user space jiffy (i.e. USER_HZ == 10 milliseconds on
i386). This is now configurable in the kernel build. Both delayed and
immediate responses are
permitted however delayed responses are more realistic. For delayed
responses, a kernel timer is used. [Real adapters would generate an
interrupt when the response was ready (i.e. the command had
completed).]
For a fast ram disk set the delay parameter to 0. These SCSI
commands ignore the delay
parameter and respond immediately: INQUIRY, REPORT LUNS, REQUEST SENSE,
SYNCHRONIZE
CACHE and TEST UNIT READY.
The dev_size_mb parameter allows the user to specify the size
of
the simulated storage. The unit is megabytes and the default value
is 8 (megabytes). The maximum value depends on the capabilities of the
vmalloc() call on the target architecture. If the module fails to load
with a "cannot allocate memory" message then a "vmalloc=nn{KMG}" boot
time argument may be needed. [See the kernel source file: Documentation/kernel-parameters.txt
for more information on this.] The RAM reserved for storage is
initialized to
zeros which leads the sd (scsi disk) driver and the block layer to
believe there is no
partition table present. Partitions can be simulated with num_parts (see below). All simulated
dummy devices share the same
RAM. If a value of 0 or less is given then dev_size_mb is forced to 1 so 1 MB
of RAM is used. Very large amounts of "virtual" storage can be
simulated with the virtual_gb parameter (see below).
The every_nth parameter takes a decimal number as an
argument. When
this number is greater than zero, then incoming commands are counted
and when <n> is reached then the associated command generates
some sort of error. Currently the available errors are timeout (when "opts
& 4" is true) and RECOVERED_ERROR (when "opts & 8" is
true) . Once the command count reaches <n> then it is reset to
zero. For example setting every_nth to 3 and opts to 4
will cause every third command to be ignored (and hence a timeout). If every_nth
is not given it is defaulted to 0 and timeouts and recovered errors
will not be generated.
If every_nth is negative
then an internal command counter counts down to that value and when it
is reached, continually generates the error condition (specified in opts) on each newly received
command. The driver flags
this continual error state by setting every_nth
to -1 . The user can stop error conditions being generated on receipt
of every subsequent command by writing 0
to every_nth (or opts ).
The fake_rw parameter instructs the scsi_debug driver to
ignore
all READ and WRITE commands and return a GOOD status. This means the
data "read" when fake_rw is set is whatever was previously in
the scatter gather list. The default value is 0 (i.e. process READ and
WRITE commands). This parameter is for testing.
The max_luns parameter allows an upper limit to be placed
on
the logical unit number (lun) that the scsi_debug driver will respond
to. A value of 2 means that this driver will respond to logical unit
numbers 0 and 1. If max_luns is modified by a sysfs write then
the scsi_debug driver modifies the scsi_host::max_lun
member of all hosts that it owns. When max_luns is modified by
a
sysfs write then it will take effect the next time a host is added (see
add_host)
or when a scan is done on any existing host. The mid level scanning
code will scan for up to but not including max_scsi_luns which
is a SCSI mid level boot and module load time parameter.
The num_parts parameter writes
a partition table to the ramdisk if the parameter's value is greater
than 0. The default is 0 so in that case the ramdisk is simply all
zeros. When num_parts is
greater than zero a DOS format primary partition block is written to
logical block 0, so the number of partitions is limited to a maximum of
4. The partitions are given an id of 0x83 which is a "Linux" partition.
The available space on the ramdisk is roughly divided evenly between
partitions when 2 or more partitions are requested. The partitions are not initialized with any
file system. Even if no partitions are specified, a utility like fdisk can be used to added them
later.
The num_tgts parameter allows the number of targets per
host to be specified. It should be 0 or greater. Target id
numbers start at 0 and ascend, bypassing the target id of the initiator
(i.e. the HBA). If num_tgts is modified by a sysfs write then
the
scsi_debug driver modifies the scsi_host::max_id
member of all hosts that it owns. When num_tgts is
modified
by a sysfs write then it will take effect the next time a host is added
(see add_host) or when a scan is done on any existing host.
The no_lun_0 parameter when
set to a non zero value causes an INQUIRY response of
peripheral_qualifier==3 indicating
there is no actual lu there. As required by SPC, lun 0 will still
respond to the a REPORT LUNS command. If the REPORT LUNS has a 'select
report' code of 1 or 2, then one of the luns reported will be the
REPORT LUNS well known logical unit (lun 49409). The default value is
0. If max_luns is greater than 1, the the first lun generated by
scsi_debug will be lun 1 (since lun 0 is skipped). To facilitate
logical unit scanning SPC-3 requires that lun 0 still respond to an
INQUIRY and REPORT LUNS command. The cleaner way to do this is to
support the REPORT LUNS well known
logical unit (lun is 49,409). This well known logical unit (wlun) only
supports the INQUIRY, REPORT
LUNS, REQUEST SENSE and TEST UNIT READY SCSI commands. To make this
wlun appear as a scsi generic (sg) device something like
this is needed:
# modprobe scsi_debug no_lun_0=1
max_luns=2
# cd /sys/class/scsi_host/host0
# echo "- - 49409" > scan
#
# lsscsi -g
[0:0:0:1] disk
Linux scsi_debug
0004 /dev/sda /dev/sg0
[0:0:0:49409]wlun Linux
scsi_debug 0004
- /dev/sg1
The ptype parameter allows the
SCSI peripheral type to be set or modified. The default value is 0
which corresponds to a disk. Other useful peripheral types are 1 for
tape, 3 for processor, 5 for dvd/cd and 13 for enclosure.
The opts parameter takes a number as an argument which
is the bitwise "or" of several flags. The flags supported are:
- 1 - "noisy" flag: all calls to
entry points of driver are logged. Commands to be executed are shown in
hex.
- 2 - "medium error" flag:
simulates a SCSI MEDIUM ERROR when sector 0x1234 (that is 4660 in
decimal) is read
- 4 - ignore "nth" command causing
timeout. Active when every_nth != 0
- 8 - cause "nth" read or write
command to yield a RECOVERED_ERROR. Active when every_nth != 0
- 16 - cause "nth" read or write command to
yield a ABORTED_COMMAND (ack/nak timeout) which is a SAS transport
error. Active when every_nth != 0
The "noisy" (or debug) flag will cause all scsi_debug entry points to
be logged in
the system log (and often sent to the console depending on how kernel
informational messages are processed). With this flag commands are
listed in hex and if they yield a result other than successful then
that
is shown. The "medium error" flag will cause any read command whose
range of sectors includes sector 0x1234 (4660 in decimal) to return a
medium error indication to the mid level. The "ignore nth" flag is only
active when every_nth != 0 . When an internal command counter
reaches the value in every_nth and the "ignore nth" flag is
set,
then this command is ignored (i.e. quietly not processed). Typically
this will cause the SCSI mid level code to timeout the command which
leads to further error processing. The internal command counter is
reset
to zero whenever opts is written to, whenever every_nth
is
written to, when the every_nth value is reached and at driver
load time. The "recovered error" flag works in a similar fashion
to the "ignore nth" flag, however when the every_nth value is
reached and it is either a read or a write command then the command is
processed normally but yields a "recovered error" indication. Such an
indication is _not_ a hard error but for a real disk could indicate
deteriorating media. The "aborted command" flag injects a transport
error in a similar fashion to the way the "recovered error" flag works.
A minor point: the kernel boot time and module
load
time opts parameter is a decimal integer. However the output
sysfs value is a hexadecimal number (output as 0x9 for example) while
the input value is interpreted as hexadecimal if prefixed by "0x" and
decimal otherwise. The sysfs handling reflects that it is easier to
manipulate bit masks in hexadecimal rather than in decimal.
The scsi_level parameter is the ANSI SCSI standard level that
the simulated disk announces that it is compliant to. The INQUIRY
response which
is generated by scsi_debug contains the ANSI SCSI standard level value
(in byte 2).
The virtual_gb parameter
allows the scsi_debug driver to simulate a much larger storage device
than physical RAM available in the machine. When the virtual_gb parameter is 0 (its
default value) then the maximum storage available is that indicated by
the dev_size_mb parameter.
When the virtual_gb parameter
is greater than zero, that many gigabytes (2**30 bytes) are reported by
the READ CAPACITY command. Reading and writing of the "gigabytes" of
data wraps around within the available physical ram (which the
scsi_debug driver has allocated and is dev_size_mb
megabytes in size). When the number of virtual gigabytes is 2048 or
greater then READ CAPACITY (16) is needed to represent the size and
READ (16) and/or WRITE (16) are needed to access data at the 2048
gigabyte boundary and beyond. This boundary represents 2**32-1 blocks
(sectors) each 512 bytes long. The "wrapping" action still allows
partitions to be written with fdisk and in many cases a file system to
be initialized. Trying to store and retrieve any useful data on such a
big virtual disk would not
be wise! If such a virtual disk is to be used to test streaming
performance (e.g. with the dd
command or sg_dd from
sg3_utils) then setting the 'delay=0' parameter is recommended,
otherwise each read or write command is delayed by one jiffy (between 1
and 10 milliseconds). Setting the dev_size_mb
parameter to a prime number, larger than the default value (which is 8)
and that doesn't starve the machine for resources, seems to help in
creating ext3 file systems. This occurs since mkfs writes the file
system super block at several offsets within the partition, and the
wrap may cause the file system header to be overwritten. The virtual_gb option is designed for testing,
not practical data storage.
The vpd_use_hostno parameter
affects the way the scsi_debug driver generates its serial numbers, SAS
and naa-5 addresses. When vpd_use_hostno
is set to 1 (its default value) then the host number ("hostno"),
target_id and lun are used to generate the serial number, SAS and naa-5
addresses. The formula is "((hostno + 1) * 2000) + (target_id * 1000) +
lun)". When vpd_use_hostno
is set to 0 then the "hostno" term in the formula is set to 0. This has
the affect of making multiple simulated hosts look like they are
connected to the same drives (i.e. there are only "num_tgts * max_luns"
unique simulated devices). The kernel will still report "add_host
* num_tgts * max_luns" devices but higher level
multipath aware software may see the difference.
Supported SCSI
commands
Below is a list of supported commands. Some do nothing (e.g.
SYNCHRONIZE CACHE). Those that have interesting functionality have
notes in brackets. If the feature was introduced in a recent version
(i.e. since 1.76) then that is noted.
- ALLOW MEDIUM REMOVAL
- INQUIRY [vital product data pages: 0, 0x80, 0x83] [1.77: VPD
pages: 0x85, 0x86, 0x87, 0x88, 0x89, 0xb0]
- LOG SENSE [1.78: temperature(0xd) and informational
exceptions(0x2f)] [1.80: support log subpages]
- MODE SELECT (6), MODE SELECT (10) [1.78: changeable pages: 0xa
(control) and 0x1c (informational exceptions)]
- MODE SENSE (6), MODE_SENSE (10) [sense pages: 1 (rw error
recovery), 2 (disconnect), 3 (format), 8 (caching), 0xa (control), 0x1c
(informational exceptions), 0x3f (read all)] [1.77: subpage support
plus
SAS pages: 0x19,0 0x19,1 and 0x19,2]
- READ (6), READ (10), READ(12), READ(16)
- READ CAPACITY (10), READ CAPACITY (16) [1.79: added 16 byte
command]
- RELEASE (6), RELEASE (10)
- REPORT LUNS [1.77: shows REPORT LUNS wlun]
- REQUEST SENSE [1.79: shows MRIE=6 failure prediction, power
states]
- RESERVE (6), RESERVE (10)
- REZERO UNIT (which is REWIND for tapes)
- SEND DIAGNOSTIC
- START STOP [1.78: maintains start and stop states, when stopped
fails media access commands]
- SYNCHRONIZE CACHE
- TEST UNIT READY [1.78: in stopped state gives appropriate error]
- VERIFY (10)
- WRITE (6), WRITE (10), WRITE (12), WRITE (16)
The implementations of the above commands are sufficient for the scsi
subsystem to detect and attach devices. The fdisk, e2fsck
and mount commands also work as do the utilities found in the
sg3_utils package (see the main page). Crude error processing picks up
unsupported commands and attempts to read or write outside the
available
RAM storage area.
Modern SCSI devices use vital product page 0x83 for identification.
This driver yields both "T10 vendor identification" and "NAA"
descriptors. The former yields an ASCII string like
"Linux scsi_debug 4000"
where the "4000" is the ((host_no + 1) * 2000) + (target_id * 1000) +
lun). In this case "4000" corresponds to host_no==1, target_id==0
and lun==0. The "NAA-5" descriptor is an 8 byte binary value that looks
like this hex sequence: "51 23 45 60 00 00 0f a0" where the IEEE
company
id is 0x123456 (fake) and the vendor specific identifier in the least
significant bytes is 4000 (which is fa0 in hex). [The "4000" is derived
the same way for both descriptors.]
Read and write commands executed by the scsi_debug driver are atomic
(i.e. a write to one scsi_debug device will not interrupt (split) a
read from another scsi_debug device. So a read command will
either
yield the contents of ram before a co-incident write, or after the
co-incident write has finished.
Usage
When the driver is loaded successfully simulated disks should be
visible just like other SCSI devices:
# modprobe scsi_debug
# lsscsi
[2:0:0:0] disk
ATA WDC WD360GD-00FL 33.0 /dev/sda
[4:0:1:0] disk SEAGATE
ST336754SS 0003 /dev/sdb
[4:0:2:0] disk SEAGATE
ST336754SS 0003 /dev/sdc
[6:0:0:0] disk
Linux scsi_debug
0004 /dev/sdd
In this case there is a real SATA disk (WDC), a dual ported SAS disk
with both ports connected (Seagate) and one
scsi_debug pseudo disk. The fdisk /dev/sdd command can now be
used to partition the disk. Assuming one ext2 partition is allocated
to the whole pseudo disk (8 MB in this case) then the mkfs.ext2
/dev/sdd1 command can be used to make an ext2 file system. Now
/dev/sdd1 can be mounted
and treated like a normal file system.
Naturally when the power is turned off anything stored in /dev/sdb1
will be forgotten.
Rather than mounting the pseudo disk, the sg3_utils package (see the
main page) could be used to carry out various tests on it.
Information about the scsi_debug driver version, its current
parameters and some other data can be found in the "proc" file system.
The trailing number in the path is the host number:
# cat /proc/scsi/scsi_debug/0
scsi_debug adapter driver, version 1.80 [20060726]
num_tgts=1, shared (ram) size=8 MB, opts=0x0, every_nth=0(curr:0)
delay=1, max_luns=1, scsi_level=5
sector_size=512 bytes, cylinders=64, heads=8, sectors=32
number of aborts=0, device_reset=0, bus_resets=0, host_resets=0
Adding and removing
hosts and devices
Individual devices can be removed via sysfs and the mid-level by
writing any value into the "delete" member in the sysfs directory
corresponding to the scsi device:
# echo 1 >
/sys/class/scsi_device/1:0:0:0/device/delete
This will work for any scsi device (not just those belonging to
scsi_debug). Note that the sysfs entries corresponding to this scsi
device will disappear if the operation is successful (i.e. the last
three elements of the path shown). That scsi device can be re-added
with
the following command:
# echo "0 0 0" >
/sys/class/scsi_host/host1/scan
# lscsi
[0:0:0:0]
disk FUJITSU MAM3184MP
0105 /dev/sda
[1:0:0:0]
disk Linux
scsi_debug 0004 /dev/sdb
The three numbers in the "echo" are channel number, target number and
lun, respectively. Wildcards (hyphen: "-") can be given for any or all
of the three numbers.
# echo 3 > /sys/bus/pseudo/drivers/scsi_debug/max_luns
# echo 2 > /sys/bus/pseudo/drivers/scsi_debug/num_tgts
# echo "0 - -" > /sys/class/scsi_host/host1/scan
# lscsi
[0:0:0:0]
disk FUJITSU MAM3184MP
0105 /dev/sda
[1:0:0:0]
disk Linux
scsi_debug 0004 /dev/sdb
[1:0:0:1]
disk Linux
scsi_debug 0004 /dev/sdc
[1:0:0:2]
disk Linux
scsi_debug 0004 /dev/sdd
[1:0:1:0]
disk Linux
scsi_debug 0004 /dev/sde
[1:0:1:1]
disk Linux
scsi_debug 0004 /dev/sdf
[1:0:1:2]
disk Linux
scsi_debug 0004 /dev/sdg
The 'echo "0 - -" > scan' line above added five devices: /dev/sdc to
/dev/sdg . Note that the
"-" in the lun position (i.e. last position) still only probes lun 0
when the kernel CONFIG_SCSI_MULTI_LUN parameter is not set. If you know or suspect a
lun is present at a lun > 0 then its number must be given explicitly.
As noted above, extra hosts can be added and removed from the
scsi_debug driver as follows:
# cd /sys/bus/pseudo/drivers/scsi_debug
# echo 1 > add_host # add a new host (after the existing
hosts)
# echo -2 > add_host # remove the last two hosts (if at least
that many are present)
The scsi_debug driver does not have any limits on the number of scsi
devices it can create. By default when loaded it has one scsi device
(owned by a host). Larger numbers of devices can be introduced at load
time by specifying the add_host, num_tgts and/or max_luns parameters, the number of
scsi devices created is the product of the 3 parameters (they all
default to 1). Alternatively sysfs can be used to add (or remove) scsi
devices after the scsi_debug driver is loaded. Two strategies can be
used:
- increase the value of num_tgts
or max_luns then use a line
like
'echo "0 - -" > scan' (shown above) to a host already owned by the
scsi_debug driver.
- add more hosts with a line like 'echo 3 > add_host'. Each new
host will create (num_tgts * max_luns) new scsi devices. Of
course num_tgts or max_luns can be modified prior to
calling 'echo 3 > add_host'.
Even though the scsi_debug can create ten thousand or more devices, it
doesn't mean that the scsi mid-level, sd, sg, the block layer and
various other kernel components will handle it gracefully.
Mode pages
The supported mode pages are listed following the MODE SENSE entry in
the supported commands sections above. Prior to version 1.80, when a
mode page is read no
block descriptor is included in the response. From version
1.78 the MODE SELECT command is supported. Two mode pages can be
modified:
- control (DSENSE field is acted upon)
- informational exceptions control (MRIE and TEST fields are acted
upon by REQUEST SENSE)
The saved page is not supported, reflecting that the scsi_debug driver
has no non-volatile storage. All fields can be changed, only those
fields indicated above have side effects.
SAS personality
The scsi_debug driver has a Serial Attached SCSI (SAS) personality. For
any application that cares, it looks like a dual ported SAS disk
accessed via the primary port (relative target port 1). In one case it
masquerades as a SATA disk behind a SCSI to ATA Translation (SAT) layer
(SATL). Many of the settings are in common with Fibre Channel dual
ported disks.
The driver sets the MULTIP (multiport) bit in the INQUIRY response. The
following VPD pages are SAS or SAT specific:
- device identification page [0x83] (yields naa-5 addresses for the
lu, the accessing target port and the target device, plus some other
designators)
- SCSI ports [0x88] (shows the naa-5 addresses of both ports)
- ATA information [0x89] (simulates a SATA disk in a SAS domain,
defined in SAT)
The naa-5 addresses are meant to be world wide unique names which
represents a challenge to the scsi_debug driver. Amongst other things
Linux does not have a IEEE company id [memo: OSDL]. Even if it did,
making them truly unique in a virtual driver, especially if multiple
boxes could somehow see each other, would be difficult.
There are also several SAS specific mode pages:
- protocol specific port page (SAS): short format page [0x19,0x0]
- protocol specific port page (SAS): phy control and discover
subpage [0x19,0x1]
- protocol specific port page (SAS): shared mode subpage [0x19,0x2]
(sas2 version)
Both the VPD and mode pages can be viewed from the user space with an
application like sdparm . Below is an
example of the device identification VPD page:
# sdparm -i /dev/sda
/dev/sda: Linux
scsi_debug 0004
Device identification VPD page:
Addressed logical unit:
desig_type: T10 vendor identification,
code_set: ASCII
vendor id: Linux
vendor specific:
scsi_debug 2000
desig_type: NAA, code_set: Binary
0x53333330000007d0
Target port:
desig_type: Relative target port, code_set:
Binary
transport: Serial Attached SCSI (SAS)
Relative target port: 0x1
desig_type: NAA, code_set: Binary
transport: Serial Attached SCSI (SAS)
0x52222220000007ce
Target device that contains addressed lu:
desig_type: NAA, code_set: Binary
transport: Serial Attached SCSI (SAS)
0x52222220000007cd
desig_type: SCSI name string, code_set: UTF-8
transport: Serial Attached SCSI (SAS)
SCSI name string:
naa.52222220000007CD
Below is an example of the SCSI ports VPD page showing a dual ported
target:
# sdparm -i -p sp /dev/sda
/dev/sda: Linux
scsi_debug 0004
SCSI Ports VPD page:
Relative port=1
Target port descriptor(s):
desig_type: NAA, code_set: Binary
transport: Serial Attached SCSI (SAS)
0x52222220000007ce
Relative port=2
Target port descriptor(s):
desig_type: NAA, code_set: Binary
transport: Serial Attached SCSI (SAS)
0x52222220000007cf
Notice that the above implies that the INQUIRY was sent via port 1
(port
A) of the emulated SAS dual ported target. The protocol specific port
phy control and discover mode subpage [0x19,0x1] has target port/phy
SAS addresses that correspond to the SCSI ports VPD page:
# sdparm -t sas -p pcd -l /dev/sda
/dev/sda:
Linux
scsi_debug 0004
Direct access
device specific parameters: WP=0 DPOFUA=0
port: phy control and discover
(SAS) mode page:
PPID_1 6 [cha: n, def:
6] Port's (transport) protocol identifier
NOP 2 [cha: n,
def: 2] Number of phys
PHID 0 [cha: n,
def: 0] Phy identifier
ADT 1 [cha: n,
def: 1] Attached device type
NPLR 9 [cha: n,
def: 9] Negotiated physical link rate
ASIP 1 [cha: n,
def: 1] Attached SSP initiator port
ATIP 0 [cha: n,
def: 0] Attached STP initiator port
AMIP 0 [cha: n,
def: 0] Attached SMP initiator port
ASTP 0 [cha: n,
def: 0] Attached SSP target port
ATTP 0 [cha: n,
def: 0] Attached STP target port
AMTP 0 [cha: n,
def: 0] Attached SMP target port
SASA 0x52222220000007ce [cha: n,
def:0x52222220000007ce] SAS address
ASASA 0x5111111000000001 [cha: n,
def:0x5111111000000001] Attached SAS address
APHID 2 [cha: n, def:
2] Attached phy identifier
PMILR 8 [cha: n, def:
8] Programmed minimum link rate
HMILR 8 [cha: n, def:
8] Hardware minimum link rate
PMALR 9 [cha: n, def:
9] Programmed maximum link rate
HMALR 9 [cha: n, def:
9] Hardware maximum link rate
2_PHID 1 [cha: n, def:
1] Phy identifier
2_ADT 1 [cha: n, def:
1] Attached device type
2_NPLR 9 [cha: n, def:
9] Negotiated physical link rate
2_ASIP 1 [cha: n, def:
1] Attached SSP initiator port
2_ATIP 0 [cha: n, def:
0] Attached STP initiator port
2_AMIP 0 [cha: n, def:
0] Attached SMP initiator port
2_ASTP 0 [cha: n, def:
0] Attached SSP target port
2_ATTP 0 [cha: n, def:
0] Attached STP target port
2_AMTP 0 [cha: n, def:
0] Attached SMP target port
2_SASA
0x52222220000007cf [cha: n, def:0x52222220000007cf] SAS
address
2_ASASA
0x5111111000000001 [cha: n, def:0x5111111000000001]
Attached SAS address
2_APHID 3 [cha: n, def: 3]
Attached phy identifier
2_PMILR 8 [cha: n, def: 8]
Programmed minimum link rate
2_HMILR 8 [cha: n, def: 8]
Hardware minimum link rate
2_PMALR 9 [cha: n, def: 9]
Programmed maximum link rate
2_HMALR 9 [cha: n, def: 9]
Hardware maximum link rate
Other supported mode pages can be accessed in a similar way by the sdparm utility. Note that transport specific
mode pages need the transport identified: hence the '-t sas' option
above.
Downloads
The tarballs in the table below contain 2 files:
drivers/scsi/scsi_debug.h and drivers/scsi/scsi_debug.c :
Linux
version
|
tarball
|
version
|
Notes
|
lk 2.6.6
|
sdebug_lk266.tgz
|
1.71
|
version 1.72 features not
available (no rescan feature)
|
2.6.6+
|
sdebug173.tgz
|
1.73
|
adds num_parts and ptype (plus
rescan feature)
|
2.6.9
|
sdebug174.tgz |
1.74
|
-ve every_nth, better sense
data, better syslog output, dsense option
|
2.6.9-bk4
|
sdebug175.tgz
|
1.75
|
higmem data transfers fix, add
VERIFY(10) [post
lk 2.6.9 release]
|
2.6.13+14
|
sdebug_lk2613.tgz
|
1.75
|
no functionality change, small
3rd party changes
|
|
|
|
|
2.6.13+14
|
sdebug_lk2614rc3_sas6.tgz |
1.77
|
add some SAS SSP support (mode
and VPD pages), no_lun_0 + wlun. See below.
|
2.6.15-rc2
|
sdebug_lk2615rc2_sas8.tgz |
1.77
|
resync; ignore delay on INQUIRY,
REPORT LUNS, SYNCHRONIZE CACHE and TEST UNIT READY
|
2.6.17-rc1
|
sdebug_lk2617rc1sas_1.tgz |
1.77
|
better SAS simulation, bigger
single command transfers
|
2.6.17-rc3
|
sdebug_lk2617rc3sas_7.tgz |
1.78
|
adds LOG SENSE, MODE SELECT
(6+10); implements START STOP UNIT, REQUEST SENSE and TEST UNIT READY
|
2.6.17-rc5
|
sdebug_lk2617rc5sas_1.tgz |
1.79
|
adds virtual_gb parameter, multi
gigabyte storage wrapping in dev_size_mb ram
|
2.6.18-rc2
|
in kernel source
|
1.79
|
same functionality as previous
entry [copy: sdebug_lk2618rc2.tgz
]
|
| 2.6.18-rc2 |
sdebug_lk2618rc2b.tgz |
1.80
|
log subpage
support, vpd_use_hostno + fake_rw
|
| 2.6.18-rc4 |
sdebug_lk2618rc4b.tgz |
1.80
|
log subpage
support, vpd_use_hostno + fake_rw; plus do_create_driverfs_files() fix
|
| 2.6.18 |
in kernel source |
1.79
|
fix error reporting from
do_create_driverfs_files() |
2.6.18
2.6.19-rc1
|
sdebug_lk2618rc7c.tgz
in kernel source
|
1.80
|
add mode sense/select block
descriptor processing when pdt=0
|
2.6.21-rc3
|
in kernel source
|
1.81
|
aborted_command transport error
injection; bug fixes
|
Conclusion
Hopefully the design of the scsi_debug driver lends itself to many
extensions. If you think that you have a useful extension that others
may be interested in, please contact the author with a patch.
Back to main page
Douglas Gilbert (dgilbert at interlog dot com)
Last updated: 8th March 2007