1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784
|
.help mtio Aug83 "Magnetic Tape I/O"
.sh
1. Introduction
This document describes the Magnetic Tape I/O (MTIO) package,
i.e., the interface by which IRAF programs access magnetic tapes.
Included are the requirements and specifications for the package,
and a discussion of the interface between MTIO and FIO.
.sh
2. MTIO Requirements
.ls 4
.ls (1)
The machine independent part of the MTIO package shall be written in
the SPP language in compliance with the standards and conventions of IRAF.
.le
.ls (2)
The MTIO package shall provide a single interface to all magtape
devices on all IRAF target machines.
.le
.ls (3)
MTIO shall interface to FIO, making it possible to read and write a magtape
file via the FIO interface in a device independent fashion.
.le
.ls (4)
All functions shall take an error action if a hardware error occurs,
or if an illegal function is requested.
No hardware exception or trap shall occur while accessing a magtape
file via MTIO which is not caught by MTIO and converted into an
IRAF error action.
.le
.ls (5)
All error actions shall be defined symbolically in the system error
code file <syserr.h>. The MTIO error messages shall have the
form SYS_MT<function>, i.e., SYS_MTOPEN. The error message strings
shall be placed in the system error message file, "syserrmsg".
.le
.ls (6)
The MTIO code shall be divided into a machine independent part and
a machine dependent part. All machine independent function and error
checking shall be done in the machine independent part, to minimize
the size and complexity of the machine dependent part, and therefore
maximize the transportability of the package.
.le
.ls (7)
MTIO shall interface to FIO by implementing the standard FIO binary file
z-routines ZOPNMT, ZCLSMT, ZARDMT, ZAWRMT, ZAWTMT, and ZSTTMT.
The specifications for these routines are given elsewhere.
.le
.sh
3. MTIO Specifications
A magtape file is opened with MTOPEN and then accessed as a binary
file via the device independent FIO interface. Upon input, FIO merges
all tape records together into a binary byte stream. Upon output,
FIO writes records equal in size to the FIO buffers, unless FLUSH or
CLOSE is called, causing a partially filled buffer to be flushed to tape.
The data within a tape file may not be randomly accessed; only sequential
accesses are permitted. When i/o is complete, CLOSE should be called
to close the file and return all buffer space.
fd = mtopen (filename, access_mode, buf_size)
The format of a nonblank magnetic tape consists of beginning-of-tape (BOT),
followed by zero or more files, followed by end-of-tape (EOT).
Each file consists of one or more records, followed by a tape mark (EOF).
EOT is defined as two consecutive tape marks, i.e., as a file containing
zero records. MTIO knows nothing about labeled tapes.
Tape records need not all be the same length, but for transportability
reasons records should be an integral number of computer words in length,
and very short records should be avoided (short records are used by some
operating systems for special purposes). The term "computer word"
is not well defined; the size of a tape record in bytes should be evenly
divisible by 2, 4, or 8, where the transportability increases with the
size of the divisor. To avoid loss of data when reading a tape,
the FIO buffer must be at least as large as the longest record on the tape.
.sh
3.1 Opening a Magtape
MTOPEN opens a file on the named magtape device. The following
device naming convention determines the tape drive and density:
mt[a-z][800|1600|6250]
The letter in the second field determines which drive is to be used,
and the third field, which is optional, determines the density.
If the density is not specified, a system or drive dependent default
density will be selected. Thus, to access a file on drive A at 1600 bpi,
one would open the file "mta1600".
The significance of the terms "drive A", "drive B", etc., is installation
dependent, and need not imply distinct physical drives. A tape drive may
have to be allocated before it can be opened by MTIO; MTIO does not attempt
to allocate devices.
The device name may optionally be followed by a subscript specifying
the index of the file to which the tape is to be positioned.
Thus, opening "mta[3]" causes device A to be opened with the default
density, positioned to BOF of the third file on the tape.
The field N, as in "mta[N]" may have the following values:
.ls 4
.ls 12 absent
If the entire subscript is absent, or if N is absent the tape is opened
at the current position, i.e., the tape is not physically moved.
.le
.ls N >= 1
If an integer number greater than or equal to 1 (one) is given,
the tape is opened positioned to that file.
.le
.ls N == EOT
If the file number is given as "EOT" or as "eot", the tape is opened
positioned at EOT.
.le
.le
If called with a non "mt"-prefixed file name, MTOPEN assumes that the file
is a regular disk resident binary file, and attempts to open the named
file. A program which normally reads directly from a magtape device may
therefore be used to read from a regular binary file, or from the
standard input (the special file "STDIN").
The following access modes are recognized by MTOPEN:
.ls 4
.ls 12 READ_ONLY
The device is opened for reading, positioned to the beginning of
a file, BOT, EOT, or to the "current position".
Any attempt to write to the device will cause an error.
.le
.ls WRITE_ONLY
The device is opened for writing, positioned to the beginning of a file,
BOT, EOT, or to the "current position". When the file is subsequently
closed, a new EOT mark will be written. Existing tape files may be overwritten.
.le
.ls APPEND
The device is opened for writing, positioned at the end of tape (EOT).
Append mode must not be used with blank tapes. Note that the significance
of APPEND mode is different for MTOPEN than for a regular file open;
the tape is to be extended by adding a new file, whereas in FIO it is
the file itself which is extended.
.le
.ls NEW_TAPE
The device is opened for writing, positioned at BOT. Any existing
data on the tape is overwritten. Recommended mode for blank tapes.
.le
.le
FIO can read any tape with a maximum record size less than or equal
to the buffer size. In buffered mode, FIO normally writes records equal
in size to the FIO internal buffers. Smaller records may be written if
FLUSH or CLOSE is called; records of any size may be written in unbuffered
mode.
The third argument to MTOPEN is used to set the FIO buffer size.
If the buffer size is given as zero, a default value is used.
The default value chosen depends on the mode of access and upon the
maximum record size permitted by the host system. MTOPEN will automatically
allocate the maximum size FIO buffer if the tape is opened for reading.
The FIO buffer size may be changed in an FSET call anytime before
the first buffered i/o on the file.
.sh
3.2 Ordinary I/O to a Magtape Device
Seeks are not permitted on magtape files. A tape may be opened for
reading or for writing, but not for both at the same time. A magtape
device is much like the standard input and output; STDIN is read only,
STDOUT is write only, and seeking is not permitted on either. STDIN
differs from ordinary files in that data may continue to be read after
an EOF; the same is true of magtape files. If a read returning EOF is
followed by another read on a magtape device, the second read will
access the first record of the next file. Once EOT is reached, every
read will return EOF. There is no way to advance beyond EOT on a read.
An EOF mark may only be written by closing the tape (see next section).
.sh
3.3 Closing a Magtape
The CLOSE function is called either explicitly by the user task,
or implicilty by the IRAF main upon normal or abnormal task termination.
If the file was opened for writing, CLOSE flushes the output buffer and
writes an EOT mark at the current position. A file opened for writing
is left positioned ready to write the first record of the next file on
the tape (i.e., after the EOF of the file just written). A file opened
for reading, if closed immediately after reading EOF, is left positioned
ready to read or write the first record of the next file on the tape.
.sh
3.4 Bytes and Records
Upon input, the size of a record will be rounded up to an integral
number of "chars". No data will be lost, but one or more extra bytes of
data may be added. A tape conversion program which must deal with
odd-sized records must know the size of tape records to properly extract
the data. FIO cannot write odd-sized records.
The binary i/o routines do not transform the data in any way,
including byte swapping. If byte swapping is necessary, the conversion
program must do the byte swapping explicitly. The predefined machine
constants BYTE_SWAP and WORD_SWAP indicate whether byte or word swapping
is necessary on the local machine (word swapping refers to the two 16 bit
words in a long integer). Floating point data should not be stored in
binary on tape, unless the tape is to be read only by the machine which
wrote it.
Routines are available elsewhere in the PI for manipulating bytes.
The routines BYTMOV, BYTSWP, and BYTPAK are particularly useful for cracking
foreign tapes.
.sh
3.5 Low level I/O to a Magtape
The asynchronous, unbuffered FIO routines AREAD, AWRITE, and AWAIT
may be used to perform record i/o on a magtape. A single tape record
is read or written by each call; the FIO buffer is not used. AWAIT must
be called after each read or write, before initiating the next i/o transfer.
Although in general it is unwise to mix buffered and unbuffered i/o on
the same file, it is safe to perform one or more unbuffered transfers
immediately after opening a file, before performing any buffered i/o.
If an application must do something peculiar, like write an odd-sized
record, the MTIO z-routines may be called directly. The z-routines transfer
data in units of machine bytes.
.sh
3.6 CL level tape commands
The four routines ALLOCATE, DEALLOCATE, REWIND and MTSTATUS will be
available at the CL level. A tape drive ("mta", "mtb", etc.) must be
explicitly allocated before it can be accessed with MTOPEN.
A drive may be allocated to only one user at a time. MTIO keeps track
of the position of an allocated tape; once a drive has been allocated,
the tape must not be manually positioned by the user. Tapes can be
changed without reallocating the drive provided REWIND is first used to
rewind the tape. DEALLOCATE automatically rewinds the tape before
deallocating the drive. MTSTATUS tells whether or not a particular drive
has been allocated, and if so, gives the name of the owner, the density,
whether not the device is physically open, and so on.
.sh
3.6 Example
The following program reads an ASCII card image file from the
input tape and converts it to an ordinary text stream, which is written
to the standard output. This program is insensitive to the number of
cards per tape record, and may be used to read card image disk files
as well as tape files.
The following CL commands might be entered to read the second card image
file on the 800 bpi input tape into file "myfile", converting to lower case:
.ks
.nf
cl> allocate mta
cl> rcardimage "mta800[2]" | lcase > myfile
.fi
.ke
The source for the program "rcardimage" follows:
.ks
.nf
# RCARDIMAGE -- CL callable task which reads a card image
# file, writing the converted cards to the standard output.
procedure rcardimage()
char filename[SZ_FNAME]
int input, mtopen()
begin
call clgstr ("filename", filename, SZ_FNAME)
input = mtopen (filename, READ_ONLY, 0)
call read_card_image_file (input, STDOUT)
call close (input)
end
.fi
.ke
.ks
.nf
define SZ_CARD 80
# READ_CARD_IMAGE_FILE -- Read the named card image file, convert
# to a regular character stream, and write to the output file.
procedure read_card_image_file (input, output)
int input, output # input, output files
char cardbuf[SZ_CARD] # raw card
char linebuf[SZ_CARD+1] # add 1 char for newline
int last_char
int read()
errchk read, putline
begin
# Read successive cards until EOF is reached. Unpack the
# card, strip trailing whitespace, and write the processed
# line to the output file.
while (read (input, cardbuf, SZ_CARD) != EOF) {
call chrupk (cardbuf, 1, linebuf, 1, SZ_CARD)
# Strip trailing whitespace, add newline.
last_char = 0
for (ip=1; ip <= SZ_CARD; ip=ip+1)
if (! IS_WHITE (linebuf[ip]))
last_char = ip
linebuf[last_char+1] = '\n'
linebuf[last_char+2] = EOS
call putline (output, linebuf)
}
end
.fi
.ke
.endhelp
.helpsys mtio Nov83 "MTIO Interface Detailed Design"
.sh
Strategies for Interfacing MTIO
The specifications for MTIO have been kept as simple as possible for maximum
machine independence. There is only one high level call, MTOPEN, which is
used to open the device; it does little more than call FIO. Thereafter
everything is done through the six FIO z-routines:
.nf
zopnmt (filespec, access_mode; channel|ERR)
zclsmt (channel)
zardmt (channel, buffer, maxbytes, one_indexed_byte_offset)
zawrmt (channel, buffer, nbytes, one_indexed_byte_offset)
zawtmt (channel; nbytes|ERR)
zsttmt (channel, parameter; long_value)
.fi
These z-routines may be written in any language so long as they are SPP (i.e.,
Fortran) callable. The "filespec" argument is a packed string. The access
modes and ERR code are system constants defined in <iraf.h>. Channel may be
anything you wish. The file offsets will always be zero since the magtape
device is a streaming (sequential) device.
Be sure that the z-routines, if written partially in the SPP language, do not
make calls to high level program interface routines, especially any which do
i/o. Doing so violates the reentrancy restrictions of the SPP language (and
of Fortran). It may also lead to problems with the way libraries are searched.
More explicitly, any calls to error or iferr, to any of the FIO routines, or to
any of the printf or scan routines are absolutely forbidden. It is ok to use
the string primitives (because they do not do any i/o or call error), but it
is best to avoid even those if possible. It is perfectly all right to call
other z-routines provided they do not directly or indirectly call you back
(none will call mtio).
.sh
Virtual Device Model
Though in general the z-routines may have to be completely rewritten for
a new OS, in fact many systems have functionally similar primitive magtape
interfaces. If your system can be described by the model defined below,
the "z?*.x" files in this directory can be used unchanged, and all you need to
provide are the equivalents of the "zz" prefixed files.
Basically, the model requires that the zz-routine which opens the magtape
be capable of positioning the tape to the first record of any file, given the
file number to which the tape is positioned at open time. The high level MTIO
interface code is charged with keeping track of the position of the tape at
all times, including while the tape is closed. The high level code does not
explicitly move the tape, though it does implicitly move it during open and when
it commands an i/o operation. The high level code assumes nothing about tape
motions; all zz-primitives return status values stating how many records or
files the tape moved in the last operation. Thus, the details of the function
of a zz-routine can vary depending on the system, without requiring
modifications to the z-routines.
.ls 4
.ls (1)
The following open/close primitives are required. ZZOPMT opens a tape
drive positioned ready to read or write the first record of the specified
file.
.ls zzopmt (drive,density,acmode, oldrec,oldfile; newfile; oschan|ERR)
.br
.ls 10 drive
Logical drive number (1,2,3,...).
.le
.ls density
Drive density. A positive integer, i.e., 800, 1600 or 6250. A value
of zero implies that an OS default density is to be selected.
.le
.ls acmode
Access mode. Read_only or write_only. Modes new_file and append are
dealt with by the "newfile" file number parameter.
.le
.ls oldrecord
The number of the record to which we are currently positioned in the
oldfile. We have to know this to know whether or not the file has to
be rewound. The first record is number one.
.le
.ls oldfile
The number of the file to which the tape is currently positioned.
.le
.ls newfile
The number of the file to be opened, where 1 specifies that the tape is
to be rewound. If newfile <= 0, open at EOT. On output, contains the
actual file number of the new file; this may differ from the requested
value if EOT is encountered. It is not an error (as far as the zz-routine
is concerned) to attempt to position to a file beyond EOT.
.le
.ls oschan
The channel number by which the file is to be referred in calls to the
other zz-routines, or ERR if the file cannot be opened. ZZOPMT should
set oschan IMMEDIATELY AFTER PHYSICALLY OPENING THE DEVICE, so that the
error recovery code can close the file if an interrupt occurs.
.le
.le
.ls 4 zzclmt (oschan, access_mode; nfile)
Close tape. Write a new EOT at the current position if writing.
Returns the file number increment (in the event that a file mark or two
has to be written).
.le
.le
.ls (2)
The following i/o primitives are required.
.ls zzrdmt (oschan, buf, maxbytes)
Initiate a read of up to maxbytes bytes from the next tape
record into buffer buf. It is not an error if fewer than "maxbytes"
bytes are read; in fact maxbytes will normally be larger than the largest
record on the tape. In general it is difficult to tell if the tape record
was larger than maxbytes; the user code should select a large maxbytes and
consider it an error if the full maxbytes are read. If EOF is encountered,
return a zero byte count in the next call to zzwtmt.
.le
.ls zzwrmt (oschan, buf, nbytes)
Initiate a write of "nbytes" bytes to the tape. It is an error
if all data is not written.
.le
.ls zzwtmt (oschan; nbytes|ERR, nrecord, nfile)
Wait for i/o to complete, and return the number of bytes read or
written in the last transfer; return 0 if we read a tape mark.
Keep returning the same thing in redundant calls. If an error
occurs the error status should be cleared when the next i/o
transfer is initiated. Return nrecord=1 for each tape record read,
but not for file marks. Return nfile=1 if a filemark is skipped.
A read of 0 bytes signifies that EOF was seen, but does not necessarily
imply that a tape mark has been skipped.
.le
.le
.le
.sh
Program Structure
The drive must be allocated before MTOPEN is called; MTOPEN verifies
that the drive has been allocated and then calls FIO to install the magtape
device and open the desired file on the drive. Allocating a file involves
a call to the OS to allocate and/or mount the device, followed by creation
of the device lock file in the dev$ directory. The lock file is used to
indicate that the drive has been allocated, and to keep track of the tape
position when the drive is closed.
.ks
.nf
mtopen
mt_parse_filespec
mt_get_tape_position
various FIO routines
fopnbf
zopnmt
zzopmt
zsttmt
fset [to set buffer size]
Structure of the MTOPEN Procedure
.fi
.ke
The ZCLSMT procedure is called by CLOSE to close a file opened with MTOPEN.
CLOSE may be called by the user, by the IRAF main if the task completes w/o
closing the file, or during error recovery. An error occurring during MTOPEN
may result in a call to CLOSE. We do not have to worry about reentrancy here
because none of the MTIO z-routines called by ZOPNMT call error (they will
return an ERR status to FOPNBF and therefore terminate before ZCLSMT is called).
.ks
.nf
close
zclsmt
mt_update_lockfile
smark,salloc,sfree
fvfn_to_osfn
mktemp
zopntx
zputtx
zclstx
zfdele
zfrnam
fatal
zzclmt
Structure of the ZCLSMT procedure
.fi
.ke
The i/o procedures keep track of the number of records read or written and
ensure that we do not read past EOF or EOT. We need to keep track of the
number of records written so that we can detect a null file write.
.ks
.nf
aread awrite
zardmt zawrmt
zzrdmt zzwrmt
await
zawtmt
zzwtmt
Structure of the I/O Procedures
.fi
.ke
The final routine is the ZSTTMT status procedure. This routine is self
contained, except that access to the MTIO common is required to get the
access mode (which determines the default buffer size).
.sh
Semicode
We do as much of the work in MTOPEN as we can, since it is the only
high level, machine independent routine we have (we can call anything in this
routine without reentrancy problems). We check that the drive has been
allocated (to us), allocate an mtio device descriptor, check that the same
drive has not been reopened, parse the filespec and save the pieces in the
descriptor (for later use by ZOPNMT), read in the current tape position from
the lock file, and then call fopnbf which in turn calls ZOPNMT to open the
drive and position to the desired file.
.tp 8
.nf
int procedure mtopen (filespec, access_mode, bufsize)
begin
if (file not mt-prefixed) {
call open to open regular binary file
return (file descriptor returned by open)
}
get mtio device descriptor slot but do not allocate it yet
if (slots all taken)
error: magtape device multiply opened (filespec)
call mt_parse_filespec to break out drivename, density,
filenumber and set up mtio device descriptor
if (drive is already open)
error: magtape device multiply opened (filespec)
check that the named drive has been allocated to us
if (drive not allocated to us)
error: magtape not allocated (filespec)
decode lock file to get old position of drive, save in
device descriptor
call fopnbf to install the magtape device and open file
if (bufsize is nonzero)
call fset to set non-default FIO buffer size
return (file descriptor)
end
.fi
ZOPNMT is passed a mostly initialized magtape file descriptor in the mtio
common by MTOPEN. The "filespec" string is not actually used by ZOPNMT.
We physically open the file and set up the remaining fields in the tape file
descriptor. NOTE: if an interrupt occurs during the call to ZZOPMT,
ZCLSMT will be called to perform error recovery. If this happens the
position of the tape is undefined.
.ks
.nf
procedure zopnmt (filespec, access_mode; chan|ERR)
[we are passed the mtio file descriptor in the mtio common]
begin
set flag for ZCLSMT in case we are interrupted
call ZZOPMT to open tape positioned to the beginning of the
indicated file.
if (cannot open tape)
return (chan = ERR)
if (actual file < requested file)
if (reading)
set at-eof flag and at_eot flag, so that reads return EOF
else {
call zzclmt to close device
return (mtchan = ERR)
}
save oschan in descriptor
save actual file number in descriptor
initialize the remaining descriptor fields
return (chan = mtio descriptor index)
end
.fi
.ke
Opening a file for writing and then immediately closing it poses problems.
There is no way to write a zero-length file on an unlabeled tape. We cannot
just write a tape mark because that might mean writing a spurious double
tapemark (false EOT) in the middle of the tape. We could just ignore the
request and not write any file, but that is not quite right either (if a
disk file is opened for writing and then immediately closed, a file is
still created). We compromise by writing a single short record containing
the packed ASCII character string "NULLFILE". The actual length of the
physical nullfile record is machine dependent.
We may or may not need to bump the file counter when the file is closed;
the OS tells us which. If we have just written a file and ZZCLMT must
write a tape mark, for example, we might be left positioned before EOT,
between the tape marks, or (unlikely) after the tape marks.
If an error (i.e., console interrupt) occurs while the tape is being
positioned by ZZOPMT, we will be called by the error recovery system
with a garbage mtchan argument. We must be able to detect this type
of call and modify the lock file, marking the position of the tape
as UNDEFINED. The next open call will then automatically rewind the
tape, ensuring accurate positioning. In a normal close we write out
a lockfile identifying the file and record to which the tape is positioned.
.ks
.nf
procedure zclsmt (mtchan)
begin
if (error recovery in progress for ZOPNMT)
mark current position as undefined
else {
if (file was opened for writing but nothing was written)
write out "null file" short record
call zzclmt (oschan, access_mode; nfiles)
file += nfiles
if (nfiles > 0)
record = 1
}
call mt_update_lockfile to save tape status, position
deallocate the mtio device descriptor slot
end
.fi
.ke
Ignore all read requests once EOF or EOT has been reached. The only operation
possible at that point is to close the device; there is no rewind or backskip
function for a streaming device. We do not "know" what would happen if we
called ZZRDMT after reaching EOF; this is OS dependent, and we do not want
to require any particular behavior (some systems would return the first
record of the next file, others would keep returning EOF).
.ks
.nf
procedure zardmt (mtchan, buf, maxbytes, offset)
begin
if (not at EOF or EOT)
call zzrdmt (oschan, buf, maxbytes)
end
.fi
.ke
We cannot hit EOF or EOT on a write, so merely post the request and return.
Ignore the "offset" parameter since magtape is a streaming device.
.ks
.nf
procedure zawrmt (mtchan, buf, nbytes, offset)
begin
call zzwrmt (oschan, buf, nbytes)
end
.fi
.ke
FIO insures that ZAWTMT is called once and only once after every asynchronous
i/o read or write request. Once we hit EOF or EOT on a read, we return
EOF (nchars = 0) on every subsequent request until the file is closed.
After each real data transfer we update the record,file counters as
directed by the OS.
.ks
.nf
procedure zawtmt (mtchan; status)
begin
if (reading and at EOF or EOT)
return (status = 0)
call zzwtmt (oschan, nchars, nrecords_skipped, nfiles_skipped)
if (nfiles_skipped > 0) {
set at-EOF flag
record = 1
}
file += nfiles_skipped # keep track of position
record += nrecords_skipped
nrecords += nrecords_skipped # count records rd|wr
status = nchars
end
.fi
.ke
.sh
Error Recovery
Error recovery during magtape operations is tricky since we are trying
to keep track of the position of the drive. If an error occurs while the
tape is being positioned by ZZOPMT we must detect the condition and mark the
position of the tape as indefinite (forcing a rewind on the next open).
If an interrupt occurs while positioning to EOT for a write, we do not
want ZZCLMT to write the new EOT mark somewhere in the middle of the tape,
truncating the tape.
Interrupts or other errors while reading or writing are comparatively
harmless. Interrupting a write results in a short but otherwise normal
file on the tape; interrupting a read leaves us positioned to some
arbitrary record within the file (harmless). Conceivably a read
could be interrupted just as we were reading a tape mark, causing the
file position to be lost. We have not protected against this.
.sh
Data Structures
The mtio device descriptor structure describes the status of each magtape
device in use. The maximum number of magtape files which can be open at one
time is the maximum number of tape drives. Only one file can be open on each
drive at a time.
.ks
.nf
struct mtiodes {
int mt_drive # 1,2, etc. (c.t. a,b,...)
int mt_density # 0,800,1600,6250, etc.
int mt_oldfile # file number at open time
int mt_oldrecord # record number at open time
int mt_file # file being accessed (0=EOT)
int mt_record # next record to be accessed
int mt_nrecords # nrecords read/written
int mt_acmode # access mode
int mt_oschan # OS channel number
int mt_ateof # true when at EOF
int mt_ateot # true when at EOT
} mtiocom[MAX_TAPES]
.fi
.ke
When a device is allocated, a lock file is created in the system logical device
directory "dev$". For example, the lock file for magtape unit A is the
file "dev$mta.lok". This is a human readable text file; it is typed out on
the terminal when the user types "devstatus mta". The lock file is updated
when the drive is closed and deleted when the drive is deallocated. The drive
is automatically deallocated when the user logs out of the CL.
.ks
.nf
Sample Lock File:
# Magtape unit 'mta' allocated to 'user' Sun 20:06:13 27-Nov-83
current file = 4
current record = 1
72 records read, EOF seen
.fi
.ke
The preliminary comments are written when the lock file is created, i.e.,
when the device is allocated. Any number of comment lines are permitted.
They are merely copied when ZCLSMT updates the lock file. The remaining
records are written by ZCLSMT to record the current position of the tape,
and to inform the user of the device status.
|