Linux
2019-03-06
man-pages-ru
Russian man pages from the Linux Documentation Project
manpages
Manual pages about using a GNU/Linux system
man-pages
Linux kernel and C library user-space interface documentation
ИМЯ
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);
ОПИСАНИЕ
Драйвер st предоставляет интерфейс к различным ленточным накопителям SCSI. В настоящее время драйвер позволяет управлять любыми устройствами "последовательного доступа". Драйвер st использует для устройств старший номер 9.
Операции с магнитной лентой по установке параметров устройства (для суперпользователя):
Для каждого устройства есть восемь младших номеров. Первые пять битов в младших номерах определяют последовательность обнаружения. В ядрах 2.6 первые восемь битов объединяются с первыми пятью битами для создания номера ленты. Младшие номера могут быть сгруппированы в два набора из четырех чисел: основные младшие номера для устройств (n) с автоперемоткой и номера устройств без автоперемотки (n + 128). При открытии устройства с основным младшим номером, будет послана команда REWIND. При открытии с использованием устройства без автоперемотки этого произведено не будет. (Заметим, что использование устройства с автоперемоткой для установки ленты в определённое положение, например, 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 буфер выделялся как один непрерывный блок. Это ограничивало размер блока самым большим непрерывным участком памяти, которое может выделить ядро. Ограничение в настоящее время составляет: 128 Кбайт для 32-битной и 256 Кбайт для 64-битной архитектуры. В новейших ядрах драйвер располагает буфер в нескольких частях, если это необходимо. По умолчанию максимальное число частей — 16. Таким способом можно сделать максимальный размер блока очень большим (2 МБ, если выделяется 16 блоков по 128 Кбайт).
Размер внутреннего буфера драйвера определяется константой при сборке; эта константа может быть изменена при загрузке ядра. Вдобавок к этому, драйвер пытается разместить больший временный буфер во время запуска, если это необходимо. Тем не менее, размещение во время запуска больших блоков памяти может завершиться неудачно, и лучше не полагаться на динамическое размещение буфера в ядре до версии 2.1.121 (это применяется также при загрузке драйвера по требованию с помощью kerneld или kmod).
В драйвере нет специальной поддержки для устройств определённых производителей или моделей. После старта системы параметры ленточного устройства определяются микропрограммой устройства. Для примера, если микропрограмма выбирает режим с блоками одинакового размера, то ленточное устройство использует этот режим. Параметры могут быть изменены вызовами ioctl(2) и действуют до тех пор, пока устройство не закрыто и потом не открыто вновь. Установка параметров влияет на оба устройства (с автоперемоткой и без автоперемотки).
Внутри подгруппы четырёх устройств для каждого могут быть заданы особые параметры. Параметры начинают работать, когда устройство открывается. Для примера, системный администратор может определить одно устройство, которое записывает данные в режиме блоков одинакового размера с задаваемым размером и другое, которое записывает данные в режиме блоков с разным размером (если накопитель поддерживает оба режима).
Драйвер поддерживает ленточные разделы, но только если их поддерживает само устройство. Заметим, что ленточные разделы не имеют ничего общего с разделами диска. Размеченная лента одного носителя может выглядеть как несколько логических лент. Поддержка разделов включается с помощью ioctl(2). Местоположение ленты зафиксировано внутри каждого раздела. При последующих ленточных операциях используется нужный раздел, выбранный с помощью ioctl(2). Переключение раздела выполняется вместе со следующей операцией с лентой во избежании ненужной перемотки. Максимальное число разделов на ленте определяется константой при компиляции (изначально оно равно четырём). Драйвер содержит вызов ioctl(2), который позволяет форматировать ленту с одним или двумя разделами.
Обычно, в системе создаётся устройство /dev/tape в виде жёсткой или символьной ссылки на ленточное устройство по умолчанию.
Начиная с ядра 2.6.2, драйвер экспортирует в каталог sysfs в файл /sys/class/scsi_tape подключённые устройства и некоторые их параметры.
Передача данных
Драйвер поддерживает операции в обоих режимах: с постоянным и переменным размером блоков (только если оба режима поддерживает само устройство). В режиме с постоянным размером блока устройство выполняет запись блоками заданного размера, и размер блока не зависит от количества байтов, которые записываются системными вызовами. В режиме с переменным размером блока один блок ленты записывается при каждом вызове записи, и размер соответствующего блока ленты определяется в соответствии с количеством записываемых байт. Заметим, что блоки ленты не содержат информации о режиме записи: при чтении единственно важной вещью является использование нужных команд, которые принимают размеры блоков ленты.
В режиме с переменным размером блока при чтении количество байтов не совпадает точно с размером блока ленты. Если количество байтов больше, чем в следующем блоке ленты, драйвер возвращает данные, а функция возвращает реальный размер блока. Если размер блока больше, чем количество байтов, то возвращается ошибка.
При чтении в режиме с постоянным размером блока количества байтов может быть произвольным, если включена буферизация, или пропорциональным размеру блока ленты, если буферизация выключена. Ядра версий до 2.1.121, позволяли записывать произвольное количество байтов, если включена буферизация. Во всех других случаях (ядра до 2.1.121 с выключенной буферизацией и новые ядра) количество байтов должно быть пропорциональным размеру блока ленты.
В ядрах 2.6 драйвер пытается использовать прямую пересылку между пользовательским буфером и устройством. Если это невозможно, то используется внутренний буфер драйвера. Причинами отказа от использования прямой пересылки может быть включение неправильного выравнивания пользовательского буфера (по умолчанию 512 байт, но может быть изменено драйвером HBA), одна или более страниц пользовательского буфера недостижима из адаптера SCSI и т. п.
Маркер файла автоматически записывается на ленту, если последней операцией до закрытия была запись.
Когда при чтении обнаруживается маркер файла, происходит следующее. Если при обнаружении маркера есть данные в буфере, то возвращаются данные буфера. Следующее чтение вернёт ноль байтов. Затем вернёт данные из следующего файла. О конце записанных данных будет сообщено возвращением нуля байтов в двух операциях чтения подряд. И, наконец, третье чтение вернёт ошибку.
Вызовы ioctl
Драйвер поддерживает три запроса ioctl(2). Запросы, не опознанные драйвером st, пропускаются в драйвер SCSI. Определения, приведённые далее, взяты из /usr/include/linux/mtio.h:
MTIOCTOP — выполнение операций с лентой
Для этого запроса требуется аргумент с типом (struct mtop *). Не все устройства поддерживает все операции. Драйвер возвращает ошибку EIO, если устройство не выполнило операцию.
/* Структура для MTIOCTOP - операция с маг. лентой */ struct mtop {
short mt_op; /* операции перечислены далее */
int mt_count; /* их количество */ };
short mt_op; /* операции перечислены далее */
int mt_count; /* их количество */ };
Операции с магнитной лентой для обычного использования:
MTBSF | Перемотка ленты на mt_count файловых маркеров назад. |
MTBSFM | Перемотка ленты на mt_count файловых маркеров назад. Перемотка ленты на сторону EOT последнего маркера файла. |
MTBSR | Перемотка ленты на mt_count записей назад (блоков ленты). |
MTBSS | Перемотка ленты на mt_count сборочных маркеров (setmarks) назад. |
MTCOMPRESSION | Включение режима сжатия данных на ленте устройства, если mt_count не равно 0, и отключение сжатия, если mt_count равно 0. Эта команда использует MODE page 15, поддерживаемую многими DAT-устройствами. |
MTEOM | Переход в конец записанных на носителе данных (для добавления файлов). |
MTERASE | Стирание ленты. В ядре 2.6 выполняется быстрое стирание (удаление маркера ленты), если аргумент равен 0. В противном случае выполняется полное стирание. |
MTFSF | Перемотка ленты на mt_count файловых маркеров вперёд. |
MTFSFM | Перемотка ленты на mt_count файловых маркеров вперёд. Перемотка ленты на сторону BOT последнего маркера файла. |
MTFSR | Перемотка ленты на mt_count записей вперёд (блоков ленты). |
MTFSS | Перемотка ленты на mt_count сборочных маркеров вперёд. |
MTLOAD | Выполнение SCSI-команды загрузки. Для некоторых автозагрузчиков HP выполняется особое действие. Если mt_count равно константе MT_ST_HPLOADER_OFFSET плюс некоторое число, то это значение передаётся устройству для управления автозагрузчиком. |
MTLOCK | Блокирование дверцы ленточного устройства. |
MTMKPART | Форматирование ленты на один или два раздела. Если mt_count положительно, то оно определяет размер раздела 1, а раздел 0 займёт остаток ленты. Если mt_count равно 0, то лента форматируется с одним разделом. Для ядра версии 4.6: отрицательное значение mt_count задаёт размер раздела 0, а раздел 1 займёт остаток ленты. Физический порядок разделов зависит от устройства. Эта команда запрещена для устройств, не поддерживающих разделы (смотрите MT_ST_CAN_PARTITIONS далее). |
MTNOP | Нет операции, как побочный эффект — сброс буфера устройства. Операция должна выполняться до чтения состояния с помощью MTIOCGET. |
MTOFFL | Перемотка ленты и отключение устройства. |
MTRESET | Возврат устройства в исходное состояние. |
MTRETEN | Подтягивание ленты. |
MTREW | Перемотка ленты назад. |
MTSEEK | Переход к блоку ленты с номером mt_count. Эта операция требует устройства SCSI-2, поддерживающего команду LOCATE (адрес, определяемый устройством), или 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 или более поздних). Одна операция может присваивать значение только одного пункта из списка выше (логические параметры считаются за одну). | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Нулевое значение старших 4-х битов будет использовано для установки режима буферизации устройства. Режимы буферизации:
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Для контроля записи пороговое значение mt_count должно включать в себя константу MT_ST_WRITE_THRESHOLD побитно сложенную (OR) с счётчиком блоков в первых 28-и битах. Счётчик блоков содержит количество блоков по 1024 байта, а не физических блоков на ленте. Пороговое значение не может превышать размер внутреннего буфера устройства. (см. ОПИСАНИЕ выше). | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Для установки и очистки логических параметров значение mt_count должно включать в себя одну из констант: MT_ST_BOOLEANS, MT_ST_SETBOOLEANS, MT_ST_CLEARBOOLEANS, MT_ST_DEFBOOLEANS или любую их побитно сложенную комбинацию. Используя параметры MT_ST_BOOLEANS можно задать значения соответствующими битами. С помощью параметров MT_ST_SETBOOLEANS можно выборочно установить, а с помощью MT_ST_DEFBOOLEANS — выборочно сбросить некоторые биты. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Параметры по умолчанию для ленточного устройства устанавливаются с помощью MT_ST_DEFBOOLEANS. Неактивное ленточное устройство (например, устройство с младшим номером 32 или 160) активируется когда для него назначаются параметры по умолчанию в первый раз. Активированное устройство наследует параметры, которые не заданы явно, от устройства, активированного при загрузке ОС. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Логические параметры:
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. Если значение равно 0, то бит очистки всегда ноль. Если значение равно 1, то используются данные TapeAlert, определённые в стандарте SCSI-3 (пока не реализовано). Значения 2-17 зарезервированы. Если самые младшие восемь бит >= 18, то используются биты из расширенных данных уточнённого состояния (extended sense data). Биты 9-16 задают маску для выбора бит, которые должны просматриваться, а биты 17-23 задают битовый шаблон поиска. Если битовый шаблон равен 0, то один или более бит в маске указывают на запрос очистки. Если шаблон не равен нулю, то шаблон должен совпадать с байтом уточнённого состояния согласно маске. |
MTIOCGET — получение состояния ленты
Для этого запроса требуется аргумент с типом (struct mtget *).
/* структура для MTIOCGET - команда получения состояния ленты */ struct mtget {
long mt_type;
long mt_resid;
/* следующие регистры зависят от устройства */
long mt_dsreg;
long mt_gstat;
long mt_erreg;
/* следующие два поля используются не всегда */
daddr_t mt_fileno;
daddr_t mt_blkno; };
long mt_type;
long mt_resid;
/* следующие регистры зависят от устройства */
long mt_dsreg;
long mt_gstat;
long mt_erreg;
/* следующие два поля используются не всегда */
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_SHIFT, MT_ST_BLKSIZE_MASK, MT_ST_DENSITY_SHIFT и MT_ST_DENSITY_MASK. | ||
mt_gstat | Содержит общую (независимую от устройства) информацию о состоянии. В заголовочном файле определены макросы для тестирования бит:
|
||
mt_erreg | Содержит счётчик (младшие 16 бит) исправленных ошибок, определяемых с помощью MT_ST_SOFTERR_SHIFT и MT_ST_SOFTERR_MASK. Из-за противоречивости способов сообщения об исправленных ошибках устройствами, часто этот счётчик не ведётся (большинство устройств по умолчанию не сообщают об исправленных ошибках, это можно изменить с помощью SCSI-команды MODE SELECT). | ||
mt_fileno | Содержит текущий номер файла (отсчёт ведётся с 0). Если номер файла неизвестен, то значение равно -1 (например, после MTBSS или MTSEEK). | ||
mt_blkno | Содержит номер блока (отсчёт ведётся с 0) в пределах текущего файла. Если номер блока неизвестен, то значение равно -1 (например, после MTBSF, MTBSS или MTSEEK). |
MTIOCPOS — получение текущей позиции ленты
Для этого запроса требуется аргумент с типом (struct mtpos *). Он возвращает текущий номер блока ленты, который необязательно совпадает со значением mt_blkno, возвращаемым MTIOCGET. Устройство должен быть SCSI-2, чтобы поддерживать команду READ POSITION (адрес, определяемый устройством), или Tandberg-совместимым устройством SCSI-1 (Tandberg, Archive Viper, Wangtek, …).
/* структура для MTIOCPOS - команда получения позиции на ленте */ struct mtpos {
long mt_blkno; /* текущий номер блока */ };
long mt_blkno; /* текущий номер блока */ };
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
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, но лента в устройстве защищена от записи. |
ФАЙЛЫ
/dev/st* | ленточные устройства SCSI с автоперемоткой |
/dev/nst* | ленточные устройства SCSI без автоперемотки |
ЗАМЕЧАНИЯ
1. | При обмене данными между системами в них должен быть согласован физический размер блока ленты. Параметры устройства после загрузки часто не являются теми, которые использует большинство операционных систем, работающих с этими устройствами. Большинство систем используют устройства в режиме с переменным размером блока, если этот режим поддерживается устройством. Это применимо к большинству современных устройств, включая DAT, DLT и т.д. Возможно, целесообразно использовать эти устройства в режиме с переменным размером блока также и в Linux (т.е., используйте MTSETBLK или MTSETDEFBLK при запуске системы для установки необходимого режима), по крайней мере при обмене данными с другими системами. Недостатком этого является довольно большой размер блока ленты, который нужно использовать для работы на приемлемой скорости при передаче данных по шине SCSI. |
2. | Многие программы (например, tar(1)) позволяют пользователю задать размер блока в командной строке. Заметим, что это помогает определить размер физического блока на ленте, но только в режиме с переменным размером блока. |
3. | Для использования ленточных устройств SCSI, базовый драйвер SCSI, драйвер SCSI-адаптера и драйвер ленты SCSI должны быть включены в ядро или загружаться как модули. Если драйвер SCSI-ленты отсутствует, то устройство считается распознанным, но поддержка работы с лентой, описанная здесь, будет недоступна. |
4. | Драйвер записывает сообщения об ошибках в консоль/журнал. Коды SENSE, содержащиеся в некоторых сообщениях, автоматически транслируются в текст, если в ядре включён параметр подробного вывода сообщений SCSI. |
5. | Использование внутреннего буфера драйвера позволяет достичь хорошей пропускной способности в режиме с постоянным размером блока даже с маленьким числом байт в read(2) и write(2). Прямой обмен для этого невозможен и может привести к неожиданностям при переходе на ядро 2.6. В качестве решения предлагается указать ПО использовать больший обмен передачи (часто, указав использовать больший размер блоков). Если это невозможно, то прямой обмен может быть выключен. |
СМОТРИТЕ ТАКЖЕ
mt(1)
Файл drivers/scsi/README.st или Documentation/scsi/st.txt (ядро >= 2.6) из дерева исходного кода ядра Linux содержит самую последнюю информацию о драйвере и его возможностях настройки