Documentation for tape software


Design of the New Tape System

Since the previous implementation of tape software on the Lambda has undergone several years of use and criticism, it has been completely redesigned. The new implementation solves various problems inherent in the previous design of the tape software and provides a substantial improvement in speed, extensibility and functionality.

The basic goal of the new design was user-extensibility. The ability to add support for an arbitrary tape format on any supported tape device with a minimal amount of work has been accomplished by separating the formatting from the data transfer functions into modular parts with a strictly defined interface. The result is two distinct object flavors: basic-tape-format and basic-tape-device. Each has a set of required methods with specified return values used to effect operations. There are several beneficial side effects which stem from this design:

Multi-unit operations

Control locking of the interface hardware for tape devices has been implemented at the device object level. Device locking is not permanent by process, as in the previous implementation, but controlled by user programs and checked at the device-object level. Although, the software must still inherently rely on the competence of the user to guarantee the expected results, this scheme offers much more flexibility. In addition, it allows easier implementation of specialized tape operations like tape-to-tape format translation.

User interface

The strict specification of operations on tape-devices and tape-formats offers a more controlled environment for user programs that wish to use tape storage for more obscure purposes, while allowing automatic storage programs to operate more effectively and need less user assistance.

Abstraction of tape operations

As any flavor object can be created to the specifications of a tape-format or tape-device, non-tape device objects are completely interchangeable. This permits operations like file backup to non-tape devices (such as other file-systems), without the need of specialized code.

Speed of tape devices

For dual-speed devices, the device-object can judge the transport speed that should be used by the amount of data requested, which results in substantial increase in speed for file and band transfer operations.

Disk Partition Transfer

Having tape device objects directly control the transfer of disk blocks to the tape allows the fastest data transfer rates possible since the device object can optimize operations according to the characteristics of the tape hardware.

The first version of the new tape system should be very stable. Yet, as it is not humanly possible to conceive of every eventuality or optimization, feedback from implementors of tape-device or tape-format support under this scheme is essential for improvement of the software. Submissions of software for other standard tape formats not in this release should be sent to LMI to be considered for inclusion in a future release. Similarly, requests for assistance in the implementation of any format are welcome and should be directed to the Customer Service Hotline.

1 The Generic Tape Device

Support for tape devices has been designed to be very modular, complete and easy to use. Devices as flavor objects need to support a relatively small number of operations, which can be performed as efficently (or as complexly), as the device can handle, but whose interface is simple enough to accomodate a variety of higher level formatting software, providing support for various standard tape formats.

This chapter outlines the operations each tape device must support along with the characteristics particular to each operation to ensure the complete modularity of tape devices.

Flavor on Tape: tape basic-tape-device

This is the base flavor upon which all tape devices should be built. It defines no methods or instance variables, it simply requires the necessary methods and instance variables for the definition of the device. Tape devices expected to be used with the general tape software, must be built on this flavor, as it is used as the type specifier by routines in the general tape software to check the validity of tape-device objects. It is defined as an :abstract-flavor.

The values of the following instance variables should be gettable and settable. The latter should only be used within the object’s method definitions, which is assumed to be accurate with respect to the limitations of the parameters. All changes of the parameters from an external source should be made through the :set-options method explained below.

Instance Variable of tape-devices: unit

The current unit selected by the device object.

Instance Variable of tape-devices: density

The selected density of the drive.

These methods provide the interface to the device as specified:

Operation on Tape: tape-devices :initialize &rest init-options

This method is responsible for setting up the device before any of the supported operations can be performed. The initial values of device parameters may be supplied in options.

Operation on Tape: tape-devices :deinitialize &rest init-options

This method is should be invoked before the device is discarded, taking care of any cleanup activities necessary (including unlocking the device if it is currently locked).

Operation on Tape: tape-devices :lock-device

This is method should lock the device so that no other processes or processors can use it when locked. The locking scheme used and its implementation is completely up to the implementor. All that is required is that no other object/process can use the physical device after this operation has been executed, until a :unlock-device operation is executed and terminates. See the section on Device Locking for a discussion on this topic.

Operation on Tape: tape-devices :unlock-device

This method undoes the action of the :lock-device operation.

Operation on Tape: tape-devices :device-locked-p

This should return t if the device is currently locked for this object, or nil if not.

Operation on Tape: tape-devices :set-options &rest options-and-args

options-and-args should be of the form: ("option1 arg1 option2" ...). This should set each of the options to its corresponding argument, checking the validity of the arguments beforehand. If an incorrect option is specified, an error should be signalled. The return value is t if the options were correctly set. If no options are specified, this method may, at the implementor’s wish, pop-up a menu for the device options to change, or otherwise query the user.

Operation on Tape: tape-devices :reset

This operation should reset the physical device associated with the flavor object.

Operation on Tape: tape-devices :status

This should return a list of status descriptors which indicate the state of the device. Each descriptor can be a keyword which implies logical truth of the condition or a list whose car is the keyword and cdr is a list of information about the condition. The supported status descriptors are as follows:

	:write-protected
	:busy
	:off-line
	:on-line
	:physical-end-of-tape
	:load-point
	:end-of-file
	(:error . condition-object)

Operation on Tape: tape-devices :speed-threshold

Since many tape drives have two transport speeds, and the reposition time plays an important factor in the overall performance of the read and write operations, this method has been provided to allow optimization of certain operations by specifying the threshold (in bytes) above which high speed can be used. The operations that currently allow speed specification are the spacing operations and search filemark operations this optimization is :search-filemark and :search-filemark-reverse.

Operation on Tape: tape-devices :rewind &optional (wait-p t)

This should rewind the tape to BOT. If wait-p is non-nil, the method will wait for the tape to reach its load point, then return, otherwise it will return immediately. The return value should be ignored.

Operation on Tape: tape-devices :unload

This unloads the tape and/or puts the device :off-line, depending on the characteristics of the physical tape drive. This method should return immediately, if possible (not waiting for the tape to unload completely.

Operation on Tape: tape-devices :speed-threshold record-size

This should return an integer in 8-bit bytes that determines the threshold after which :high speed should be used for spacing operations. This can return any integer if the speed optimization is meaningless for a particular device.

Operation on Tape: tape-devices :space number-of-records &optional (speed :low)

This should move the tape forward the specified number of records. This operation will space over a filemark on the tape, counting it as a record. The speed argument allows the user to specify how fast the drive spaces over records for drives that are dual speed. Valid values are :high or :low. This allows faster searching of the filemark when it is expected to be far from the current tape position, but the :low speed increses efficency for short files, as tape reposition time increases with transport speed.

Operation on Tape: tape-devices :space-reverse number-of-records &optional (speed :low)

This is the same as space but moves in the reverse direction.

Operation on Tape: tape-devices :search-filemark number-of-sequential-filemarks &optional (speed :low)

This should move forward until the specified number of sequential filemarks have been reached. The tape should be positioned after the last of the filemarks found. Eventually, if the filemarks are not found, a physical-end-of-tape error will be signalled. The :speed argument is like for :Space.

Operation on Tape: tape-devices :search-filemark-reverse number-of-sequential-filemarks &optional (speed :low)

This is just like :search-filemark but in reverse.

Operation on Tape: tape-devices :optimal-chunk-size record-size

This should return the optimal amount of data (in bytes) for read/write array operations for the specified record-size. It must be some multiple of record-size.

Operation on Tape: tape-devices :read-block dma-buffer record-size

This should read one record from the tape into dma-buffer. The number of bytes expected to be in the record on tape is specified as record-size. The return value is the actual number of bytes that were in the record on tape. If this is larger than the specified record size, the dma-buffer will have only been filled up to the requested record size. If it is smaller, the dma-buffer will have only been filled up to the number of bytes in the record on tape. As no error is signalled in either case, the requestor is expected to check the return value against the expected record-size. In general, if the user does not know what the size of the next record will be, a large buffer can be used. Although the overhead increases slightly with a larger block, this is a perfectly safe thing to do. In most cases, the larges block size that can be used is 64k bytes (sometimes less).

Operation on Tape: tape-devices :write-block dma-buffer record-size

This should write one record, record-size bytes long, of data from dma-buffer on the tape.

Operation on Tape: tape-devices :read-array array number-of-records record-size

This should read the specified number of record-size records into array from tape. This method should be able to handle the following array types: art-8b, art-16b, and art-string. Record-size must be an even multiple of 1024. The return value should be ignored.

Operation on Tape: tape-devices :write-array array number-of-records record-size

This is just like :read-array only it writes from the array to tape.

Operation on Tape: tape-devices :read-to-disk disk-unit starting-address number-of-blocks

record-size &key silent

This should transfer the specified number of disk blocks from the tape to the disk starting at starting-address. Care must be used in checking the arguments, as a reference to a non-existent disk address on the Lambda will make the machine crash. Record-size must be an even multiple of 1024. The return values are the number of blocks actually written on disk and an error condition or NIL as in :read-array. disk-unit should be a normal disk unit spec (i.e. local disk unit number or a string "<host> <unit-number>").

Operation on Tape: tape-devices :write-from-disk disk-unit starting-address number-of-blocks

record-size &key silent

This is the similar to :read-to-disk except the direction of data transfer is reversed.

Operation on Tape: tape-devices :write-filemark &optional (number-of-filemarks 1)

Instructs the tape device to write the specified number of filemarks on the tape.

2 Tape Format Objects

Tape Format objects are flavor objects which implement certain generic operations such as writing, restoring and listing files on a tape. Their responsibility is to read, examine or write data to or from the tape device which represents the correct file data (specified by the arguments) in the appropriate format.

Flavor on Tape: basic-tape-format

This is the base flavor upon which all tape format flavors should be built. It defines no method or instance variables, it simply requires the necessary methods and instance variables for the definition of the format. As with tape-devices, all tape formats expected to work with the general tape software must be built on this flavor. It is defined as an :abstract-flavor.

Instance Variable of tape-formats: record-size

This is the size in bytes for each record to be written on the tape, or :variable if this format uses variable-length records.

Instance Variable of tape-formats: file-stream

This holds the stream object that is created if the :open-file method is invoked. This will be explained in detail below.

Operation on Tape: tape-formats :initialize &rest options

This is similar to the operation of the same name on tape devices. It is responsible for setting up the tape format object. options is passed to the :set-options method.

Operation on Tape: tape-formats :set-options &rest options-and-args

As for tape devices, this is responsible for checking and setting parameters for the tape format. If no options are specified, the user should be presented with options to change by means of a pop-up window or something.

Operation on Tape: tape-formats :read-tape-header tape-device

This should return tape header information in the form of a disembodied property list. The car of the list should be the flavor symbol of the format (i.e. LMFL format), the cdr an alternating list of properties and values.

Operation on Tape: tape-formats :write-tape-header plist device

This should take plist and write a proper header according to the specification of the format on device. For safety, it should send the device a :rewind message first.

Operation on Tape: tape-devices :tape-is-your-format-p device

This should check the tape and return t if the tape is of this format, assuming that the tape is already rewound, NIL otherwise.

Operation on Tape: tape-formats :restore-file

device &key transform query (overwrite :always) (create-directory :always) silent Restore a file from the tape.

:transform

If this is a pathname or a string, the components of the pathname of the file on tape are merged into this one. If it is a function, it must take arguments: (in internal lisp machine format)

(device directory name type version)

and return a pathname to which the file will be restored.

:query

If non-nil, the user will be asked for each file whether to restore it.

:overwrite

Decides whether to overwrite an existing non-deleted file with the same pathname (including version). Valid values are: :always :query :never.

:create-directory

Decides whether to create a directory for a file to be restored if the directory does not exist. Valid values are: :always :query :never :error. :never skips over the file, :error will signal a directory-not-found error.

:silent

If non-nil, should not print anything unless a query is in order. Otherwise, this method should print out what file the tape file is being restored to.

Operation on Tape: tape-formats :write-file device file

&key (end-of-tape-action :continue) silent

Writes a file on the tape. device and silent are as usual.

file

This should be a string, pathname or a file property list in the form ("truename" . ("prop value" ...)) as returned by fs:directory-list. If the argument is a file plist, then the properties in the plist are written to tape, otherwise the file properties are derived from the input stream at write time.

end-of-tape-action

What happens when the end of tape is reached during this operation is dependent on this variable.

:continue

This directs the format software to continue to another tape according to the specifications of the format. This may, though, be an error in some cases, since some formats don’t know about multi-tape save-sets.

:error

This means that an error should be signalled according to when the filemark was encountered. The flavor to signal is end-of-tape-writing-header or end-of-tape-writing-file depending on when the end of tape was encountered. These error flavors are documented elsewhere in this manual.

:return

This should cause an appropriate error condition to be returned immediately. (See above).

Operation on Tape: tape-formats :write-partition partition device disk-unit

&key silent number-of-blocks start

Writes a partition to tape. :device and :silent are as usual.

:partition

This should be a complete partition name as a string (i.e. "LOD1")

:disk-unit

This should be a disk unit argument like those passed the general system disk software. To specify a local disk unit, provide an integer. To specify a disk on a remote host, provide a string that looks like "<host-name> <disk-unit-number>". Providing a string form for the local host will still use the remote disk server.

:whole-thing

If this is T, then the whole partition is copied; if it is a number, then that number of blocks is copied; if it is NIL, then only the active blocks in cases of compressed format bands will be copied.

:offset

If this is provided, it must be an integer representing the offset into the partition to start copying from.

Operation on Tape: tape-formats :compare-file device &key transform silent

(error-action :return)

Compares the next file on tape with the source it was dumped from. Transform is treated exactly as for :restore-file, and should provide the pathname of the file to be compared against. If this argument is NIL, then the local host is assumed to be the source. If silent is nil, then this method should print out messages concerning the comparison of the files. If the file compares successfully, then the plist of the file should be returned. If the file gets a compare error, error-action determines the action to take:

:return

Returns an error condition instance of the appropriate error flavor: compare-error, source-not-found, source-file-changed.

:error

Signals an appropriate error condition.

Operation on Tape: tape-formats :beginning-of-file device

This positions the tape to the beginning of the current file. Return value should be ignored. Warning: Be sure that repeated invocations of this method do not space to the previous file.

Operation on Tape: tape-formats :next-file device &optional (number-of-files 1)

Positions the tape at the beginning of the file that is number-of-files away from the current file (i.e. 1 specifies the next file).

Operation on Tape: tape-formats :previous-file number-of-files device

Like :next-file but moves backwards.

Operation on Tape: tape-formats :find-file device match

This operations searches for file on tape. match can be of the following types:

list

Car should a symbol, either or or and, cdr should be a list of valid match arguments. tape-file-match is called on all of elements with the same plist, and the values applied to and or or appropriately to determine the return value.

string or pathname

Uses :pathname-match operation on match pathname.

function, closure, or symbol

Funcall match with plist as the argument.

If the processing of the match argument returns non-nil, then the tape is positioned at the beginning of the matched file, and the file’s plist returned. Otherwise the search continues.

Operation on Tape: tape-format :find-file-reverse match device

This is like :find-file but moves backwards. If the beginning of the tape is reached before a match is found, a physical-beginning-of-tape error should be signalled.

Operation on Tape: tape-formats :open-file device &key (:direction :input) (:byte-size :default) (:characters :default) plist

This function returns a stream according to the arguments which have the same meaning as for open. plist is only meaningful for :output streams, and must be supplied in that case. The file’s properties are copied onto the si:property-list instance variable of the stream, allowing the use of the generic property list functions (get, putprop, plist, etc.). The stream returned is basically exatcly like that returned by FS:MAKE-MT-FILE-STEAM in the old tape software.

Operation on Tape: tape-formats :list-files device &key (stream *standard-output*) (number-of-files -1)

Should print a description of each file on the tape to stream. The listing should stop after number-of-files is reached or the end of tape is encountered, returning a list of the file property lists if the files found. If :stream is NIL, then nothing should be printed.

Operation on Tape: tape-formats :finish-tape device

Marks the logical end of tape on device. For convenience, the tape should be re-adjusted so that any further write operations will not be after the logical end of tape. This operation simply should guarentee that the logical end of tape is represented on the tape.

Operation on Tape: tape-formats :rewind device &optional (wait-p t)

This should cause the tape on device to be rewound. It has the same meaning as for tape-devices, but is provided here since some format objects may need to update some internal information when the tape is rewound.

Operation on Tape: tape-formats :unload device

This should cause the tape on the device specified to be unloaded. This should take the same care of saving the state of the tape format object as the :rewind method.

Operation on Tape: tape-formats :position-to-append device

Position tape so that all subsequent :write-file operations will add the files to the end of tape.

3 Error Handling

The new implementation of the tape software has gone quite out of its way to provide an accurate and consistent system of error condition flavors, to allow reliable catching and handling of various tape errors and states. The following set of flavors should be used in all places where they logically fit. Higher level software will depend on this consistency and will be able to provide more ‘intelligence’ to tape operations rather than dropping through to the error handler at every exception. Errors are subclassified to allow easier intuitive understanding of the condition and also to allow more intelligent user interfaces and automated programs to operate more reliably. Each classification flavor (with the exception of hardware-error and driver-error) is defined as an :abstract-flavor (see the Lisp Machine Manual [flavors]).

This is the base flavor for all tape-related errors; all other error flavors use this one.

Flavor on Tape: tape-error

Abstract flavor for the classification of all tape errors, built on error.

3.1 Hardware Errors

These errors are internal hardware errors that cannot be reasonably handled by other software (fatal hardware errors). Use this for building flavors internal to the drivers for specific devices. It is acceptable to allow these conditions to be passed through to the error handler in the case of a fatal hardware error.

Flavor on Tape: hardware-error

:device-type, :error-code, and :error-message are required instance variables. The :device-type should be a symbol an is primarily for the user to identify the device that has errored if the debugger has been entered. The :error-code driver dependent. The :error-message should be a string which is used to report the error if the debugger is entered.

3.2 Driver Errors

Driver errors are internal errors in the driver software. These should be used within the driver software for signalling conditions only within the driver level. All exceptions that need to be signalled to higher level software, should be converted into a condition of an appropriate flavor (listed below), rather than signalling the internal error condition. Therefore, conventionally, if the debugger is entered because of a driver-error, it should be considered a bug in the driver software and should be reported to the implementor(s) of the driver.

Flavor on Tape: driver-error

:device-type, :error-code, and :error-message are required instance variables.

3.3 Device Errors

Device errors are typical, sometimes expected, errors that the device may encounter, such as the physical end of the tape, device not ready, etc. The following is the base, uninstantiable flavor upon which all other device-error flavors depend.

Flavor on Tape: device-error

Abstrace flavor for classification of device errors.

These are the currently defined device error flavors:

Flavor on Tape: device-unavailable

This error should be signalled when the device is being used by another processor or another process within the same processor. :device-type should be a symbol describing the device (i.e. ’tapemaster). :current-owner should be either an integer or a cons (not a list!). If it is an integer, than it is the NuBus slot number of the processor currently ‘owning’ the device hardware interface. If it is a list, the car of the cons is the device that is currently using the device, the cdr is the process in which the device object is being accessed. The process may not be significant for some locking schemes, and useful in others. The proceed-types defined for this condition are: :steal-device-internally, :steal-device-from-other-processor, :wait-for-device-free.

Flavor on Tape: wait-timeout

This error should be used for all unrecoverable timeout conditions. :device-type, :unit, :seconds-waited, and :wait-string are required instance variables for this flavor. :wait-string should describe the timeout.

Flavor on Tape: bad-tape

This error should be signalled if there is an indication that there is a defect in the tape. :device-type and :unit are required instance variable.

Flavor on Tape: blank-tape

Should be signalled if an attempt to read the tape is made and it is detected as blank by the device. :device-type and :unit is the only required instance variable.

Flavor on Tape: physical-end-of-tape

When the physical end of the tape is detected, this error should be signalled. :device-type is as usual. :unit should be the unit number for the device :data-transferred should be is a signaller dependent value that represents how much of the operation (read/write/space) was carried out before the end of tape was reached. For more detailed information about this, see the documentation for the read and write operations for basic-tape-device. It is important not to confuse this with logical-end-of-tape explained below.

Flavor on Tape: physical-beginning-of-tape

This is exactly like physical-end-of-tape except it is for reverse direction operations (currently only spacing operations). This should NOT be signalled by rewind operations, since the beginning of the tape is expected. :device-type, :unit, and :data-transferred are as for the aforementioned flavor.

Flavor on Tape: filemark-encountered

This should be signalled when a hard filemark on the tape is encountered during a read operation. :device-type, :unit, and :data-transferred are required instance variables.

3.4 Format Errors

Format errors are expected conditions (like logical-end-of-tape) or errors in the format of information on the tape with respect to the specific format standard (a bad file headers, for instance).

Flavor on Tape: format-error

Abstract flavor for the classification of format errors.

Flavor on Tape: bad-tape-header

This should be signalled when the tape header (as specified by the format) is invalid in some way. This is in most cases a fatal error. header is a string provided for debugging so the user can examine it and possibly determine how corrupted the header is. format-type is provided identify the format of the tape.

Flavor on Tape: bad-file-header

This should be signalled when there is an indication that a file header on the tape is invalid. This is usually fatal error, but unfortunately in some cases has to be used to determine the logical end of tape. :format-type, and :header are the required instance variables, as in bad-tape-header.

Flavor on Tape: logical-end-of-tape

This indicates the end of the tape, in file terms. Whether there are more files on the tape is dependent on the format. The format software for each format should be careful to correctly handle cases of repeated attempts to access any more files, if there aren’t any more. :device-object is the only required instance variable and should hold the device object the format detected the logical end of tape on.

Flavor on Tape: end-of-tape-writing-header

This condition is used if a physical-end-of-tape error was signalled by a device while the formatting software was trying to read a file header. This might not always be signalled, since the user may opt to have the format handle the end of tape internally. (See the :write-file operation for tape formats for more information.) :file-plist is the only required instance variable and should hold the property list of the file that was being written. :device is the object which signalled the physical end of tape.

Flavor on Tape: end-of-tape-reading-header

This is just like end-of-tape-reading-header, but signalled during a file read (or compare) operation. :device is the only required instance variable and should hold the device object which signalled the end of tape.

Flavor on Tape: end-of-tape-writing-file

This indicates that the physical end of tape was encountered while writing the file’s data on the tape. :file-plist and :device are as in end-of-tape-writing-header. bytes-transferred indicates how many bytes of the file were transferred before the end of the tape was encountered. Note carefully that bytes-transferred corresponds to the BYTE-SIZE of the file, which may vary but is typically 8 or 16 bits.

Flavor on Tape: end-of-tape-reading-file

This is just like end-of-tape-writing-file but for read or compare operations. :file-plist, :device, and :bytes-transferred are the required instance variables.

Flavor on Tape: compare-error

Indicates that there was an error comparing a tape file and its source. :source-file is the pathname of the source file used to compare, :file-plist is the property list of the file compared.

Flavor on Tape: compare-source-not-found

Indicates that the source for the file to be compared was not found. :source-file is the file it tried to find.

Flavor on Tape: compare-source-changed

Indicates that the attributes of the source file changed in some way since the file was written to tape. :source-plist is a plist of the source file’s properties, :file-plist is that of the file on tape.

3.5 User Errors

User errors are errors that the user can correct and retry, or that the user has precipitated by not following the conventions (not mounting the tape, for instance).

Flavor on Tape: user-error

Abstract flavor for the classification of user errors.

Flavor on Tape: write-protected

This should only be signalled by operations that wish to alter the data on the tape. It obviously indicates that the tape in the driver is write protected. :device-type, and :unit are required instance variables that give the appropriate information as to which drive (if there are more than one) needs attention.

Flavor on Tape: tape-not-ready

This usually means that the tape driver is not online or the tape is not mounted. :device-type, and :unit are the required instance variables.

Flavor on Tape: unknown-format

This indicates that the tape is of a format unknown to the software. This should is signalled by higher level software that checks the tape against all the supported tape formats (using :tape-is-your-format-p) and fails to find appropriate format support. :device, :unit, are as usual. :header-string is provided for debugging.

Flavor on Tape: file-stream-exists

This indicates that a file stream already exists for this particular format object. It should be signalled by the :open-file method for tape formats. For a discussion of why only one stream may be open at a time, see the documentation of the :open-file method for tape formats. Fixing this condition, by closing the existing stream, may not always work as desired, depending on the intelligence of the format software. And since programs that use the open file feature should use WITH-OPEN-STREAM, this error condition should be considered fatal and due to some user mistake, or an internal error in the format software. :format-object holds the format object in which the error occurred. :file-stream is the stream that exists, which is provided for closing. (The file stream is also a ‘gettable’ instance variable of format object.)

Flavor on Tape: no-such-partition

This error is signalled when the user asks to operate on a partition that doesn’t exist. This should be a general system error, but for not will be implemented locally here. :partition is the name of the partition requested. :disk-unit is the drive-number of the disk. :host is the machine whose disk we are talking about.

Flavor on Tape: invalid-option

This should be signalled by the :set-options methods for format and device objects (there is no need for a distinction here). :option is the invalid option that was supplied, value is its corresponding value. :object is the object which rejected the option.

Flavor on Tape: write-in-middle-of-tape

This may be signalled by the formatting software if it is generally unacceptable to start writing data if not in the middle of the tape. (For example: aborting out of a :list-files operation and then using :write-file without rewinding first.) This adds an extra level of protection against lossage due to carelessness, but is by no means required by the format software. :device-object is the only required instance variable.

Flavor on Tape: read-during-write

This is similar to write-in-middle-of-tape but indicated that attempt was made to read data on the tape before the end of tape was written. Again, in some cases with some devices, this is an acceptable thing to do, but in others might simply confuse things and cause the user to re-write the tape. :device-object is the only required instance variable.

Flavor on Tape: not-supported

This can be used when support for a particular format or device is being written. Since the software requires that all documented operations on a device be provided before the object can be used, one can use this to signal an error for operations that have not yet been implemented. Its intended use is for non-distributed or special user implemented format or device support, where it is allowable to have unsupported operations. :device-object is the object which errored, and :operation is the operation in question.

Flavor on Tape: protocol-violation

This indicates that an argument passed by the user or by software did not adhere to the specifications set out by this document. It is the type of error condition that is signalled when you pass an ART-Q array as the array argument to the :write-array operation for tape devices. :format-string is the only required instance variable. :format-args is accepted and defaults to NIL.

3.6 Higher Level Software Errors

For the purpose of classification without exception, the following flavor is defined. It is expected that all layers between but not including the format support and user-interface levels build their error flavors on this flavor. It is not clear exactly how useful this will be in the long run, but for purposes of extensibility it will be included.

Flavor on Tape: higher-level-software-error

Abstract flavor for higher level tape software to build error flavors upon.