Museum

Home

Lab Overview

Retrotechnology Articles

⇒ Online Manual

Media Vault

Software Library

Restoration Projects

Artifacts Sought

Related Articles

close(2)

ioctl(2)

open(2)

read(2)

select(2)

write(2)

intro(7)

st(7)



rmt(7)                         DG/UX R4.11MU05                        rmt(7)


NAME
       rmt - character special magnetic tape interface

SYNOPSIS
       #include <sys/ioctl.h>
       #include <unistd.h>

       ioctl(fildes, command, argument)
       int fildes;
       int command;
       int argument;

DESCRIPTION
       The character special device interface supports flexible file I/O to
       and from a tape in a magnetic tape drive. The interface treats a
       magnetic tape as one or more records of varying lengths.  End-of-file
       (EOF) markers on the tape are considered to be tape records of length
       0. The interface allows you to control the record (block) size and to
       determine the position after each read(2) or write(2) operation.

       The character special commands and arguments for tape files are a
       subset of the ioctl(2) device control commands:

       fildes    is an open file descriptor for a tape drive. See open(2)
                 and st(7), respectively, for I/O options and access
                 pathnames for SCSI tape devices.

       command   specifies the type of I/O control operation to perform.

       argument  where relevant, specifies the action to be performed by
                 command.

   Commands and Arguments
       The valid ioctl(2) commands and arguments for tape files are
       described below.  See "EXAMPLES" for illustrations.

       MTIOCTOP argument
                 Perform the operation indicated by argument. The argument
                 is passed via a pointer to the mtop structure:

                    struct mtop
                      {
                      short     mt_op;
                      short     mt_pad1;
                      daddr_t   mt_count;
                      };

                 The mt_op field contains one of the arguments listed below;
                 the mt_count field, where relevant, specifies the number of
                 times to perform that operation.

                 MTWEOF    Write EOF markers.  Leave the tape positioned
                           after the last-written EOF marker.

                 MTFSF     Space forward the specified number of files (EOF
                           markers). Leave the tape positioned after the
                           last EOF marker.

                 MTBSF     Space backward past the specified number of EOF
                           markers plus 1.  Leave the tape positioned after
                           the last EOF marker (at the beginning of the
                           specified file).  If BOT is encountered, leave
                           the tape at BOT. If the tape is already at BOT
                           when a backspacing operation is initiated, set an
                           I/O status error and leave the tape at BOT.

                 MTFSR     Space forward the specified number of records.
                           If an EOF marker is encountered, terminate and
                           leave the tape positioned after the EOF marker.

                 MTBSR     Space backward the specified number of records.
                           If an EOF marker is encountered, terminate and
                           leave the tape positioned before the EOF marker.
                           If BOT is encountered, leave the tape at BOT.  If
                           the tape is already at BOT when a backspacing
                           operation is initiated, set an I/O status error
                           and leave the tape at BOT.

                 MTREW     Rewind the tape to BOT. The count is ignored for
                           this command.

                 MTOFFL    Rewind the tape and place it off-line.  Some tape
                           controllers do not support placing the tape unit
                           off-line.  For such models, this command is
                           equivalent to MTREW; no error is reported.  The
                           count is ignored for this command.

                 MTEND     Move to the end of the tape.  The implementation
                           of this command is device-specific, and is not
                           supported by all tape devices.  The count is
                           ignored for this command.

                 MTTEN     Tighten (remove slack from) the tape.

                 MTLOAD    Load the tape.

                 MTUNLOAD  Unload (eject) the tape.

                 MTPOSLOAD Move the autoloader (stacker) to the specified
                           slot of the magazine and load the tape.  To eject
                           the magazine specify a negative slot number.

                 MTNOP     This command does nothing.

       MTIOC_MODFM MTIOC_MODFM_NOFM
                 When a tape device that was opened for writing is closed,
                 do not write a file mark unless data was actually written
                 to the device. The MTIOC_MODFM_NOFM argument modifies the
                 default action performed by close(2), which is to write a
                 file mark whether or not data was written to the device.
                 You pass this argument via a pointer to structure mtop,
                 described above.

       MTIOCGET  Get tape drive model and status information. The
                 information is returned via a pointer to the mtget
                 structure:

                    struct      mtget
                      {
                      short     mt_model;
                      short     mt_status1;
                      short     mt_status2;
                      };

                 The mt_model field contains an internal DG/UX model code
                 used by the device driver, which may be interesting to DG
                 Support.

                 The mt_status1 and mt_status2 fields contain zero if the
                 status is OK.  Otherwise they contain extended sense
                 information which is available only until another SCSI
                 command is issued.  The mt_status1 field contains the first
                 16-bit status word from the tape drive.  For st class tape
                 drives, this is the upper four bits of the third byte of
                 SCSI extended sense information.

                 The mt_status2 field contains the second 16-bit status word
                 from the tape drive.  For st class tape drives, this is the
                 SCSI sense key from the extended sense information.

       MTIOC_MEDIA_INFO
                 Get the status of the tapes in a CLARiiON tape array.  The
                 information is returned via a pointer to the mtmedia
                 structure:

                    struct           mtmedia
                      {
                      unsigned int   count;
                      mt_media_id_type    mt_media_id[1];
                      };

                 The count is an input and output field. On input, it
                 specifies the number of mt_media_id structures to return.
                 On output, it contains the number of tape drives installed
                 in the CLARiiON array.  A typical use of this dual
                 input/output role is to call ioctl(2) first with a count of
                 1, in order to find out the number of installed drives in
                 the tape array and to allocate the required memory; then,
                 to get the status of the tapes currently in the array, call
                 ioctl(2) again with the count that was returned by the
                 first call. (See "EXAMPLES" for an illustration of this
                 use.)

                 The mt_media_id field is an array of structures. The size
                 of the array ranges from 1 to the number of tape drives
                 installed in the CLARiiON array. The array size is the
                 input value of count that was in effect prior to the most
                 recent ioctl(2) call, except that this range is imposed.

                 Installed CLARiiON tape drives are numbered left-to-right,
                 beginning with 1 in the left-most position. The structures
                 in mt_media_id correspond to the CLARiiON tape drives in
                 the same order, beginning with the left-most unit.

                 The mt_media_id_type structure is shown and described
                 below:

                    typedef     struct
                      {
                      unsigned long  group_id;
                      short     tape_number;
                      short     tapes_in_set;
                      short     tape_present;
                      short     write_protect;
                      short     parity_control;
                      } mt_media_id_type;

                 group_id      contains a unique identifier for the set of
                               tapes in the array.

                 tape_number   contains the sequence number of the tape in
                               the set.  (e.g. tape 3 of a 4-tape set). This
                               number comes from the CLARiiON drive unit
                               that the tape initially occupied. Thereafter,
                               the tape retains this same tape_number
                               regardless of which CLARiiON drive it
                               occupies.

                 tapes_in_set  contains the number of tapes in the set.

                 tape_present  contains 0 if the unit is empty or 1 if it
                               contains a tape.

                 write_protect contains 0 if the unit contains a write-
                               enabled tape or 1 if the unit is empty or
                               contains a write-protected tape.

                 parity_control
                               contains 0 if parity is turned off or 1 if
                               the tape unit is part of a redundant (parity
                               protected) tape set.

   Default Tape I/O
       Unless you change tape I/O with the ioctl(2) commands and arguments
       described above, tape I/O works as described below.

       An open(2) to a tape device performs the necessary device-dependent
       checks to ensure that a tape is loaded and can be read or written as
       requested.  Only one open may be outstanding on a tape drive at any
       one time; if called on a drive that is already open, open(2) returns
       error EBUSY. If a tape drive cannot be opened because it is off-line
       or not in a ready state, open(2) returns EIO or ENXIO.

       If the last operation to a "rewind-on-close" device was a write, a
       close(2) rewinds to the beginning-of-tape (BOT) marker after writing
       one or two EOF markers: two EOF markers if the tape drive allows data
       (including EOF markers) to be overwritten, one EOF marker if it does
       not.

       A close(2) to a "no-rewind-on-close" tape device spaces forward to
       the next EOF marker and leaves the tape positioned after the marker,
       provided all of the following are true:

        * You opened the device for read-only operation

        * The tape is not positioned immediately after an EOF marker;

        * The previous operation on this tape device was not one of the
          MTIOCTOP ioctl commands (except for MTTEN).

       See the 88open Binary Compatibility Standard for more information.

       If the "no-rewind-on-close" tape device was opened for read-write
       operation, and the last tape operation was a write, one or two EOF
       markers are written, and the tape is left positioned between the EOF
       markers (if two were written) or after the EOF marker (if only one
       was written), as described under write(2) below.  If the last tape
       operation was a read that read an EOF marker, the position of the
       tape is not changed by close.

       A read(2) always reads the next physical tape record and transfers
       the data into the caller's buffer regardless of the current file
       pointer.  If the physical tape record is larger than the caller's
       buffer, the excess data is lost.  If the physical tape record is
       smaller than the caller's buffer, the remaining section of the
       caller's buffer is unmodified.  The number of bytes actually
       transferred into the caller's buffer is returned.  The tape is always
       positioned after the tape record just read, ready to read the next
       record.  If an EOF marker is read, no data is transferred, zero is
       returned as the number of bytes actually transferred, and the tape is
       positioned after the EOF marker.  To read the next record on the
       tape, a tape positioning operation (MTFSF) must be used with a count
       of zero before subsequent read() calls will succeed.


       A write(2) always writes one physical tape record at the current
       position of the tape regardless of the current file pointer unless
       the tape drive does not allow data to be overwritten.  In this case,
       a tape record can only be written at BOT or appended after the End-
       of-Recorded-Media (EORM).  Attempting to write a record at any other
       location on the tape will result in an ENXIO error.  The size of the
       physical tape record is the size of the caller's buffer.  The tape is
       always positioned after the tape record just written, ready to write
       the next record.  Every write operation invalidates all tape records
       that follow it with the effect that a read of such a record will
       return an I/O error.  Following the write, one or two EOF markers are
       implicitly written (and the tape positioned as described in close) if
       the next tape operation is not another write.

       Select(2) always returns READY for both read and write operations.

EXAMPLES
       /* 1 - write file marks only if data is actually written to the tape */

       int arg;
       int fd;

       tape_device = st(cisc(vme(0),0),4,0)n;
       arg = MTIOC_MODFM_NOFM;

       fd = open(tape_device, O_RDWR);

       /* pass a pointer to int, where int =  MTIOC_MODFM_NOFM */
       ioctl(fd, MTIOC_MODFM, &arg);
       ----
       /* 2 - space forward 2 file marks from current location */

       struct    mtop
            {
            short          mt_op;
            short          mt_pad1;
            daddr_t        mt_count;
            };

       int fd;
       struct mtop mt_com;

       mt_com.mt_op = MTFSF;
       mt_com.mt_count = 2;

       /* pass a mtop struct to MTIOCTOP */
       ioctl(fd, MTIOCTOP, &mt_com);
       ----
       /* 3- get tape status info) */
       struct    mtget
            {
            short     mt_model;
            short     mt_status1;
            short     mt_status2;
            };

       int fd;
       struct mtget mt_status;

       /* MTIOCGET fills in an mtget structure */
       ioctl(fd, MTIOCGET, (char *)&mt_status);
       ----
       /* 4- Get the number of drives in a CLARiiON tape array, allocate memory,
             then get the status of the set of tapes currently in the array.
       */

       int fd,st,i;
       int count;
       long size;

       struct mtmedia     media_info;
       struct mtmedia   * media_info_ptr;
       mt_media_id_type * mi_ptr;

       fd = open("/dev/rmt/0", O_RDONLY);

       if (fd != -1)
           {
           /* get only one packet, to find out how many are installed */
           media_info.count = 1;
           st = ioctl(fd, MTIOC_MEDIA_INFO,  &media_info);
           if (st == -1)
               {
               exit(1);
               }

           /* get enough space to hold all the packets */
           count = media_info.count;
           size = sizeof(struct mtmedia) + count * sizeof (* mi_ptr);
           media_info_ptr = (struct mtmedia *)malloc(size);

           media_info_ptr->count = count;

           st = ioctl(fd, MTIOC_MEDIA_INFO, media_info_ptr);
           if (st == -1)
               {
               exit(1);
               }

           printf("COUNT: %d %x0, count, count);
           for (i=0; i<count; i++)
               {
               mi_ptr = &media_info_ptr->mt_media_id[i];
               printf("%d: tape %x of %x; wp:%x tp:%x pc:%x group:%x0, i,
                      mi_ptr->tape_number,
                      mi_ptr->tapes_in_set,
                      mi_ptr->write_protect,
                      mi_ptr->tape_present,
                      mi_ptr->parity_control,
                      mi_ptr->group_id);
               }
           }

FILES
       /dev/rmt/*                Tape device names for character-special
                                 access
       /usr/include/sys/ioctl.h  ioctl definitions

SEE ALSO
       close(2), ioctl(2), open(2), read(2), select(2), write(2), intro(7).
       st(7) for an explanation of driver switches for model 6760/6761 8mm
       magnetic tape drive.


Licensed material--property of copyright holder(s)

Typewritten Software • bear@typewritten.org • Edmonds, WA 98026