요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
.. SPDX-License-Identifier: GPL-2.0
====================
The SCSI Tape Driver
====================
This file contains brief information about the SCSI tape driver.
The driver is currently maintained by Kai Mäkisara (email
Last modified: Tue Feb 9 21:54:16 2016 by kai.makisara
Basics
======
The driver is generic, i.e., it does not contain any code tailored
to any specific tape drive. The tape parameters can be specified with
one of the following three methods:
1. Each user can specify the tape parameters he/she wants to use
directly with ioctls. This is administratively a very simple and
flexible method and applicable to single-user workstations. However,
in a multiuser environment the next user finds the tape parameters in
state the previous user left them.
2. The system manager (root) can define default values for some tape
parameters, like block size and density using the MTSETDRVBUFFER ioctl.
These parameters can be programmed to come into effect either when a
new tape is loaded into the drive or if writing begins at the
beginning of the tape. The second method is applicable if the tape
drive performs auto-detection of the tape format well (like some
QIC-drives). The result is that any tape can be read, writing can be
continued using existing format, and the default format is used if
the tape is rewritten from the beginning (or a new tape is written
for the first time). The first method is applicable if the drive
does not perform auto-detection well enough and there is a single
"sensible" mode for the device. An example is a DAT drive that is
used only in variable block mode (I don't know if this is sensible
or not :-).
The user can override the parameters defined by the system
manager. The changes persist until the defaults again come into
effect.
3. By default, up to four modes can be defined and selected using the minor
number (bits 5 and 6). The number of modes can be changed by changing
ST_NBR_MODE_BITS in st.h. Mode 0 corresponds to the defaults discussed
above. Additional modes are dormant until they are defined by the
system manager (root). When specification of a new mode is started,
the configuration of mode 0 is used to provide a starting point for
definition of the new mode.
Using the modes allows the system manager to give the users choices
over some of the buffering parameters not directly accessible to the
users (buffered and asynchronous writes). The modes also allow choices
between formats in multi-tape operations (the explicitly overridden
parameters are reset when a new tape is loaded).
If more than one mode is used, all modes should contain definitions
for the same set of parameters.
Many Unices contain internal tables that associate different modes to
supported devices. The Linux SCSI tape driver does not contain such
tables (and will not do that in future). Instead of that, a utility
program can be made that fetches the inquiry data sent by the device,
scans its database, and sets up the modes using the ioctls. Another
alternative is to make a small script that uses mt to set the defaults
tailored to the system.
The driver supports fixed and variable block size (within buffer
limits). Both the auto-rewind (minor equals device number) and
non-rewind devices (minor is 128 + device number) are implemented.
In variable block mode, the byte count in write() determines the size
of the physical block on tape. When reading, the drive reads the next
tape block and returns to the user the data if the read() byte count
is at least the block size. Otherwise, error ENOMEM is returned.
In fixed block mode, the data transfer between the drive and the
driver is in multiples of the block size. The write() byte count must
be a multiple of the block size. This is not required when reading but
may be advisable for portability.
Support is provided for changing the tape partition and partitioning
of the tape with one or two partitions. By default support for
partitioned tape is disabled for each driver and it can be enabled
with the ioctl MTSETDRVBUFFER.
By default the driver writes one filemark when the device is closed after
writing and the last operation has been a write. Two filemarks can be
optionally written. In both cases end of data is signified by
returning zero bytes for two consecutive reads.
Writing filemarks without the immediate bit set in the SCSI command block acts
as a synchronization point, i.e., all remaining data form the drive buffers is
written to tape before the command returns. This makes sure that write errors
are caught at that point, but this takes time. In some applications, several
consecutive files must be written fast. The MTWEOFI operation can be used to
write the filemarks without flushing the drive buffer. Writing filemark at
close() is always flushing the drive buffers. However, if the previous
operation is MTWEOFI, close() does not write a filemark. This can be used if
the program wants to close/open the tape device between files and wants to
skip waiting.
If rewind, offline, bsf, or seek is done and previous tape operation was
write, a filemark is written before moving tape.
The compile options are defined in the file linux/drivers/scsi/st_options.h.
4. If the open option O_NONBLOCK is used, open succeeds even if the
drive is not ready. If O_NONBLOCK is not used, the driver waits for
the drive to become ready. If this does not happen in ST_BLOCK_SECONDS
seconds, open fails with the errno value EIO. With O_NONBLOCK the
device can be opened for writing even if there is a write protected
tape in the drive (commands trying to write something return error if
attempted).
Minor Numbers
=============
The tape driver currently supports up to 2^17 drives if 4 modes for
each drive are used.
The minor numbers consist of the following bit fields::
dev_upper non-rew mode dev-lower
20 - 8 7 6 5 4 0
The non-rewind bit is always bit 7 (the uppermost bit in the lowermost
byte). The bits defining the mode are below the non-rewind bit. The
remaining bits define the tape device number. This numbering is
backward compatible with the numbering used when the minor number was
only 8 bits wide.
Sysfs Support
=============
The driver creates the directory /sys/class/scsi_tape and populates it with
directories corresponding to the existing tape devices. There are autorewind
and non-rewind entries for each mode. The names are stxy and nstxy, where x
is the tape number and y a character corresponding to the mode (none, l, m,
a). For example, the directories for the first tape device are (assuming four
modes): st0 nst0 st0l nst0l st0m nst0m st0a nst0a.
Each directory contains the entries: default_blksize default_compression
default_density defined dev device driver. The file 'defined' contains 1
if the mode is defined and zero if not defined. The files 'default_*' contain
the defaults set by the user. The value -1 means the default is not set. The
file 'dev' contains the device numbers corresponding to this device. The links
'device' and 'driver' point to the SCSI device and driver entries.
Each directory also contains the entry 'options' which shows the currently
enabled driver and mode options. The value in the file is a bit mask where the
bit definitions are the same as those used with MTSETDRVBUFFER in setting the
options.
Each directory contains the entry 'position_lost_in_reset'. If this value is
one, reading and writing to the device is blocked after device reset. Most
devices rewind the tape after reset and the writes/read don't access the
tape position the user expects.
A link named 'tape' is made from the SCSI device directory to the class
directory corresponding to the mode 0 auto-rewind device (e.g., st0).
Sysfs and Statistics for Tape Devices
=====================================
The st driver maintains statistics for tape drives inside the sysfs filesystem.
The following method can be used to locate the statistics that are
available (assuming that sysfs is mounted at /sys):
1. Use opendir(3) on the directory /sys/class/scsi_tape
2. Use readdir(3) to read the directory contents
3. Use regcomp(3)/regexec(3) to match directory entries to the extended
regular expression "^st[0-9]+$"
4. Access the statistics from the /sys/class/scsi_tape/<match>/stats
directory (where <match> is a directory entry from /sys/class/scsi_tape
that matched the extended regular expression)
The reason for using this approach is that all the character devices
pointing to the same tape drive use the same statistics. That means
that st0 would have the same statistics as nst0.
The directory contains the following statistics files:
1. in_flight
- The number of I/Os currently outstanding to this device.
2. io_ns
- The amount of time spent waiting (in nanoseconds) for all I/O
to complete (including read and write). This includes tape movement
commands such as seeking between file or set marks and implicit tape
movement such as when rewind on close tape devices are used.
3. other_cnt
- The number of I/Os issued to the tape drive other than read or
write commands. The time taken to complete these commands uses the
following calculation io_ms-read_ms-write_ms.
4. read_byte_cnt
- The number of bytes read from the tape drive.
5. read_cnt
- The number of read requests issued to the tape drive.
6. read_ns
- The amount of time (in nanoseconds) spent waiting for read
requests to complete.
7. write_byte_cnt
- The number of bytes written to the tape drive.
8. write_cnt
- The number of write requests issued to the tape drive.
9. write_ns
- The amount of time (in nanoseconds) spent waiting for write
requests to complete.
10. resid_cnt
- The number of times during a read or write we found
the residual amount to be non-zero. This should mean that a program
is issuing a read larger thean the block size on tape. For write
not all data made it to tape.
.. Note::
The in_flight value is incremented when an I/O starts the I/O
itself is not added to the statistics until it completes.
The total of read_cnt, write_cnt, and other_cnt may not total to the same
value as iodone_cnt at the device level. The tape statistics only count
I/O issued via the st module.
When read the statistics may not be temporally consistent while I/O is in
progress. The individual values are read and written to atomically however
when reading them back via sysfs they may be in the process of being
updated when starting an I/O or when it is completed.
The value shown in in_flight is incremented before any statstics are
updated and decremented when an I/O completes after updating statistics.
The value of in_flight is 0 when there are no I/Os outstanding that are
issued by the st driver. Tape statistics do not take into account any
I/O performed via the sg device.
BSD and Sys V Semantics
=======================
The user can choose between these two behaviours of the tape driver by
defining the value of the symbol ST_SYSV. The semantics differ when a
file being read is closed. The BSD semantics leaves the tape where it
currently is whereas the SYS V semantics moves the tape past the next
filemark unless the filemark has just been crossed.
The default is BSD semantics.
Buffering
=========
The driver tries to do transfers directly to/from user space. If this
is not possible, a driver buffer allocated at run-time is used. If
direct i/o is not possible for the whole transfer, the driver buffer
is used (i.e., bounce buffers for individual pages are not
used). Direct i/o can be impossible because of several reasons, e.g.:
- one or more pages are at addresses not reachable by the HBA
- the number of pages in the transfer exceeds the number of
scatter/gather segments permitted by the HBA
- one or more pages can't be locked into memory (should not happen in
any reasonable situation)
The size of the driver buffers is always at least one tape block. In fixed
block mode, the minimum buffer size is defined (in 1024 byte units) by
ST_FIXED_BUFFER_BLOCKS. With small block size this allows buffering of
several blocks and using one SCSI read or write to transfer all of the
blocks. Buffering of data across write calls in fixed block mode is
allowed if ST_BUFFER_WRITES is non-zero and direct i/o is not used.
Buffer allocation uses chunks of memory having sizes 2^n * (page
size). Because of this the actual buffer size may be larger than the
minimum allowable buffer size.
NOTE that if direct i/o is used, the small writes are not buffered. This may
cause a surprise when moving from 2.4. There small writes (e.g., tar without
-b option) may have had good throughput but this is not true any more with
2.6. Direct i/o can be turned off to solve this problem but a better solution
is to use bigger write() byte counts (e.g., tar -b 64).
Asynchronous writing. Writing the buffer contents to the tape is
started and the write call returns immediately. The status is checked
at the next tape operation. Asynchronous writes are not done with
direct i/o and not in fixed block mode.
Buffered writes and asynchronous writes may in some rare cases cause
problems in multivolume operations if there is not enough space on the
tape after the early-warning mark to flush the driver buffer.
Read ahead for fixed block mode (ST_READ_AHEAD). Filling the buffer is
attempted even if the user does not want to get all of the data at
this read command. Should be disabled for those drives that don't like
a filemark to truncate a read request or that don't like backspacing.
Scatter/gather buffers (buffers that consist of chunks non-contiguous
in the physical memory) are used if contiguous buffers can't be
allocated. To support all SCSI adapters (including those not
supporting scatter/gather), buffer allocation is using the following
three kinds of chunks:
1. The initial segment that is used for all SCSI adapters including
those not supporting scatter/gather. The size of this buffer will be
(PAGE_SIZE << ST_FIRST_ORDER) bytes if the system can give a chunk of
this size (and it is not larger than the buffer size specified by
ST_BUFFER_BLOCKS). If this size is not available, the driver halves
the size and tries again until the size of one page. The default
settings in st_options.h make the driver to try to allocate all of the
buffer as one chunk.
2. The scatter/gather segments to fill the specified buffer size are
allocated so that as many segments as possible are used but the number
of segments does not exceed ST_FIRST_SG.
3. The remaining segments between ST_MAX_SG (or the module parameter
max_sg_segs) and the number of segments used in phases 1 and 2
are used to extend the buffer at run-time if this is necessary. The
number of scatter/gather segments allowed for the SCSI adapter is not
exceeded if it is smaller than the maximum number of scatter/gather
segments specified. If the maximum number allowed for the SCSI adapter
is smaller than the number of segments used in phases 1 and 2,
extending the buffer will always fail.
EOM Behaviour When Writing
==========================
When the end of medium early warning is encountered, the current write
is finished and the number of bytes is returned. The next write
returns -1 and errno is set to ENOSPC. To enable writing a trailer,
the next write is allowed to proceed and, if successful, the number of
bytes is returned. After this, -1 and the number of bytes are
alternately returned until the physical end of medium (or some other
error) is encountered.
Module Parameters
=================
The buffer size, write threshold, and the maximum number of allocated buffers
are configurable when the driver is loaded as a module. The keywords are:
========================== ===========================================
buffer_kbs=xxx the buffer size for fixed block mode is set
to xxx kilobytes
write_threshold_kbs=xxx the write threshold in kilobytes set to xxx
max_sg_segs=xxx the maximum number of scatter/gather
segments
try_direct_io=x try direct transfer between user buffer and
tape drive if this is non-zero
========================== ===========================================
Note that if the buffer size is changed but the write threshold is not
set, the write threshold is set to the new buffer size - 2 kB.
Boot Time Configuration
=======================
If the driver is compiled into the kernel, the same parameters can be
also set using, e.g., the LILO command line. The preferred syntax is
to use the same keyword used when loading as module but prepended
with 'st.'. For instance, to set the maximum number of scatter/gather
segments, the parameter 'st.max_sg_segs=xx' should be used (xx is the
number of scatter/gather segments).
For compatibility, the old syntax from early 2.5 and 2.4 kernel
versions is supported. The same keywords can be used as when loading
the driver as module. If several parameters are set, the keyword-value
pairs are separated with a comma (no spaces allowed). A colon can be
used instead of the equal mark. The definition is prepended by the
string st=. Here is an example::
st=buffer_kbs:64,write_threshold_kbs:60
The following syntax used by the old kernel versions is also supported::
st=aa[,bb[,dd]]
where:
- aa is the buffer size for fixed block mode in 1024 byte units
- bb is the write threshold in 1024 byte units
- dd is the maximum number of scatter/gather segments
IOCTLs
======
The tape is positioned and the drive parameters are set with ioctls
defined in mtio.h The tape control program 'mt' uses these ioctls. Try
to find an mt that supports all of the Linux SCSI tape ioctls and
opens the device for writing if the tape contents will be modified
(look for a package mt-st* from the Linux ftp sites; the GNU mt does
not open for writing for, e.g., erase).
The supported ioctls are:
The following use the structure mtop:
MTFSF
Space forward over count filemarks. Tape positioned after filemark.
MTFSFM
As above but tape positioned before filemark.
MTBSF
Space backward over count filemarks. Tape positioned before
filemark.
MTBSFM
As above but ape positioned after filemark.
MTFSR
Space forward over count records.
MTBSR
Space backward over count records.
MTFSS
Space forward over count setmarks.
MTBSS
Space backward over count setmarks.
MTWEOF
Write count filemarks.
MTWEOFI
Write count filemarks with immediate bit set (i.e., does not
wait until data is on tape)
MTWSM
Write count setmarks.
MTREW
Rewind tape.
MTOFFL
Set device off line (often rewind plus eject).
MTNOP
Do nothing except flush the buffers.
MTRETEN
Re-tension tape.
MTEOM
Space to end of recorded data.
MTERASE
Erase tape. If the argument is zero, the short erase command
is used. The long erase command is used with all other values
of the argument.
MTSEEK
Seek to tape block count. Uses Tandberg-compatible seek (QFA)
for SCSI-1 drives and SCSI-2 seek for SCSI-2 drives. The file and
block numbers in the status are not valid after a seek.
MTSETBLK
Set the drive block size. Setting to zero sets the drive into
variable block mode (if applicable).
MTSETDENSITY
Sets the drive density code to arg. See drive
documentation for available codes.
MTLOCK and MTUNLOCK
Explicitly lock/unlock the tape drive door.
MTLOAD and MTUNLOAD
Explicitly load and unload the tape. If the
command argument x is between MT_ST_HPLOADER_OFFSET + 1 and
MT_ST_HPLOADER_OFFSET + 6, the number x is used sent to the
drive with the command and it selects the tape slot to use of
HP C1553A changer.
MTCOMPRESSION
Sets compressing or uncompressing drive mode using the
SCSI mode page 15. Note that some drives other methods for
control of compression. Some drives (like the Exabytes) use
density codes for compression control. Some drives use another
mode page but this page has not been implemented in the
driver. Some drives without compression capability will accept
any compression mode without error.
MTSETPART
Moves the tape to the partition given by the argument at the
next tape operation. The block at which the tape is positioned
is the block where the tape was previously positioned in the
new active partition unless the next tape operation is
MTSEEK. In this case the tape is moved directly to the block
specified by MTSEEK. MTSETPART is inactive unless
MT_ST_CAN_PARTITIONS set.
MTMKPART
Formats the tape with one partition (argument zero) or two
partitions (argument non-zero). If the argument is positive,
it specifies the size of partition 1 in megabytes. For DDS
drives and several early drives this is the physically first
partition of the tape. If the argument is negative, its absolute
value specifies the size of partition 0 in megabytes. This is
the physically first partition of many later drives, like the
LTO drives from LTO-5 upwards. The drive has to support partitions
with size specified by the initiator. Inactive unless
MT_ST_CAN_PARTITIONS set.
MTSETDRVBUFFER
Is used for several purposes. The command is obtained from count
with mask MT_SET_OPTIONS, the low order bits are used as argument.
This command is only allowed for the superuser (root). The
subcommands are:
* 0
The drive buffer option is set to the argument. Zero means
no buffering.
* MT_ST_BOOLEANS
Sets the buffering options. The bits are the new states
(enabled/disabled) the following options (in the
parenthesis is specified whether the option is global or
can be specified differently for each mode):
MT_ST_BUFFER_WRITES
write buffering (mode)
MT_ST_ASYNC_WRITES
asynchronous writes (mode)
MT_ST_READ_AHEAD
read ahead (mode)
MT_ST_TWO_FM
writing of two filemarks (global)
MT_ST_FAST_EOM
using the SCSI spacing to EOD (global)
MT_ST_AUTO_LOCK
automatic locking of the drive door (global)
MT_ST_DEF_WRITES
the defaults are meant only for writes (mode)
MT_ST_CAN_BSR
backspacing over more than one records can
be used for repositioning the tape (global)
MT_ST_NO_BLKLIMS
the driver does not ask the block limits
from the drive (block size can be changed only to
variable) (global)
MT_ST_CAN_PARTITIONS
enables support for partitioned
tapes (global)
MT_ST_SCSI2LOGICAL
the logical block number is used in
the MTSEEK and MTIOCPOS for SCSI-2 drives instead of
the device dependent address. It is recommended to set
this flag unless there are tapes using the device
dependent (from the old times) (global)
MT_ST_SYSV
sets the SYSV semantics (mode)
MT_ST_NOWAIT
enables immediate mode (i.e., don't wait for
the command to finish) for some commands (e.g., rewind)
MT_ST_NOWAIT_EOF
enables immediate filemark mode (i.e. when
writing a filemark, don't wait for it to complete). Please
see the BASICS note about MTWEOFI with respect to the
possible dangers of writing immediate filemarks.
MT_ST_SILI
enables setting the SILI bit in SCSI commands when
reading in variable block mode to enhance performance when
reading blocks shorter than the byte count; set this only
if you are sure that the drive supports SILI and the HBA
correctly returns transfer residuals
MT_ST_DEBUGGING
debugging (global; debugging must be
compiled into the driver)
* MT_ST_SETBOOLEANS, MT_ST_CLEARBOOLEANS
Sets or clears the option bits.
* MT_ST_WRITE_THRESHOLD
Sets the write threshold for this device to kilobytes
specified by the lowest bits.
* MT_ST_DEF_BLKSIZE
Defines the default block size set automatically. Value
0xffffff means that the default is not used any more.
* MT_ST_DEF_DENSITY, MT_ST_DEF_DRVBUFFER
Used to set or clear the density (8 bits), and drive buffer
state (3 bits). If the value is MT_ST_CLEAR_DEFAULT
(0xfffff) the default will not be used any more. Otherwise
the lowermost bits of the value contain the new value of
the parameter.
* MT_ST_DEF_COMPRESSION
The compression default will not be used if the value of
the lowermost byte is 0xff. Otherwise the lowermost bit
contains the new default. If the bits 8-15 are set to a
non-zero number, and this number is not 0xff, the number is
used as the compression algorithm. The value
MT_ST_CLEAR_DEFAULT can be used to clear the compression
default.
* MT_ST_SET_TIMEOUT
Set the normal timeout in seconds for this device. The
default is 900 seconds (15 minutes). The timeout should be
long enough for the retries done by the device while
reading/writing.
* MT_ST_SET_LONG_TIMEOUT
Set the long timeout that is used for operations that are
known to take a long time. The default is 14000 seconds
(3.9 hours). For erase this value is further multiplied by
eight.
* MT_ST_SET_CLN
Set the cleaning request interpretation parameters using
the lowest 24 bits of the argument. The driver can set the
generic status bit GMT_CLN if a cleaning request bit pattern
is found from the extended sense data. Many drives set one or
more bits in the extended sense data when the drive needs
cleaning. The bits are device-dependent. The driver is
given the number of the sense data byte (the lowest eight
bits of the argument; must be >= 18 (values 1 - 17
reserved) and <= the maximum requested sense data sixe),
a mask to select the relevant bits (the bits 9-16), and the
bit pattern (bits 17-23). If the bit pattern is zero, one
or more bits under the mask indicate cleaning request. If
the pattern is non-zero, the pattern must match the masked
sense data byte.
(The cleaning bit is set if the additional sense code and
qualifier 00h 17h are seen regardless of the setting of
MT_ST_SET_CLN.)
The following ioctl uses the structure mtpos:
MTIOCPOS
Reads the current position from the drive. Uses
Tandberg-compatible QFA for SCSI-1 drives and the SCSI-2
command for the SCSI-2 drives.
The following ioctl uses the structure mtget to return the status:
MTIOCGET
Returns some status information.
The file number and block number within file are returned. The
block is -1 when it can't be determined (e.g., after MTBSF).
The drive type is either MTISSCSI1 or MTISSCSI2.
The number of recovered errors since the previous status call
is stored in the lower word of the field mt_erreg.
The current block size and the density code are stored in the field
mt_dsreg (shifts for the subfields are MT_ST_BLKSIZE_SHIFT and
MT_ST_DENSITY_SHIFT).
The GMT_xxx status bits reflect the drive status. GMT_DR_OPEN
is set if there is no tape in the drive. GMT_EOD means either
end of recorded data or end of tape. GMT_EOT means end of tape.
Miscellaneous Compile Options
=============================
The recovered write errors are considered fatal if ST_RECOVERED_WRITE_FATAL
is defined.
The maximum number of tape devices is determined by the define
ST_MAX_TAPES. If more tapes are detected at driver initialization, the
maximum is adjusted accordingly.
Immediate return from tape positioning SCSI commands can be enabled by
defining ST_NOWAIT. If this is defined, the user should take care that
the next tape operation is not started before the previous one has
finished. The drives and SCSI adapters should handle this condition
gracefully, but some drive/adapter combinations are known to hang the
SCSI bus in this case.
The MTEOM command is by default implemented as spacing over 32767
filemarks. With this method the file number in the status is
correct. The user can request using direct spacing to EOD by setting
ST_FAST_EOM 1 (or using the MT_ST_OPTIONS ioctl). In this case the file
number will be invalid.
When using read ahead or buffered writes the position within the file
may not be correct after the file is closed (correct position may
require backspacing over more than one record). The correct position
within file can be obtained if ST_IN_FILE_POS is defined at compile
time or the MT_ST_CAN_BSR bit is set for the drive with an ioctl.
(The driver always backs over a filemark crossed by read ahead if the
user does not request data that far.)
Debugging Hints
===============
Debugging code is now compiled in by default but debugging is turned off
with the kernel module parameter debug_flag defaulting to 0. Debugging
can still be switched on and off with an ioctl. To enable debug at
module load time add debug_flag=1 to the module load options, the
debugging output is not voluminous. Debugging can also be enabled
and disabled by writing a '0' (disable) or '1' (enable) to the sysfs
file /sys/bus/scsi/drivers/st/debug_flag.
If the tape seems to hang, I would be very interested to hear where
the driver is waiting. With the command 'ps -l' you can see the state
of the process using the tape. If the state is D, the process is
waiting for something. The field WCHAN tells where the driver is
waiting. If you have the current System.map in the correct place (in
/boot for the procps I use) or have updated /etc/psdatabase (for kmem
ps), ps writes the function name in the WCHAN field. If not, you have
to look up the function from System.map.
Note also that the timeouts are very long compared to most other
drivers. This means that the Linux driver may appear hung although the
real reason is that the tape firmware has got confused.
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
문서 범위와 관리 정보
1-13이 문서는 GPL-2.0으로 배포되는 SCSI tape driver의 간략한 안내서다. 문서 제목은 'The SCSI Tape Driver'이며, 관리자는 Kai Mäkisara(`[email protected]`)다. 마지막 수정 기록은 2016년 2월 9일 21:54:16이다.
.. SPDX-License-Identifier: GPL-2.0
====================
The SCSI Tape Driver
====================
This file contains brief information about the SCSI tape driver.
The driver is currently maintained by Kai Mäkisara (email
[email protected])
Last modified: Tue Feb 9 21:54:16 2016 by kai.makisara
범용 드라이버와 세 가지 설정 방법
14-67`st`는 특정 tape drive에 맞춘 코드를 포함하지 않는 범용 driver다. Tape parameter는 세 방법으로 정한다. 첫째, 각 사용자가 ioctl로 원하는 값을 직접 설정할 수 있다. 단일 사용자 workstation에서는 단순하고 유연하지만, 다중 사용자 환경에서는 다음 사용자가 이전 사용자가 남긴 설정을 그대로 보게 된다.
둘째, system manager(root)가 `MTSETDRVBUFFER` ioctl로 block size와 density 같은 기본값을 정의할 수 있다. 기본값은 새 tape를 넣을 때 또는 tape 처음에서 쓰기를 시작할 때 적용되도록 설정할 수 있다. 후자는 QIC drive처럼 format 자동 감지가 잘 되는 경우 유용하다. 기존 tape는 감지한 format으로 읽거나 이어 쓰고, tape를 처음부터 다시 쓰거나 새 tape를 처음 쓸 때만 기본 format을 사용한다. 자동 감지가 불충분하고 장치에 사실상 하나의 합리적인 mode만 있다면 새 tape를 넣을 때 기본값을 적용하는 방식이 맞다. 문서는 variable block mode만 쓰는 DAT drive를 예로 든다. 사용자는 manager가 정한 값을 덮어쓸 수 있으며, 변경은 기본값이 다시 적용될 때까지 유지된다.
셋째, 기본적으로 minor number의 bit 5와 6으로 최대 네 mode를 정의하고 선택할 수 있다. Mode 수는 `st.h`의 `ST_NBR_MODE_BITS`로 바꾼다. Mode 0은 앞에서 설명한 기본값이고 추가 mode는 root가 정의하기 전까지 비활성이다. 새 mode 정의를 시작할 때 mode 0 구성을 출발점으로 복사한다. Mode를 이용하면 사용자가 직접 바꿀 수 없는 buffered write와 asynchronous write 같은 buffering parameter를 관리자가 선택지로 제공할 수 있고, 여러 tape를 다루는 작업에서 format 선택도 제공할 수 있다. 새 tape가 들어오면 명시적으로 덮어쓴 parameter는 초기화된다. 둘 이상의 mode를 사용한다면 모든 mode에서 같은 parameter 집합을 정의해야 한다.
설정 주체와 값이 다시 적용되는 시점을 구분한다.
Basics
======
The driver is generic, i.e., it does not contain any code tailored
to any specific tape drive. The tape parameters can be specified with
one of the following three methods:
1. Each user can specify the tape parameters he/she wants to use
directly with ioctls. This is administratively a very simple and
flexible method and applicable to single-user workstations. However,
in a multiuser environment the next user finds the tape parameters in
state the previous user left them.
2. The system manager (root) can define default values for some tape
parameters, like block size and density using the MTSETDRVBUFFER ioctl.
These parameters can be programmed to come into effect either when a
new tape is loaded into the drive or if writing begins at the
beginning of the tape. The second method is applicable if the tape
drive performs auto-detection of the tape format well (like some
QIC-drives). The result is that any tape can be read, writing can be
continued using existing format, and the default format is used if
the tape is rewritten from the beginning (or a new tape is written
for the first time). The first method is applicable if the drive
does not perform auto-detection well enough and there is a single
"sensible" mode for the device. An example is a DAT drive that is
used only in variable block mode (I don't know if this is sensible
or not :-).
The user can override the parameters defined by the system
manager. The changes persist until the defaults again come into
effect.
3. By default, up to four modes can be defined and selected using the minor
number (bits 5 and 6). The number of modes can be changed by changing
ST_NBR_MODE_BITS in st.h. Mode 0 corresponds to the defaults discussed
above. Additional modes are dormant until they are defined by the
system manager (root). When specification of a new mode is started,
the configuration of mode 0 is used to provide a starting point for
definition of the new mode.
Using the modes allows the system manager to give the users choices
over some of the buffering parameters not directly accessible to the
users (buffered and asynchronous writes). The modes also allow choices
between formats in multi-tape operations (the explicitly overridden
parameters are reset when a new tape is loaded).
If more than one mode is used, all modes should contain definitions
for the same set of parameters.
Many Unices contain internal tables that associate different modes to
supported devices. The Linux SCSI tape driver does not contain such
tables (and will not do that in future). Instead of that, a utility
program can be made that fetches the inquiry data sent by the device,
scans its database, and sets up the modes using the ioctls. Another
Mode 배치, block mode, partition과 filemark
68-119일부 Unix는 지원 장치와 mode를 연결하는 내부 table을 갖지만 Linux SCSI tape driver에는 그런 table이 없고 앞으로도 넣지 않는다. 대신 inquiry data를 읽어 database와 대조한 뒤 ioctl로 mode를 구성하는 utility를 만들거나, `mt`로 시스템별 기본값을 설정하는 작은 script를 사용할 수 있다.
Driver는 buffer 한도 안에서 fixed block size와 variable block size를 모두 지원한다. Auto-rewind 장치는 minor가 장치 번호와 같고, non-rewind 장치는 `128 + device number`다. Variable block mode에서는 `write()`의 byte count가 tape의 물리 block 크기를 정한다. 읽을 때 drive는 다음 tape block을 읽고, `read()` byte count가 block size 이상이면 data를 반환한다. 더 작으면 `ENOMEM`을 반환한다. Fixed block mode에서는 drive와 driver 사이 전송량이 block size의 배수이고 `write()` byte count도 반드시 배수여야 한다. 읽기에서는 필수는 아니지만 portability를 위해 배수 사용이 권장된다.
Tape partition 변경과 1개 또는 2개 partition으로의 format을 지원한다. 각 drive에서 partition 지원은 기본적으로 꺼져 있으며 `MTSETDRVBUFFER`로 켠다. 쓰기 뒤 마지막 작업이 write인 상태로 장치를 닫으면 기본적으로 filemark 하나를 쓰며, 선택에 따라 두 개를 쓸 수 있다. 어느 경우든 연속 두 번의 read가 0 byte를 반환하면 end of data다.
SCSI command block의 immediate bit 없이 filemark를 쓰면 동기화 지점이 되어 drive buffer의 남은 data가 tape에 기록된 뒤 command가 끝난다. 이때 write error를 포착할 수 있지만 시간이 걸린다. 여러 file을 빠르게 연속 기록해야 하면 `MTWEOFI`로 buffer flush를 기다리지 않고 filemark를 쓸 수 있다. `close()`가 쓰는 filemark는 항상 drive buffer를 flush하지만, 직전 작업이 `MTWEOFI`이면 `close()`는 filemark를 추가하지 않는다. 따라서 program이 file 사이에 장치를 닫았다 다시 열면서 대기를 피할 수 있다. Rewind, offline, `bsf`, seek 전에 이전 tape 작업이 write였다면 이동 전에 filemark를 쓴다. Compile option은 `linux/drivers/scsi/st_options.h`에 정의된다.
`O_NONBLOCK`으로 열면 drive가 준비되지 않아도 `open()`이 성공한다. 이 option이 없으면 driver는 최대 `ST_BLOCK_SECONDS` 동안 준비를 기다리고, 끝내 준비되지 않으면 `EIO`로 실패한다. `O_NONBLOCK`을 사용하면 write-protected tape가 들어 있어도 쓰기용으로 열 수 있지만 실제 write command는 오류를 반환한다.
Immediate filemark와 일반 close가 drive buffer를 다루는 차이다.
alternative is to make a small script that uses mt to set the defaults
tailored to the system.
The driver supports fixed and variable block size (within buffer
limits). Both the auto-rewind (minor equals device number) and
non-rewind devices (minor is 128 + device number) are implemented.
In variable block mode, the byte count in write() determines the size
of the physical block on tape. When reading, the drive reads the next
tape block and returns to the user the data if the read() byte count
is at least the block size. Otherwise, error ENOMEM is returned.
In fixed block mode, the data transfer between the drive and the
driver is in multiples of the block size. The write() byte count must
be a multiple of the block size. This is not required when reading but
may be advisable for portability.
Support is provided for changing the tape partition and partitioning
of the tape with one or two partitions. By default support for
partitioned tape is disabled for each driver and it can be enabled
with the ioctl MTSETDRVBUFFER.
By default the driver writes one filemark when the device is closed after
writing and the last operation has been a write. Two filemarks can be
optionally written. In both cases end of data is signified by
returning zero bytes for two consecutive reads.
Writing filemarks without the immediate bit set in the SCSI command block acts
as a synchronization point, i.e., all remaining data form the drive buffers is
written to tape before the command returns. This makes sure that write errors
are caught at that point, but this takes time. In some applications, several
consecutive files must be written fast. The MTWEOFI operation can be used to
write the filemarks without flushing the drive buffer. Writing filemark at
close() is always flushing the drive buffers. However, if the previous
operation is MTWEOFI, close() does not write a filemark. This can be used if
the program wants to close/open the tape device between files and wants to
skip waiting.
If rewind, offline, bsf, or seek is done and previous tape operation was
write, a filemark is written before moving tape.
The compile options are defined in the file linux/drivers/scsi/st_options.h.
4. If the open option O_NONBLOCK is used, open succeeds even if the
drive is not ready. If O_NONBLOCK is not used, the driver waits for
the drive to become ready. If this does not happen in ST_BLOCK_SECONDS
seconds, open fails with the errno value EIO. With O_NONBLOCK the
device can be opened for writing even if there is a write protected
tape in the drive (commands trying to write something return error if
attempted).
Minor number bit 배치
120-137각 drive에 네 mode를 사용할 때 driver는 최대 `2^17`개 drive를 지원한다. Non-rewind flag는 항상 bit 7, 즉 하위 byte의 최상위 bit다. Mode bit는 그 아래 bit 6과 5에 놓이고, 나머지 bit가 tape device number를 이룬다. 이 배치는 minor number가 8 bit였던 시절의 번호와 하위 byte 수준에서 호환된다.
원문의 ASCII bit-field를 같은 의미의 구조화 표로 옮겼다.
Minor Numbers
=============
The tape driver currently supports up to 2^17 drives if 4 modes for
each drive are used.
The minor numbers consist of the following bit fields::
dev_upper non-rew mode dev-lower
20 - 8 7 6 5 4 0
The non-rewind bit is always bit 7 (the uppermost bit in the lowermost
byte). The bits defining the mode are below the non-rewind bit. The
remaining bits define the tape device number. This numbering is
backward compatible with the numbering used when the minor number was
only 8 bits wide.
Sysfs device·mode attribute
138-168Driver는 `/sys/class/scsi_tape`를 만들고 존재하는 tape device마다 directory를 둔다. 각 mode마다 auto-rewind와 non-rewind entry가 있다. 이름은 `stxy`와 `nstxy`이며 x는 tape 번호, y는 mode를 나타내는 문자다. 네 mode를 가정하면 첫 장치는 `st0`, `nst0`, `st0l`, `nst0l`, `st0m`, `nst0m`, `st0a`, `nst0a`로 나타난다.
각 directory에는 `default_blksize`, `default_compression`, `default_density`, `defined`, `dev`, `device`, `driver`가 있다. `defined`는 mode가 정의되었으면 1, 아니면 0이다. `default_*`에는 사용자가 정한 기본값이 들어가며 -1은 기본값이 없음을 뜻한다. `dev`는 해당 entry의 device number를 담고, `device`와 `driver` link는 각각 SCSI device와 driver entry를 가리킨다.
`options`에는 현재 활성화된 driver·mode option이 bit mask로 표시되며 bit 정의는 `MTSETDRVBUFFER`에서 option을 설정할 때와 같다. `position_lost_in_reset`이 1이면 device reset 뒤 read와 write를 차단한다. 대부분의 device가 reset 뒤 tape를 rewind해 사용자가 기대한 위치가 아니게 되기 때문이다. SCSI device directory의 `tape` link는 mode 0 auto-rewind class directory, 예를 들어 `st0`을 가리킨다.
Mode별 directory에서 확인하는 설정과 연결 정보다.
Sysfs Support
=============
The driver creates the directory /sys/class/scsi_tape and populates it with
directories corresponding to the existing tape devices. There are autorewind
and non-rewind entries for each mode. The names are stxy and nstxy, where x
is the tape number and y a character corresponding to the mode (none, l, m,
a). For example, the directories for the first tape device are (assuming four
modes): st0 nst0 st0l nst0l st0m nst0m st0a nst0a.
Each directory contains the entries: default_blksize default_compression
default_density defined dev device driver. The file 'defined' contains 1
if the mode is defined and zero if not defined. The files 'default_*' contain
the defaults set by the user. The value -1 means the default is not set. The
file 'dev' contains the device numbers corresponding to this device. The links
'device' and 'driver' point to the SCSI device and driver entries.
Each directory also contains the entry 'options' which shows the currently
enabled driver and mode options. The value in the file is a bit mask where the
bit definitions are the same as those used with MTSETDRVBUFFER in setting the
options.
Each directory contains the entry 'position_lost_in_reset'. If this value is
one, reading and writing to the device is blocked after device reset. Most
devices rewind the tape after reset and the writes/read don't access the
tape position the user expects.
A link named 'tape' is made from the SCSI device directory to the class
directory corresponding to the mode 0 auto-rewind device (e.g., st0).
Tape device 통계의 위치와 의미
169-240`st` driver는 tape drive 통계를 sysfs에 유지한다. `/sys`에 sysfs가 mount되었다고 가정하면 `/sys/class/scsi_tape`를 `opendir(3)`으로 열고 `readdir(3)`으로 entry를 읽는다. `regcomp(3)`과 `regexec(3)`으로 확장 정규식 `^st[0-9]+$`에 맞는 directory를 찾은 뒤 `/sys/class/scsi_tape/<match>/stats`에 접근한다. 같은 tape drive를 가리키는 모든 character device가 통계를 공유하므로 `st0`과 `nst0`의 값은 같다.
`in_flight`는 아직 끝나지 않은 I/O 수다. `io_ns`는 read·write와 file/set mark 사이 seek, close 시 rewind 같은 명시적·암시적 tape 이동을 포함해 모든 I/O 완료를 기다린 nanosecond 합계다. `other_cnt`는 read·write 이외 command 수이며, 이 command의 시간은 `io_ns - read_ns - write_ns`로 계산한다. `read_byte_cnt`와 `write_byte_cnt`는 읽고 쓴 byte 수, `read_cnt`와 `write_cnt`는 요청 수, `read_ns`와 `write_ns`는 각 요청 완료를 기다린 nanosecond 합계다.
`resid_cnt`는 read 또는 write에서 residual amount가 0이 아니었던 횟수다. Read에서는 program이 tape block size보다 큰 요청을 보냈음을 뜻하고, write에서는 모든 data가 tape에 도달하지 않았음을 뜻한다. `in_flight`는 I/O 시작 시 먼저 증가하지만 그 I/O 자체의 나머지 통계는 완료될 때 반영된다.
`read_cnt + write_cnt + other_cnt`는 device level의 `iodone_cnt`와 같지 않을 수 있다. Tape 통계는 `st` module을 통해 발행된 I/O만 세며 `sg` device를 통한 I/O는 포함하지 않는다. I/O 진행 중 통계를 읽으면 여러 값의 시점이 서로 다를 수 있다. 각 값의 read·write는 atomic이지만 sysfs로 연속해서 읽는 동안 I/O가 시작되거나 완료될 수 있기 때문이다. `in_flight`는 다른 통계를 갱신하기 전에 증가하고, 완료 시 통계를 갱신한 뒤 감소한다. 따라서 값이 0이면 `st` driver가 발행해 대기 중인 I/O가 없다는 뜻이다.
`stats` directory가 제공하는 counter와 시간 값이다.
Sysfs and Statistics for Tape Devices
=====================================
The st driver maintains statistics for tape drives inside the sysfs filesystem.
The following method can be used to locate the statistics that are
available (assuming that sysfs is mounted at /sys):
1. Use opendir(3) on the directory /sys/class/scsi_tape
2. Use readdir(3) to read the directory contents
3. Use regcomp(3)/regexec(3) to match directory entries to the extended
regular expression "^st[0-9]+$"
4. Access the statistics from the /sys/class/scsi_tape/<match>/stats
directory (where <match> is a directory entry from /sys/class/scsi_tape
that matched the extended regular expression)
The reason for using this approach is that all the character devices
pointing to the same tape drive use the same statistics. That means
that st0 would have the same statistics as nst0.
The directory contains the following statistics files:
1. in_flight
- The number of I/Os currently outstanding to this device.
2. io_ns
- The amount of time spent waiting (in nanoseconds) for all I/O
to complete (including read and write). This includes tape movement
commands such as seeking between file or set marks and implicit tape
movement such as when rewind on close tape devices are used.
3. other_cnt
- The number of I/Os issued to the tape drive other than read or
write commands. The time taken to complete these commands uses the
following calculation io_ms-read_ms-write_ms.
4. read_byte_cnt
- The number of bytes read from the tape drive.
5. read_cnt
- The number of read requests issued to the tape drive.
6. read_ns
- The amount of time (in nanoseconds) spent waiting for read
requests to complete.
7. write_byte_cnt
- The number of bytes written to the tape drive.
8. write_cnt
- The number of write requests issued to the tape drive.
9. write_ns
- The amount of time (in nanoseconds) spent waiting for write
requests to complete.
10. resid_cnt
- The number of times during a read or write we found
the residual amount to be non-zero. This should mean that a program
is issuing a read larger thean the block size on tape. For write
not all data made it to tape.
.. Note::
The in_flight value is incremented when an I/O starts the I/O
itself is not added to the statistics until it completes.
The total of read_cnt, write_cnt, and other_cnt may not total to the same
value as iodone_cnt at the device level. The tape statistics only count
I/O issued via the st module.
When read the statistics may not be temporally consistent while I/O is in
progress. The individual values are read and written to atomically however
when reading them back via sysfs they may be in the process of being
updated when starting an I/O or when it is completed.
The value shown in in_flight is incremented before any statstics are
updated and decremented when an I/O completes after updating statistics.
The value of in_flight is 0 when there are no I/Os outstanding that are
issued by the st driver. Tape statistics do not take into account any
I/O performed via the sg device.
BSD와 System V filemark semantics
241-252사용자는 `ST_SYSV` symbol 값으로 tape driver의 두 동작 방식 중 하나를 선택한다. 차이는 읽던 file을 닫을 때 나타난다. BSD semantics는 tape를 현재 위치에 그대로 두고, System V semantics는 방금 filemark를 넘은 경우가 아니라면 다음 filemark 뒤로 tape를 이동한다. 기본값은 BSD semantics다.
읽던 file을 닫을 때 두 semantics가 달라지는 지점이다.
BSD and Sys V Semantics
=======================
The user can choose between these two behaviours of the tape driver by
defining the value of the symbol ST_SYSV. The semantics differ when a
file being read is closed. The BSD semantics leaves the tape where it
currently is whereas the SYS V semantics moves the tape past the next
filemark unless the filemark has just been crossed.
The default is BSD semantics.
Direct I/O, driver buffer와 scatter/gather
253-324Driver는 가능한 경우 user space와 tape drive 사이를 직접 전송한다. 전체 전송에 direct I/O를 쓸 수 없으면 runtime에 할당한 driver buffer를 사용하며 page별 bounce buffer는 사용하지 않는다. HBA가 접근할 수 없는 주소의 page가 있거나, 전송 page 수가 HBA의 scatter/gather segment 한도를 넘거나, page를 memory에 lock할 수 없을 때 direct I/O가 불가능할 수 있다. 마지막 경우는 정상적인 환경에서는 일어나지 않아야 한다.
Driver buffer는 항상 tape block 하나 이상이다. Fixed block mode의 최소 크기는 1024 byte 단위의 `ST_FIXED_BUFFER_BLOCKS`가 정한다. 작은 block size에서는 여러 block을 buffer해 한 번의 SCSI read 또는 write로 전송할 수 있다. `ST_BUFFER_WRITES`가 0이 아니고 direct I/O를 사용하지 않으면 fixed block mode에서 여러 `write()` 호출 사이에 data를 buffer할 수 있다. Buffer는 `2^n * PAGE_SIZE` 크기 chunk로 할당되므로 실제 크기가 최소 요구 크기보다 클 수 있다.
Direct I/O에서는 작은 write를 buffer하지 않는다. Linux 2.4에서 `tar`를 `-b` 없이 사용했을 때는 작은 write도 좋은 처리량을 냈을 수 있지만 2.6에서는 그렇지 않다. Direct I/O를 끌 수도 있으나 `tar -b 64`처럼 더 큰 `write()` byte count를 사용하는 편이 낫다. Asynchronous write는 buffer 내용을 tape에 쓰기 시작한 뒤 write call을 즉시 반환하고 다음 tape 작업에서 status를 확인한다. Direct I/O 또는 fixed block mode에서는 asynchronous write를 하지 않는다. Buffered·asynchronous write는 early-warning mark 뒤에 driver buffer를 비울 공간이 부족한 드문 경우 multi-volume 작업에 문제를 일으킬 수 있다.
Fixed block mode의 read ahead는 `ST_READ_AHEAD`가 제어한다. 현재 read가 buffer 전체를 요구하지 않아도 buffer 채우기를 시도한다. Filemark가 read request를 자르는 동작이나 backspace를 싫어하는 drive에서는 꺼야 한다.
물리적으로 연속된 buffer를 할당할 수 없으면 여러 비연속 chunk로 된 scatter/gather buffer를 쓴다. 첫 segment는 scatter/gather를 지원하지 않는 adapter까지 모두 사용한다. 가능하면 크기는 `PAGE_SIZE << ST_FIRST_ORDER`이며 `ST_BUFFER_BLOCKS`가 정한 전체 buffer보다 클 수 없다. 이 크기를 얻지 못하면 한 page가 될 때까지 반으로 줄여 재시도한다. 기본 `st_options.h` 설정은 buffer 전체를 한 chunk로 할당하려 한다. 둘째 단계에서는 전체 지정 크기를 채우되 segment 수가 `ST_FIRST_SG`를 넘지 않도록 가능한 많은 segment를 할당한다. 셋째 단계에서는 1·2단계에서 사용한 수와 `ST_MAX_SG` 또는 module parameter `max_sg_segs` 사이의 남은 segment를 runtime 확장에 쓴다. SCSI adapter 자체 한도가 더 작으면 그 한도를 넘지 않으며, adapter 한도가 이미 1·2단계 segment 수보다 작으면 buffer 확장은 항상 실패한다.
한 전송에 적용되는 direct I/O와 driver buffer 결정 흐름이다.
Buffering
=========
The driver tries to do transfers directly to/from user space. If this
is not possible, a driver buffer allocated at run-time is used. If
direct i/o is not possible for the whole transfer, the driver buffer
is used (i.e., bounce buffers for individual pages are not
used). Direct i/o can be impossible because of several reasons, e.g.:
- one or more pages are at addresses not reachable by the HBA
- the number of pages in the transfer exceeds the number of
scatter/gather segments permitted by the HBA
- one or more pages can't be locked into memory (should not happen in
any reasonable situation)
The size of the driver buffers is always at least one tape block. In fixed
block mode, the minimum buffer size is defined (in 1024 byte units) by
ST_FIXED_BUFFER_BLOCKS. With small block size this allows buffering of
several blocks and using one SCSI read or write to transfer all of the
blocks. Buffering of data across write calls in fixed block mode is
allowed if ST_BUFFER_WRITES is non-zero and direct i/o is not used.
Buffer allocation uses chunks of memory having sizes 2^n * (page
size). Because of this the actual buffer size may be larger than the
minimum allowable buffer size.
NOTE that if direct i/o is used, the small writes are not buffered. This may
cause a surprise when moving from 2.4. There small writes (e.g., tar without
-b option) may have had good throughput but this is not true any more with
2.6. Direct i/o can be turned off to solve this problem but a better solution
is to use bigger write() byte counts (e.g., tar -b 64).
Asynchronous writing. Writing the buffer contents to the tape is
started and the write call returns immediately. The status is checked
at the next tape operation. Asynchronous writes are not done with
direct i/o and not in fixed block mode.
Buffered writes and asynchronous writes may in some rare cases cause
problems in multivolume operations if there is not enough space on the
tape after the early-warning mark to flush the driver buffer.
Read ahead for fixed block mode (ST_READ_AHEAD). Filling the buffer is
attempted even if the user does not want to get all of the data at
this read command. Should be disabled for those drives that don't like
a filemark to truncate a read request or that don't like backspacing.
Scatter/gather buffers (buffers that consist of chunks non-contiguous
in the physical memory) are used if contiguous buffers can't be
allocated. To support all SCSI adapters (including those not
supporting scatter/gather), buffer allocation is using the following
three kinds of chunks:
1. The initial segment that is used for all SCSI adapters including
those not supporting scatter/gather. The size of this buffer will be
(PAGE_SIZE << ST_FIRST_ORDER) bytes if the system can give a chunk of
this size (and it is not larger than the buffer size specified by
ST_BUFFER_BLOCKS). If this size is not available, the driver halves
the size and tries again until the size of one page. The default
settings in st_options.h make the driver to try to allocate all of the
buffer as one chunk.
2. The scatter/gather segments to fill the specified buffer size are
allocated so that as many segments as possible are used but the number
of segments does not exceed ST_FIRST_SG.
3. The remaining segments between ST_MAX_SG (or the module parameter
max_sg_segs) and the number of segments used in phases 1 and 2
are used to extend the buffer at run-time if this is necessary. The
number of scatter/gather segments allowed for the SCSI adapter is not
exceeded if it is smaller than the maximum number of scatter/gather
segments specified. If the maximum number allowed for the SCSI adapter
is smaller than the number of segments used in phases 1 and 2,
extending the buffer will always fail.
쓰기 중 EOM early warning 처리
325-335Medium 끝의 early warning을 만나면 현재 write를 끝내고 기록된 byte 수를 반환한다. 다음 write는 -1을 반환하고 `errno`를 `ENOSPC`로 설정한다. Trailer를 쓸 수 있도록 그 다음 write는 다시 진행을 허용하며 성공하면 byte 수를 반환한다. 이후 물리적인 medium 끝이나 다른 오류를 만날 때까지 -1과 byte 수 반환이 번갈아 나타난다.
Early warning 뒤 trailer 기록 기회를 제공하는 반환 패턴이다.
EOM Behaviour When Writing
==========================
When the end of medium early warning is encountered, the current write
is finished and the number of bytes is returned. The next write
returns -1 and errno is set to ENOSPC. To enable writing a trailer,
the next write is allowed to proceed and, if successful, the number of
bytes is returned. After this, -1 and the number of bytes are
alternately returned until the physical end of medium (or some other
error) is encountered.
Module load parameter
336-355Driver를 module로 load할 때 buffer size, write threshold, 최대 scatter/gather segment 수와 direct I/O 시도 여부를 설정할 수 있다. `buffer_kbs=xxx`는 fixed block mode buffer를 xxx KB로, `write_threshold_kbs=xxx`는 write threshold를 xxx KB로 정한다. `max_sg_segs=xxx`는 최대 scatter/gather segment 수를 정하고, `try_direct_io=x`가 0이 아니면 user buffer와 tape drive 사이 direct transfer를 시도한다. Buffer size만 바꾸고 write threshold를 지정하지 않으면 threshold는 새 buffer size에서 2 KB를 뺀 값이 된다.
원문의 parameter 표를 구조화해 옮겼다.
Module Parameters
=================
The buffer size, write threshold, and the maximum number of allocated buffers
are configurable when the driver is loaded as a module. The keywords are:
========================== ===========================================
buffer_kbs=xxx the buffer size for fixed block mode is set
to xxx kilobytes
write_threshold_kbs=xxx the write threshold in kilobytes set to xxx
max_sg_segs=xxx the maximum number of scatter/gather
segments
try_direct_io=x try direct transfer between user buffer and
tape drive if this is non-zero
========================== ===========================================
Note that if the buffer size is changed but the write threshold is not
set, the write threshold is set to the new buffer size - 2 kB.
Kernel 내장 driver의 boot-time 설정
356-385Driver를 kernel에 내장했다면 module parameter와 같은 값을 LILO 같은 boot command line에서 설정할 수 있다. 권장 문법은 module keyword 앞에 `st.`를 붙이는 것이다. 예를 들어 최대 scatter/gather segment 수는 `st.max_sg_segs=xx`로 지정한다.
초기 2.5와 2.4 kernel 호환을 위해 예전 문법도 지원한다. Module load 때와 같은 keyword를 사용하고 여러 `keyword=value` 쌍은 공백 없이 comma로 구분한다. Equal sign 대신 colon도 가능하며 전체 앞에 `st=`를 붙인다. 예시는 `st=buffer_kbs:64,write_threshold_kbs:60`이다.
더 오래된 kernel 문법 `st=aa[,bb[,dd]]`도 지원한다. `aa`는 fixed block mode buffer size, `bb`는 write threshold이며 둘 다 1024 byte 단위다. `dd`는 최대 scatter/gather segment 수다.
동일한 설정을 표현하는 세 세대의 형식이다.
Boot Time Configuration
=======================
If the driver is compiled into the kernel, the same parameters can be
also set using, e.g., the LILO command line. The preferred syntax is
to use the same keyword used when loading as module but prepended
with 'st.'. For instance, to set the maximum number of scatter/gather
segments, the parameter 'st.max_sg_segs=xx' should be used (xx is the
number of scatter/gather segments).
For compatibility, the old syntax from early 2.5 and 2.4 kernel
versions is supported. The same keywords can be used as when loading
the driver as module. If several parameters are set, the keyword-value
pairs are separated with a comma (no spaces allowed). A colon can be
used instead of the equal mark. The definition is prepended by the
string st=. Here is an example::
st=buffer_kbs:64,write_threshold_kbs:60
The following syntax used by the old kernel versions is also supported::
st=aa[,bb[,dd]]
where:
- aa is the buffer size for fixed block mode in 1024 byte units
- bb is the write threshold in 1024 byte units
- dd is the maximum number of scatter/gather segments
mtop 기반 위치·media control ioctl
386-482Tape 위치와 drive parameter는 `mtio.h`의 ioctl로 제어하며 tape control program `mt`가 이를 사용한다. Linux SCSI tape ioctl을 모두 지원하고 tape 내용을 바꿀 때 장치를 write mode로 여는 `mt`가 필요하다. Linux FTP site의 `mt-st*` package를 찾을 수 있으며, GNU `mt`는 예를 들어 erase 때 write mode로 열지 않는다.
`mtop` 구조체를 쓰는 위치 이동 command는 다음과 같다. `MTFSF`는 count filemark만큼 앞으로 이동해 filemark 뒤에 놓고 `MTFSFM`은 같은 이동 뒤 filemark 앞에 놓는다. `MTBSF`는 뒤로 이동해 filemark 앞에, `MTBSFM`은 뒤로 이동해 filemark 뒤에 놓는다. `MTFSR`·`MTBSR`은 record 단위 전진·후진, `MTFSS`·`MTBSS`는 setmark 단위 전진·후진이다.
`MTWEOF`는 count filemark를 쓰고 `MTWEOFI`는 immediate bit를 설정해 data가 tape에 도달할 때까지 기다리지 않는다. `MTWSM`은 setmark를 쓴다. `MTREW`는 rewind, `MTOFFL`은 보통 rewind와 eject를 포함한 offline 전환, `MTNOP`은 buffer flush 이외에는 아무 작업도 하지 않는다. `MTRETEN`은 re-tension, `MTEOM`은 기록 data 끝으로 이동한다. `MTERASE`는 argument가 0이면 short erase, 그 밖의 값이면 long erase를 실행한다.
`MTSEEK`는 count tape block으로 이동한다. SCSI-1 drive에는 Tandberg 호환 seek(QFA), SCSI-2 drive에는 SCSI-2 seek를 사용하며 seek 뒤 status의 file·block number는 유효하지 않다. `MTSETBLK`는 drive block size를 설정하고 0은 가능한 경우 variable block mode를 뜻한다. `MTSETDENSITY`는 drive 문서가 정의한 density code를 설정한다. `MTLOCK`·`MTUNLOCK`은 drive door를 명시적으로 잠그거나 풀고, `MTLOAD`·`MTUNLOAD`는 tape를 load·unload한다. Argument x가 `MT_ST_HPLOADER_OFFSET + 1`부터 `+ 6`이면 HP C1553A changer에 x를 보내 사용할 slot을 선택한다.
`MTCOMPRESSION`은 SCSI mode page 15로 compression mode를 켜거나 끈다. 일부 drive는 Exabyte처럼 density code를 쓰거나 다른 mode page를 사용하며, 후자는 이 driver에 구현되지 않았다. Compression 기능이 없는 일부 drive가 오류 없이 어떤 mode든 받아들일 수도 있다.
`MTSETPART`는 다음 tape 작업 때 argument가 가리키는 partition으로 옮긴다. 새 partition에서 이전에 있던 block 위치로 가지만 다음 작업이 `MTSEEK`이면 해당 block으로 직접 이동한다. `MTMKPART`는 argument 0이면 한 partition, 0이 아니면 두 partition으로 format한다. 양수는 partition 1 크기(MB)이며 DDS와 일부 초기 drive에서 물리적으로 첫 partition이다. 음수의 절댓값은 partition 0 크기(MB)이며 LTO-5 이후 같은 신형 drive에서 물리적으로 첫 partition이다. Drive가 initiator 지정 크기 partition을 지원해야 한다. 두 command는 `MT_ST_CAN_PARTITIONS`를 설정해야 작동한다.
많은 command를 이동·기록·media control로 묶어 살펴본다.
IOCTLs
======
The tape is positioned and the drive parameters are set with ioctls
defined in mtio.h The tape control program 'mt' uses these ioctls. Try
to find an mt that supports all of the Linux SCSI tape ioctls and
opens the device for writing if the tape contents will be modified
(look for a package mt-st* from the Linux ftp sites; the GNU mt does
not open for writing for, e.g., erase).
The supported ioctls are:
The following use the structure mtop:
MTFSF
Space forward over count filemarks. Tape positioned after filemark.
MTFSFM
As above but tape positioned before filemark.
MTBSF
Space backward over count filemarks. Tape positioned before
filemark.
MTBSFM
As above but ape positioned after filemark.
MTFSR
Space forward over count records.
MTBSR
Space backward over count records.
MTFSS
Space forward over count setmarks.
MTBSS
Space backward over count setmarks.
MTWEOF
Write count filemarks.
MTWEOFI
Write count filemarks with immediate bit set (i.e., does not
wait until data is on tape)
MTWSM
Write count setmarks.
MTREW
Rewind tape.
MTOFFL
Set device off line (often rewind plus eject).
MTNOP
Do nothing except flush the buffers.
MTRETEN
Re-tension tape.
MTEOM
Space to end of recorded data.
MTERASE
Erase tape. If the argument is zero, the short erase command
is used. The long erase command is used with all other values
of the argument.
MTSEEK
Seek to tape block count. Uses Tandberg-compatible seek (QFA)
for SCSI-1 drives and SCSI-2 seek for SCSI-2 drives. The file and
block numbers in the status are not valid after a seek.
MTSETBLK
Set the drive block size. Setting to zero sets the drive into
variable block mode (if applicable).
MTSETDENSITY
Sets the drive density code to arg. See drive
documentation for available codes.
MTLOCK and MTUNLOCK
Explicitly lock/unlock the tape drive door.
MTLOAD and MTUNLOAD
Explicitly load and unload the tape. If the
command argument x is between MT_ST_HPLOADER_OFFSET + 1 and
MT_ST_HPLOADER_OFFSET + 6, the number x is used sent to the
drive with the command and it selects the tape slot to use of
HP C1553A changer.
MTCOMPRESSION
Sets compressing or uncompressing drive mode using the
SCSI mode page 15. Note that some drives other methods for
control of compression. Some drives (like the Exabytes) use
density codes for compression control. Some drives use another
mode page but this page has not been implemented in the
driver. Some drives without compression capability will accept
any compression mode without error.
MTSETPART
Moves the tape to the partition given by the argument at the
next tape operation. The block at which the tape is positioned
is the block where the tape was previously positioned in the
new active partition unless the next tape operation is
MTSEEK. In this case the tape is moved directly to the block
specified by MTSEEK. MTSETPART is inactive unless
MT_ST_CAN_PARTITIONS set.
MTMKPART
Formats the tape with one partition (argument zero) or two
partitions (argument non-zero). If the argument is positive,
it specifies the size of partition 1 in megabytes. For DDS
drives and several early drives this is the physically first
partition of the tape. If the argument is negative, its absolute
value specifies the size of partition 0 in megabytes. This is
the physically first partition of many later drives, like the
LTO drives from LTO-5 upwards. The drive has to support partitions
with size specified by the initiator. Inactive unless
MT_ST_CAN_PARTITIONS set.
MTSETDRVBUFFER option과 기본값
483-598`MTSETDRVBUFFER`는 여러 목적에 사용한다. `count`에 `MT_SET_OPTIONS` mask를 적용해 command를 얻고 하위 bit를 argument로 쓴다. Superuser(root)만 호출할 수 있다. Subcommand 0은 drive buffer option을 argument로 설정하며 0은 buffering 없음이다.
`MT_ST_BOOLEANS`는 option bit를 새 enabled·disabled 상태로 설정한다. Mode별 option은 `MT_ST_BUFFER_WRITES`(write buffering), `MT_ST_ASYNC_WRITES`(asynchronous write), `MT_ST_READ_AHEAD`(read ahead), `MT_ST_DEF_WRITES`(기본값을 write에만 적용), `MT_ST_SYSV`(System V semantics)다. Global option은 `MT_ST_TWO_FM`(filemark 두 개), `MT_ST_FAST_EOM`(SCSI EOD spacing), `MT_ST_AUTO_LOCK`(door 자동 잠금), `MT_ST_CAN_BSR`(여러 record backspace로 재배치), `MT_ST_NO_BLKLIMS`(drive에 block limit를 묻지 않아 block size는 variable로만 변경), `MT_ST_CAN_PARTITIONS`(partition tape 지원), `MT_ST_SCSI2LOGICAL`(SCSI-2의 `MTSEEK`·`MTIOCPOS`에서 device-dependent address 대신 logical block number 사용), `MT_ST_DEBUGGING`이다. 오래된 device-dependent address tape가 없다면 `MT_ST_SCSI2LOGICAL` 설정을 권장한다.
`MT_ST_NOWAIT`는 rewind 같은 일부 command가 끝날 때까지 기다리지 않는 immediate mode를 켠다. `MT_ST_NOWAIT_EOF`는 filemark 기록 완료를 기다리지 않는다. Immediate filemark의 위험은 앞의 `MTWEOFI` 설명을 따라야 한다. `MT_ST_SILI`는 variable block mode에서 요청 byte count보다 짧은 block을 읽을 때 SCSI command의 SILI bit를 설정해 성능을 높인다. Drive가 SILI를 지원하고 HBA가 transfer residual을 정확히 반환한다고 확신할 때만 켜야 한다. Debugging option은 driver에 debugging code가 compile되어 있어야 한다.
`MT_ST_SETBOOLEANS`와 `MT_ST_CLEARBOOLEANS`는 option bit를 각각 설정하거나 지운다. `MT_ST_WRITE_THRESHOLD`는 하위 bit 값(KB)으로 write threshold를 정한다. `MT_ST_DEF_BLKSIZE`는 자동 적용할 기본 block size를 정의하며 `0xffffff`는 더 이상 기본값을 사용하지 않음을 뜻한다. `MT_ST_DEF_DENSITY`와 `MT_ST_DEF_DRVBUFFER`는 density 8 bit와 drive buffer state 3 bit를 설정·해제한다. 값이 `MT_ST_CLEAR_DEFAULT`(`0xfffff`)이면 기본값을 사용하지 않고, 아니면 최하위 bit들이 새 parameter 값이다.
`MT_ST_DEF_COMPRESSION`은 최하위 byte가 `0xff`이면 compression 기본값을 사용하지 않는다. 그 밖에는 최하위 bit가 새 기본값이고, bit 8-15가 0도 `0xff`도 아니면 그 수를 compression algorithm으로 쓴다. `MT_ST_CLEAR_DEFAULT`로 compression 기본값을 지울 수도 있다. `MT_ST_SET_TIMEOUT`은 일반 timeout을 second 단위로 정하며 기본값은 900초(15분)다. Read·write 중 device가 수행하는 retry를 감당할 만큼 길어야 한다. `MT_ST_SET_LONG_TIMEOUT`은 오래 걸리는 작업의 timeout이며 기본값은 14,000초(3.9시간), erase에서는 이 값을 다시 8배 한다.
`MT_ST_SET_CLN`은 argument 하위 24 bit로 cleaning request 해석법을 정한다. Extended sense data에서 지정 pattern을 찾으면 generic status bit `GMT_CLN`을 설정할 수 있다. 하위 8 bit는 sense data byte 번호이며 18 이상이고 요청 가능한 최대 sense data 크기 이하여야 한다. 값 1-17은 예약되어 있다. Bit 9-16은 관련 bit를 고르는 mask, bit 17-23은 pattern이다. Pattern이 0이면 mask 아래 bit 중 하나 이상이 켜졌을 때 cleaning request이고, 0이 아니면 masked sense byte와 pattern이 일치해야 한다. Additional sense code·qualifier `00h 17h`가 보이면 `MT_ST_SET_CLN` 설정과 관계없이 cleaning bit를 켠다.
괄호로 표시되던 mode별·global 범위를 분리했다.
MTSETDRVBUFFER
Is used for several purposes. The command is obtained from count
with mask MT_SET_OPTIONS, the low order bits are used as argument.
This command is only allowed for the superuser (root). The
subcommands are:
* 0
The drive buffer option is set to the argument. Zero means
no buffering.
* MT_ST_BOOLEANS
Sets the buffering options. The bits are the new states
(enabled/disabled) the following options (in the
parenthesis is specified whether the option is global or
can be specified differently for each mode):
MT_ST_BUFFER_WRITES
write buffering (mode)
MT_ST_ASYNC_WRITES
asynchronous writes (mode)
MT_ST_READ_AHEAD
read ahead (mode)
MT_ST_TWO_FM
writing of two filemarks (global)
MT_ST_FAST_EOM
using the SCSI spacing to EOD (global)
MT_ST_AUTO_LOCK
automatic locking of the drive door (global)
MT_ST_DEF_WRITES
the defaults are meant only for writes (mode)
MT_ST_CAN_BSR
backspacing over more than one records can
be used for repositioning the tape (global)
MT_ST_NO_BLKLIMS
the driver does not ask the block limits
from the drive (block size can be changed only to
variable) (global)
MT_ST_CAN_PARTITIONS
enables support for partitioned
tapes (global)
MT_ST_SCSI2LOGICAL
the logical block number is used in
the MTSEEK and MTIOCPOS for SCSI-2 drives instead of
the device dependent address. It is recommended to set
this flag unless there are tapes using the device
dependent (from the old times) (global)
MT_ST_SYSV
sets the SYSV semantics (mode)
MT_ST_NOWAIT
enables immediate mode (i.e., don't wait for
the command to finish) for some commands (e.g., rewind)
MT_ST_NOWAIT_EOF
enables immediate filemark mode (i.e. when
writing a filemark, don't wait for it to complete). Please
see the BASICS note about MTWEOFI with respect to the
possible dangers of writing immediate filemarks.
MT_ST_SILI
enables setting the SILI bit in SCSI commands when
reading in variable block mode to enhance performance when
reading blocks shorter than the byte count; set this only
if you are sure that the drive supports SILI and the HBA
correctly returns transfer residuals
MT_ST_DEBUGGING
debugging (global; debugging must be
compiled into the driver)
* MT_ST_SETBOOLEANS, MT_ST_CLEARBOOLEANS
Sets or clears the option bits.
* MT_ST_WRITE_THRESHOLD
Sets the write threshold for this device to kilobytes
specified by the lowest bits.
* MT_ST_DEF_BLKSIZE
Defines the default block size set automatically. Value
0xffffff means that the default is not used any more.
* MT_ST_DEF_DENSITY, MT_ST_DEF_DRVBUFFER
Used to set or clear the density (8 bits), and drive buffer
state (3 bits). If the value is MT_ST_CLEAR_DEFAULT
(0xfffff) the default will not be used any more. Otherwise
the lowermost bits of the value contain the new value of
the parameter.
* MT_ST_DEF_COMPRESSION
The compression default will not be used if the value of
the lowermost byte is 0xff. Otherwise the lowermost bit
contains the new default. If the bits 8-15 are set to a
non-zero number, and this number is not 0xff, the number is
used as the compression algorithm. The value
MT_ST_CLEAR_DEFAULT can be used to clear the compression
default.
* MT_ST_SET_TIMEOUT
Set the normal timeout in seconds for this device. The
default is 900 seconds (15 minutes). The timeout should be
long enough for the retries done by the device while
reading/writing.
* MT_ST_SET_LONG_TIMEOUT
Set the long timeout that is used for operations that are
known to take a long time. The default is 14000 seconds
(3.9 hours). For erase this value is further multiplied by
eight.
* MT_ST_SET_CLN
Set the cleaning request interpretation parameters using
the lowest 24 bits of the argument. The driver can set the
generic status bit GMT_CLN if a cleaning request bit pattern
is found from the extended sense data. Many drives set one or
more bits in the extended sense data when the drive needs
cleaning. The bits are device-dependent. The driver is
given the number of the sense data byte (the lowest eight
bits of the argument; must be >= 18 (values 1 - 17
reserved) and <= the maximum requested sense data sixe),
a mask to select the relevant bits (the bits 9-16), and the
bit pattern (bits 17-23). If the bit pattern is zero, one
or more bits under the mask indicate cleaning request. If
the pattern is non-zero, the pattern must match the masked
sense data byte.
(The cleaning bit is set if the additional sense code and
qualifier 00h 17h are seen regardless of the setting of
MT_ST_SET_CLN.)
MTIOCPOS와 MTIOCGET status
599-623`mtpos` 구조체를 사용하는 `MTIOCPOS`는 drive의 현재 위치를 읽는다. SCSI-1 drive에는 Tandberg 호환 QFA를, SCSI-2 drive에는 SCSI-2 command를 사용한다.
`mtget` 구조체로 status를 반환하는 `MTIOCGET`은 file number와 file 안의 block number를 제공한다. `MTBSF` 뒤처럼 block을 결정할 수 없으면 -1이다. Drive type은 `MTISSCSI1` 또는 `MTISSCSI2`다. 직전 status call 이후 복구된 error 수는 `mt_erreg` 하위 word에 저장한다. 현재 block size와 density code는 `mt_dsreg`에 들어가며 subfield shift는 `MT_ST_BLKSIZE_SHIFT`와 `MT_ST_DENSITY_SHIFT`다.
`GMT_xxx` bit는 drive status를 반영한다. `GMT_DR_OPEN`은 drive에 tape가 없을 때 설정되고, `GMT_EOD`는 기록 data 끝 또는 tape 끝, `GMT_EOT`는 tape 끝을 뜻한다.
위치와 종합 status 반환 구조체가 다르다.
The following ioctl uses the structure mtpos:
MTIOCPOS
Reads the current position from the drive. Uses
Tandberg-compatible QFA for SCSI-1 drives and the SCSI-2
command for the SCSI-2 drives.
The following ioctl uses the structure mtget to return the status:
MTIOCGET
Returns some status information.
The file number and block number within file are returned. The
block is -1 when it can't be determined (e.g., after MTBSF).
The drive type is either MTISSCSI1 or MTISSCSI2.
The number of recovered errors since the previous status call
is stored in the lower word of the field mt_erreg.
The current block size and the density code are stored in the field
mt_dsreg (shifts for the subfields are MT_ST_BLKSIZE_SHIFT and
MT_ST_DENSITY_SHIFT).
The GMT_xxx status bits reflect the drive status. GMT_DR_OPEN
is set if there is no tape in the drive. GMT_EOD means either
end of recorded data or end of tape. GMT_EOT means end of tape.
기타 compile option과 위치 정확성
624-655`ST_RECOVERED_WRITE_FATAL`을 정의하면 복구된 write error도 fatal로 취급한다. Tape device 최대 수는 `ST_MAX_TAPES`가 정하지만 driver 초기화 때 더 많은 tape를 발견하면 최대값을 그 수에 맞춰 늘린다.
`ST_NOWAIT`을 정의하면 tape positioning SCSI command가 즉시 반환할 수 있다. 이 경우 사용자는 이전 작업이 끝나기 전에 다음 tape 작업을 시작하지 않아야 한다. Drive와 SCSI adapter는 이를 정상 처리해야 하지만 일부 조합은 이 상황에서 SCSI bus를 멈추는 것으로 알려져 있다.
`MTEOM`은 기본적으로 filemark 32,767개를 건너뛰는 방식으로 구현되며 이 방식에서는 status의 file number가 정확하다. `ST_FAST_EOM`을 1로 설정하거나 `MT_ST_OPTIONS` ioctl을 사용하면 EOD로 직접 spacing할 수 있지만 file number는 무효가 된다.
Read ahead나 buffered write를 사용하면 file을 닫은 뒤 file 내부 위치가 정확하지 않을 수 있다. 정확한 위치를 복구하려면 둘 이상의 record를 뒤로 이동해야 할 수 있다. Compile time에 `ST_IN_FILE_POS`를 정의하거나 ioctl로 drive의 `MT_ST_CAN_BSR` bit를 설정하면 정확한 file 내 위치를 얻을 수 있다. 사용자가 read ahead로 미리 읽은 범위까지 data를 요청하지 않았다면 driver는 항상 넘었던 filemark 뒤로 되돌아간다.
Miscellaneous Compile Options
=============================
The recovered write errors are considered fatal if ST_RECOVERED_WRITE_FATAL
is defined.
The maximum number of tape devices is determined by the define
ST_MAX_TAPES. If more tapes are detected at driver initialization, the
maximum is adjusted accordingly.
Immediate return from tape positioning SCSI commands can be enabled by
defining ST_NOWAIT. If this is defined, the user should take care that
the next tape operation is not started before the previous one has
finished. The drives and SCSI adapters should handle this condition
gracefully, but some drive/adapter combinations are known to hang the
SCSI bus in this case.
The MTEOM command is by default implemented as spacing over 32767
filemarks. With this method the file number in the status is
correct. The user can request using direct spacing to EOD by setting
ST_FAST_EOM 1 (or using the MT_ST_OPTIONS ioctl). In this case the file
number will be invalid.
When using read ahead or buffered writes the position within the file
may not be correct after the file is closed (correct position may
require backspacing over more than one record). The correct position
within file can be obtained if ST_IN_FILE_POS is defined at compile
time or the MT_ST_CAN_BSR bit is set for the drive with an ioctl.
(The driver always backs over a filemark crossed by read ahead if the
user does not request data that far.)
Debug 활성화와 hang 진단
656-678Debugging code는 기본으로 compile되지만 kernel module parameter `debug_flag`의 기본값이 0이라 출력은 꺼져 있다. Ioctl로 켜고 끌 수 있으며 module load option에 `debug_flag=1`을 넣으면 시작부터 활성화된다. 출력량은 많지 않다. `/sys/bus/scsi/drivers/st/debug_flag`에 `0` 또는 `1`을 써서도 비활성화·활성화할 수 있다.
Tape가 멈춘 듯 보이면 `ps -l`로 tape를 사용하는 process 상태를 확인한다. State가 `D`이면 무언가를 기다리는 중이고 `WCHAN`은 driver가 기다리는 위치를 보여 준다. 현재 `System.map`이 올바른 위치, 문서의 procps 기준 `/boot`에 있거나 kmem ps용 `/etc/psdatabase`가 갱신되어 있으면 `WCHAN`에 function 이름이 나온다. 그렇지 않으면 `System.map`에서 address에 해당하는 function을 찾아야 한다.
Tape driver timeout은 대부분의 다른 driver보다 매우 길다. 따라서 Linux driver가 hang한 것처럼 보여도 실제 원인은 tape firmware가 혼란 상태에 빠진 채 긴 timeout을 기다리는 것일 수 있다.
긴 timeout과 실제 wait 지점을 구분하는 기본 절차다.
Debugging Hints
===============
Debugging code is now compiled in by default but debugging is turned off
with the kernel module parameter debug_flag defaulting to 0. Debugging
can still be switched on and off with an ioctl. To enable debug at
module load time add debug_flag=1 to the module load options, the
debugging output is not voluminous. Debugging can also be enabled
and disabled by writing a '0' (disable) or '1' (enable) to the sysfs
file /sys/bus/scsi/drivers/st/debug_flag.
If the tape seems to hang, I would be very interested to hear where
the driver is waiting. With the command 'ps -l' you can see the state
of the process using the tape. If the state is D, the process is
waiting for something. The field WCHAN tells where the driver is
waiting. If you have the current System.map in the correct place (in
/boot for the procps I use) or have updated /etc/psdatabase (for kmem
ps), ps writes the function name in the WCHAN field. If not, you have
to look up the function from System.map.
Note also that the timeouts are very long compared to most other
drivers. This means that the Linux driver may appear hung although the
real reason is that the tape firmware has got confused.
요약·해설
st.rst:1-678범용 SCSI tape driver `st`가 사용자·관리자 설정을 결합하는 방식부터 minor number mode, fixed·variable block I/O, filemark 동기화, sysfs 통계, direct I/O와 scatter/gather buffering, EOM 반환 규칙, 전체 ioctl 및 debug 절차까지 운영에 필요한 동작을 한 문서에서 다룹니다.