返回值

EACCES
试图写入或擦除写保护的磁带。 (在open(2)期间未检测到此错误。)
EBUSY
设备已在使用中,或者驱动程序无法分配缓冲区。
EFAULT
命令参数指向不属于调用进程的内存。
EINVAL
ioctl(2)的参数无效,或者请求的块大小无效。
EIO
请求的操作无法完成。
ENOMEM
read(2)中的字节数小于磁带上的下一个物理块。 (在2.2.18和2.4.0之前,多余的字节已被静默忽略。)
ENOSPC
磁带已到达介质末尾,因此无法完成写操作。
ENOSYS
未知的ioctl(2)。
ENXIO
在打开期间,磁带设备不存在。
EOVERFLOW
试图读取或写入一个大于驱动程序内部缓冲区的可变长度块。
EROFS
当驱动器中的磁带受到写保护时,尝试使用O_WRONLY或O_RDWR进行打开。

说明

st驱动程序提供了到各种SCSI磁带设备的接口。当前,驱动程序控制所有检测到的lqsequential-accessrq类型的设备。 st驱动程序使用主设备号9。

每个设备使用八个次设备号。次编号中的最低五位按检测顺序顺序分配。在2.6内核中,最低8位上方的位与最低5位相连,形成了磁带号。次要编号可以分为两组,每组四个数字:主体(自动倒带)次要设备编号n和lqno-rewindrq设备编号(n + 128)。关闭使用主设备号打开的设备时,将向其发送REWIND命令。使用lqno-rewindrq设备编号打开的设备将不会。 (请注意,使用自动倒带设备将磁带与mt一起放置不会产生预期的结果:在mt命令之后将磁带倒带,而下一条命令将从磁带的开头开始)。

在每个组中,四个次要数字可用于定义具有不同特征(块大小,压缩,密度等)的设备。系统启动时,只有第一个设备可用。定义默认特征后,将激活其他三个(请参见下文)。 (通过更改编译时常数,可以更改最大数量的磁带机和每个磁带机的次要数量之间的平衡。默认分配允许控制32个磁带机。例如,可以控制多达64个带两个次要号的磁带机,用于不同的选项。)

设备通常由以下人员创建:

mknod -m 666 /dev/st0 c 9 0
mknod -m 666 /dev/st0l c 9 32
mknod -m 666 /dev/st0m c 9 64
mknod -m 666 /dev/st0a c 9 96
mknod -m 666 /dev/nst0 c 9 128
mknod -m 666 /dev/nst0l c 9 160
mknod -m 666 /dev/nst0m c 9 192
mknod -m 666 /dev/nst0a c 9 224

没有相应的块设备。

驱动程序使用一个内部缓冲区,该缓冲区必须足够大以容纳至少一个磁带块。在2.1.121之前的内核中,缓冲区被分配为一个连续的块。这将块大小限制为内核分配器可以提供的最大连续内存块。目前,对于32位体系结构,该限制为128 kB;对于64位体系结构,该限制为256 kB。在较新的内核中,如果有必要,驱动程序会分几部分分配缓冲区。默认情况下,最大部分数为16.这意味着最大块大小非常大(如果成功分配16个128kB的块,则为2MB)。

驱动程序的内部缓冲区大小由编译时常数确定,可以用内核启动选项覆盖。除此之外,如有必要,驱动程序会在运行时尝试分配更大的临时缓冲区。但是,大块连续内存块的运行时分配可能会失败,建议不要对2.1.121之前的内核过分依赖动态缓冲区分配(这也适用于按需加载带有内核或kmod的驱动程序)。

该驱动程序不专门支持任何磁带机品牌或型号。系统启动后,磁带设备选项由驱动器固件定义。例如,如果驱动器固件选择固定块模式,则磁带设备将使用固定块模式。这些选项可以通过显式的ioctl(2)调用进行更改,并在关闭并重新打开设备后仍然有效。设置选项会同时影响自动倒带和非倒带设备。

可以为四个子组中的不同设备指定不同的选项。这些选项在打开设备后生效。例如,系统管理员可以定义一种以固定块模式写入具有特定块大小的设备,另一种以可变块模式写入(如果驱动器支持两种模式)。

如果驱动器支持,则驱动程序支持磁带分区。 (请注意,磁带分区与磁盘分区无关。已分区的磁带可以看作是一种介质中的多个逻辑磁带。)必须通过ioctl(2)启用分区支持。磁带位置在分区更改后保留在每个分区内。使用ioctl(2)选择用于后续磁带操作的分区。为了避免不必要的磁带移动,分区开关将与下一个磁带操作一起执行。磁带上的最大分区数由编译时常数(最初为四个)定义。该驱动程序包含一个ioctl(2),可以格式化带有一个或两个分区的磁带。

通常将设备/ dev / tape创建为到系统上默认磁带设备的硬链接或软链接。

从内核2.6.2开始,驱动程序在sysfs目录/ sys / class / scsi_tape中导出连接的设备以​​及分配给设备的一些参数。

Data transfer

驱动程序支持固定块模式和可变块模式下的操作(如果驱动器支持)。在固定块模式下,驱动器将写入指定大小的块,并且块大小不取决于写入系统调用的字节数。在可变块模式下,每个写调用都写入一个磁带块,字节数确定相应磁带块的大小。请注意,磁带上的块不包含有关写入模式的任何信息:读取时,唯一重要的事情是使用接受磁带上块大小的命令。

在可变块模式下,读取字节数不必与磁带块大小完全匹配。如果字节数大于磁带上的下一个块,则驱动程序将返回数据,函数将返回实际的块大小。如果块大小大于字节数,则返回错误。

在固定块模式下,如果启用了缓冲,则读取的字节数可以是任意的;如果禁用了缓冲,则读取的字节数可以是磁带块大小的倍数。如果启用了缓冲,则2.1.121之前的内核允许使用任意字节数进行写入。在所有其他情况下(禁用缓冲的2.1.121之前的内核或较新的内核),写字节数必须是磁带块大小的倍数。

在2.6内核中,驱动程序尝试在用户缓冲区和设备之间使用直接传输。如果无法做到这一点,则使用驱动程序的内部缓冲区。不使用直接传输的原因包括用户缓冲区的对齐不正确(默认值为512字节,但是可以由HBA驱动程序更改),SCSI适配器无法访问用户缓冲区的一页或多页,等等。

如果关闭前的最后一个磁带操作是写操作,则将文件标记自动写入磁带。

读取时遇到文件标记时,将发生以下情况。当找到文件标记时,如果缓冲区中还有剩余数据,则返回缓冲的数据。下一次读取将返回零字节。以下读取从下一个文件返回数据。通过为两个连续的读取调用返回零字节来指示已记录数据的结尾。第三次读取返回错误。

Ioctls

该驱动程序支持三个ioctl(2)请求。 st驱动程序无法识别的请求将传递到SCSI驱动程序。以下定义来自/usr/include/linux/mtio.h

MTIOCTOP --- perform a tape operation

该请求采用类型(struct mtop *)的参数。并非所有驱动器都支持所有操作。如果驱动器拒绝操作,则驱动器将返回EIO错误。

/* Structure for MTIOCTOP - mag tape op command: */
struct mtop {
    short   mt_op;       /* operations defined below */
    int     mt_count;    /* how many of them */
};

常规磁带使用的磁带操作:

MTBSF
mt_count文件标记上的后退空间。
MTBSFM
mt_count文件标记上的后退空间。将磁带重新放置到最后一个文件标记的EOT侧。
MTBSR
mt_count记录(磁带块)上的后退空间。
MTBSS
mt_count设置标记上的后退空间。
MTCOMPRESSION
如果mt_count不为零,则启用驱动器中的磁带数据压缩;如果mt_count为零,则禁用压缩。此命令使用大多数DAT支持的MODE页面15。
MTEOM
转到录制媒体的末尾(用于附加文件)。
MTERASE
擦除磁带。对于2.6内核,如果参数为零,则执行短擦除(标记磁带为空)。否则,将进行长时间擦除(全部擦除)。
MTFSF
通过mt_count文件标记转发空间。
MTFSFM
通过mt_count文件标记转发空间。将磁带重新放置到最后一个文件标记的BOT一侧。
MTFSR
通过mt_count记录(磁带块)转发空间。
MTFSS
通过mt_count个设置标记转发空间。
MTLOAD
执行SCSI load命令。某些HP自动装带器有特殊情况。如果mt_count是常数MT_ST_HPLOADER_OFFSET加上数字,则该数字将发送到驱动器以控制自动装带器。
MTLOCK
锁上磁带机门。
MTMKPART
将磁带格式化为一个或两个分区。如果mt_count为正,则给出分区1的大小,分区0包含其余的磁带。如果mt_count为零,则将磁带格式化为一个分区。从内核版本4.6开始,负mt_count指定分区0的大小,而磁带的其余部分包含分区1。分区的物理顺序取决于驱动器。除非为驱动器启用了分区支持,否则该驱动器不允许使用此命令(请参见下面的MT_ST_CAN_PARTITIONS)。
MTNOP
没有操作-会浪费驱动程序的缓冲区。在使用MTIOCGET读取状态之前,应使用它。
MTOFFL
倒带并使驱动器脱机。
MTRESET
重置驱动器。
MTRETEN
重新拉紧胶带。
MTREW
倒带。
MTSEEK
寻找在mt_count中指定的磁带块号。此操作需要支持LOCATE命令的SCSI-2驱动器(特定于设备的地址)或与Tandberg兼容的SCSI-1驱动器(Tandberg,Archive Viper,Wangtek等)。如果使用特定于设备的地址,则块号应该是MTIOCPOS先前返回的块号。
MTSETBLK
将驱动器的块长度设置为mt_count中指定的值。块长度为零会将驱动器设置为可变块大小模式。
MTSETDENSITY
将磁带密度设置为mt_count中的代码。可以从驱动器文档中找到驱动器支持的密度代码。
MTSETPART
活动分区切换到mt_count。分区从零开始编号。除非为驱动器启用了分区支持,否则该驱动器不允许使用此命令(请参见下面的MT_ST_CAN_PARTITIONS)。
MTUNLOAD
执行SCSI卸载命令(不弹出磁带)。
MTUNLOCK
解锁磁带机门。
MTWEOF
写入mt_count文件标记。
MTWSM
编写mt_count设置标记。

磁带操作,用于设置设备选项(由超级用户执行):

MTSETDRVBUFFER
根据mt_count中编码的位设置各种驱动器和驱动程序选项。这些包括驱动器的缓冲模式,一组布尔驱动器选项,缓冲区写阈值,块大小和密度的默认值以及超时(仅在内核2.1及更高版本中)。单个操作只能影响以下列表中的一项(布尔值计为一项)。
A value having zeros in the high-order 4 bits will be used to set the drive's buffering mode. The buffering modes are:
0
在将数据块实际写入介质之前,驱动器不会报告写入命令的良好状态。
1
一旦所有数据都已传输到驱动器的内部缓冲区,驱动器可能会报告写入命令的良好状态。
2
一旦(a)所有数据都已传输到驱动器的内部缓冲区中,并且(b)来自不同启动器的所有缓冲数据都已成功写入介质中,驱动器可能会报告写入命令的良好状态。
为了控制写阈值,mt_count中的值必须包括常数MT_ST_WRITE_THRESHOLD按位或与低28位的块计数进行或运算。块计数是指1024字节的块,而不是磁带上的物理块大小。阈值不能超过驱动程序的内部缓冲区大小(请参见上面的说明)。
要设置和清除布尔选项,mt_count中的值必须包括常数MT_ST_BOOLEANSMT_ST_SETBOOLEANS,MT_ST_CLEARBOOLEANS或MT_ST_DEFBOOLEANS之一,按位与以下选项的任意组合进行或运算。使用MT_ST_BOOLEANS,可以将选项设置为相应位中定义的值。使用MT_ST_SETBOOLEANS可以选择设置选项,并且可以选择MT_ST_DEFBOOLEANS清除。
磁带设备的默认选项是使用MT_ST_DEFBOOLEANS设置的。首次定义非活动磁带设备(例如具有次要32或160的设备)时,将激活该设备。激活的设备将从启动时激活的设备继承未明确设置的选项。
The Boolean options are:
MT_ST_BUFFER_WRITES(Default: true)
在固定块模式下缓冲所有写操作。如果此选项为false,并且驱动器使用固定的块大小,则所有写操作必须是块大小的倍数。必须将此选项设置为false才能写入可靠的多卷存档。
MT_ST_ASYNC_WRITES(Default: true)
当此选项为true时,如果数据适合驱动程序的缓冲区,则写操作将立即返回,而无需等待将数据传输到驱动器。写入阈值确定发出新的SCSI写入命令之前缓冲区必须满的程度。驱动器报告的任何错误将保留到下一次操作。必须将此选项设置为false才能写入可靠的多卷存档。
MT_ST_READ_AHEAD(Default: true)
此选项使驱动程序以固定块模式提供读取缓冲和预读。如果此选项为false,并且驱动器使用固定的块大小,则所有读取操作必须是块大小的倍数。
MT_ST_TWO_FM(Default: false)
关闭文件时,此选项可修改驱动程序的行为。通常的操作是写入单个文件标记。如果该选项为true,则驱动程序将在第二个文件标记和后退空间上写入两个文件标记。
注意:由于QIC磁带驱动器无法覆盖文件标记,因此不应将其设置为true。这些驱动器通过测试空白磁带而不是两个连续的文件标记来检测记录数据的结尾。当前,大多数其他驱动器还会检测记录数据的结尾,通常仅在与其他系统交换磁带时才需要使用两个文件标记。
MT_ST_DEBUGGING(Default: false)
此选项打开来自驱动程序的各种调试消息(仅当使用DEBUG定义的非零编译驱动程序时才有效)。
MT_ST_FAST_EOM(Default: false)
此选项导致MTEOM操作直接发送到驱动器,可能会加快操作速度,但会导致驱动程序无法跟踪通常由MTIOCGET请求返回的当前文件号。如果MT_ST_FAST_EOM为false,则驱动程序将通过向前间隔文件来响应MTEOM请求。
MT_ST_AUTO_LOCK(Default: false)
如果此选项为true,则打开设备文件时驱动器门将被锁定,而当设备文件关闭时驱动器门将被解锁。
MT_ST_DEF_WRITES(Default: false)
当从链接到驱动器的一个设备更改为链接到同一驱动器的另一设备时,磁带选项(块大小,模式,压缩等)可能会更改,具体取决于设备的定义方式。此选项定义驱动程序何时使用SCSI命令强制执行更改以及何时依赖驱动器自动检测功能。如果此选项为false,则驱动程序将在设备更改时立即发送SCSI命令。如果该选项为true,则在请求写入之前不发送SCSI命令。在这种情况下,读取时允许驱动器固件检测磁带结构,而SCSI命令仅用于确保按照正确的规范写入磁带。
MT_ST_CAN_BSR(Default: false)
当使用预读时,有时在关闭设备时必须将磁带向后间隔到正确的位置,并使用SCSI命令在记录上向后间隔。某些较旧的驱动器无法可靠地处理此命令,该选项可用于指示驱动程序不使用该命令。最终结果是,在预读和固定块模式下,关闭设备后,磁带可能无法正确放置在文件中。对于2.6内核,对于支持SCSI-3的驱动器,默认设置为true。
MT_ST_NO_BLKLIMS(Default: false)
某些驱动器不接受READ BLOCK LIMITS SCSI命令。如果使用此命令,则驱动程序不使用该命令。缺点是驱动程序无法在发送命令之前检查所选块大小是否为驱动器可接受。
MT_ST_CAN_PARTITIONS(Default: false)
此选项启用对磁带中多个分区的支持。该选项适用于链接到驱动器的所有设备。
MT_ST_SCSI2LOGICAL(Default: false)
此选项指示驱动程序在执行查找和告知操作时(同时使用MTSEEK和MTIOCPOS命令以及更改磁带分区时)使用SCSI-2标准中定义的逻辑块地址。否则,将使用设备特定的地址。如果驱动器支持逻辑地址,则强烈建议设置此选项,因为它们也计算文件标记。有些驱动器仅支持逻辑块地址。
MT_ST_SYSV(Default: false)
启用此选项后,磁带设备将使用System V语义。否则,将使用BSD语义。语义之间最重要的区别是,当关闭用于读取的设备时会发生什么:在System V语义中,如果磁带在使用设备时未发生变化,则磁带向前间隔下一个文件标记。在BSD语义中,磁带位置不会更改。
MT_NO_WAIT(Default: false)
为某些命令(例如快退)启用即时模式(即,不要等待命令完成)。

一个例子:

struct mtop mt_cmd;
mt_cmd.mt_op = MTSETDRVBUFFER;
mt_cmd.mt_count = MT_ST_BOOLEANS |
        MT_ST_BUFFER_WRITES | MT_ST_ASYNC_WRITES;
ioctl(fd, MTIOCTOP, mt_cmd);
可以使用MT_ST_DEF_BLKSIZE设置设备的默认块大小,并且可以使用MT_ST_DEFDENSITY设置默认密度代码。参数的值与操作码相加。
在内核2.1.x及更高版本中,可以使用子命令MT_ST_SET_TIMEOUT设置超时值,或者以秒为单位设置超时值。可以使用MT_ST_SET_LONG_TIMEOUT设置长超时(用于倒带和其他可能花费很长时间的命令)。内核默认值很长,以确保任何驱动器的成功命令都不会超时。因此,即使仅等待超时,驱动程序似乎也可能卡住了。这些命令可用于为特定驱动器设置更多实用值。为一台设备设置的超时适用于链接到同一驱动器的所有设备。
从内核2.4.19和2.5.43开始,驱动程序支持一个状态位,该状态位指示驱动器是否请求清洗。使用MT_ST_SEL_CLN子命令设置驱动器返回清洁信息的方法。如果该值为零,则清理位始终为零。如果值为1,则使用SCSI-3标准中定义的TapeAlert数据(尚未实现)。值2-17保留。如果最低的八个位>= 18,则使用扩展的检测数据中的位。位9-16指定掩码以选择要查看的位,位17-23指定要查找的位模式。如果位模式为零,则掩码下的一个或多个位指示清除请求。如果该模式为非零,则该模式必须与被屏蔽的检测数据字节匹配。

MTIOCGET --- get status

该请求采用类型(struct mtget *)的参数。

/* structure for MTIOCGET - mag tape get status command */
struct mtget {
    long     mt_type;
    long     mt_resid;
    /* the following registers are device dependent */
    long     mt_dsreg;
    long     mt_gstat;
    long     mt_erreg;
    /* The next two fields are not always used */
    daddr_t  mt_fileno;
    daddr_t  mt_blkno;
};
mt_type
头文件为mt_type定义了许多值,但是当前驱动程序仅报告通用类型MT_ISSCSI1(通用SCSI-1磁带)和MT_ISSCSI2(通用SCSI-2磁带)。
mt_resid
包含当前的磁带分区号。
mt_dsreg
报告驱动器当前的块大小(低24位)和密度(高8位)设置。这些字段由MT_ST_BLKSIZE_SHIFTMT_ST_BLKSIZE_MASK,MT_ST_DENSITY_SHIFT和MT_ST_DENSITY_MASK定义。
mt_gstat
reports generic (device independent) status information. The header file defines macros for testing these status bits:
GMT_EOF(x):
磁带恰好位于文件标记之后(在MTSEEK操作之后始终为false)。
GMT_BOT(x):
磁带位于第一个文件的开头(在MTSEEK操作之后始终为false)。
GMT_EOT(x):
磁带操作已到达物理磁带尾。
GMT_SM(x):
磁带当前位于设定标记处(MTSEEK操作后始终为假)。
GMT_EOD(x):
磁带位于记录数据的末尾。
GMT_WR_PROT(x):
驱动器被写保护。对于某些驱动器,这也可能意味着该驱动器不支持在当前介质类型上写入。
GMT_ONLINE(x):
最后一个open(2)找到了已安装磁带并准备运行的驱动器。
GMT_D_6250(x), GMT_D_1600(x), GMT_D_800(x):
该lqgenericrq状态信息仅报告9磁道½"磁带机的当前密度设置。
GMT_DR_OPEN(x):
驱动器上没有磁带。
GMT_IM_REP_EN(x):
立即报告模式。如果不能保证在写调用返回时已将数据物理地写入磁带,则该位置1。仅当驱动程序不缓冲数据并且驱动器设置为不缓冲数据时,才将其设置为零。
GMT_CLN(x):
驱动器已要求清洁。从2.4.19和2.5.43开始在内核中实现。
mt_erreg
mt_erreg中定义的唯一字段是低16位(由MT_ST_SOFTERR_SHIFT和MT_ST_SOFTERR_MASK定义)中的已恢复错误计数。由于驱动器报告已恢复错误的方式不一致,因此通常不维护此计数(默认情况下,大多数驱动器不报告软错误,但是可以使用SCSI MODE SELECT命令更改此错误)。
mt_fileno
报告当前文件号(从零开始)。当文件号未知时(例如,在MTBSS或MTSEEK之后),此值设置为-1。
mt_blkno
报告当前文件中的块号(从零开始)。当块号未知时(例如,在MTBSF,MTBSS或MTSEEK之后),此值设置为-1。

MTIOCPOS --- get tape position

该请求采用类型(struct mtpos *)的参数,并报告当前磁带块号的驱动器概念,该概念与MTIOCGET返回的mt_blkno不同。该驱动器必须是支持READ POSITION命令(特定于设备的地址)的SCSI-2驱动器,或者是与Tandberg兼容的SCSI-1驱动器(Tandberg,Archive Viper,Wangtek等)。

/* structure for MTIOCPOS - mag tape get position command */
struct mtpos {
    long mt_blkno;    /* current block number */
};

另外参见

mt(1)

Linux内核源代码树中的文件driver / scsi / README.st或Documentation / scsi / st.txt(内核> = 2.6)包含有关驱动程序及其配置可能性的最新信息

出版信息

这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/

文件

/dev/st*
自动倒带SCSI磁带设备
/dev/nst*
非倒带SCSI磁带设备
ST - Linux手册页

Linux程序员手册 第4部分
更新日期: 2020-04-11

名称

st-SCSI磁带设备

语法

#include <sys/mtio.h>

int ioctl(int fd, int request [, (void *)arg3]);
int ioctl(int fd, MTIOCTOP, (struct mtop *)mt_cmd);
int ioctl(int fd, MTIOCGET, (struct mtget *)mt_status);
int ioctl(int fd, MTIOCPOS, (struct mtpos *)mt_pos);

备注

1.
在系统之间交换数据时,两个系统都必须在物理磁带块大小上达成共识。启动后驱动器的参数通常不是大多数操作系统在这些设备上使用的参数。如果驱动器支持可变模式,则大多数系统都使用该模式。这适用于大多数现代驱动器,包括DAT,8mm螺旋扫描驱动器,DLT等。建议在Linux中也以可变块模式使用这些驱动器(例如,在系统启动时使用MTSETBLK或MTSETDEFBLK设置模式) ,至少在与外部系统交换数据时使用。这样的缺点是必须使用相当大的磁带块大小才能在SCSI总线上获得可接受的数据传输速率。
2.
许多程序(例如tar(1))允许用户在命令行上指定阻止因素。请注意,这仅在可变块模式下确定磁带上的物理块大小。
3.
为了使用SCSI磁带驱动器,必须将基本SCSI驱动程序,SCSI适配器驱动程序和SCSI磁带驱动程序配置到内核中或作为模块加载。如果不存在SCSI-tape驱动程序,则可以识别该驱动器,但此页面中描述的磁带支持不可用。
4.
驱动程序将错误消息写入控制台/日志。如果在内核配置中启用了详细的SCSI消息,则写入某些消息中的SENSE代码会自动转换为文本。
5.
驱动程序的内部缓冲允许在固定块模式下实现良好的吞吐量,同时具有较小的read(2)和write(2)字节数。对于直接传输,这是不可能的,并且在转移到2.6内核时可能会引起意外。解决方案是告诉软件使用更大的传输(通常告诉它使用更大的块)。如果无法这样做,则可以禁用直接传输。
日期:2019-08-20 18:01:47 来源:oir作者:oir