Document revision date: 19 July 1999 | |
Previous | Contents | Index |
The buffered I/O byte count quota (BYTELM) specifies the maximum amount of buffer space that can be consumed from system dynamic memory for buffering I/O requests. All buffered I/O requests require system dynamic memory in which the actual I/O operation takes place.
The system manager, or the person who creates the process, establishes
the buffered I/O byte count quota in the user authorization file. If
you use the SYS$SETRWM system service to enable resource wait mode for
the process, the process enters resource wait mode if it attempts to
exceed its direct I/O quota.
11.2.3 Direct I/O Quota
The direct I/O limit quota (DIOLM) specifies the maximum number of concurrent direct (unbuffered) I/O operations that a process can have active. In a direct I/O operation, data is moved directly to or from the user buffer. Direct I/O is used for disk, magnetic tape, most direct memory access (DMA) real-time devices, and nonnetwork transfers, such as DMC11/DMR11 write transfers. For direct I/O, the user's buffer must be locked in memory during the transfer.
The system manager, or the person who creates the process, establishes
the direct I/O quota value in the user authorization file. If you use
the SYS$SETRWM system service to enable resource wait mode for the
process, the process enters resource wait mode if it attempts to exceed
its direct I/O quota.
11.2.4 AST Quota
The AST quota specifies the maximum number of outstanding asynchronous
system traps that a process can have. The system manager, or the person
who creates the process, establishes the quota value in the user
authorization file. There is never an implied wait for that resource.
11.2.5 Physical I/O Privilege
Physical I/O privilege (PHY_IO) allows a process to perform physical
I/O operations on a device. Physical I/O privilege also allows a
process to perform logical I/O operations on a device.
11.2.6 Logical I/O Privilege
Logical I/O privilege (LOG_IO) allows a process to perform logical I/O
operations on a device. A process can also perform physical operations
on a device if the process has logical I/O privilege, the volume is
mounted foreign, and the volume
protection mask allows access to the device. (A foreign volume is one
volume that contains no standard file structure understood by any of
the operating system software.) See Section 11.3.2 for further
information about logical I/O privilege.
11.2.7 Mount Privilege
Mount privilege (MOUNT) allows a process to use the IO$_MOUNT function
to perform mount operations on disk and magnetic tape devices. The
IO$_MOUNT function is used in ancillary control processs (ACP)
interface operations.
11.2.8 Share Privilege
Share privilege (SHARE) allows a process to use the SYS$ASSIGN system service to override another process's exclusive access request on the specified device.
Performing any I/O operations to a device driver coded to expect exclusive access---performing I/O to any device driver not explicitly coded to expect shared multiple-process access---can result in unusual and unexpected device and application behaviour, and can result in problems of device ownership, and failures during the device driver last channel deassign operation.
Using SHARE to override access is useful for a few specific situations,
such as user-written device driver debugging and user-written device
driver diagnostic tools. General use of SHARE is not recommended.
11.2.9 Volume Protection
Volume protection protects the integrity of mailboxes and both foreign and Files-11 On-Disk Structure Level 2 structured volumes. Volume protection for a foreign volume is established when the volume is mounted. Volume protection for a Files-11 structured volume is established when the volume is initialized. (If the process mounting the volume has the override volume protection privilege, VOLPRO, protection can be overridden when the volume is mounted.)
The SYS$CREMBX system service protection mask argument establishes mailbox protection.
Set Protection QIO requests allow you to set volume protection on a mailbox. You must either be the owner of the mailbox or have the BYPASS privilege.
Protection for structured volumes and mailboxes is provided by a volume protection mask that contains four 4-bit fields. These fields correspond to the four classes of user permitted to access the volume. (User classes are based on the volume owner's UIC.)
The 4-bit fields are interpreted differently for volumes that are mounted as structured (that is, volumes serviced by an ACP), volumes that are mounted as foreign, and mailboxes (both temporary and permanent).
Figure 11-1 shows the 4-bit protection fields for mailboxes. Usually, volume protection is meaningful only for read and write operations.
Figure 11-1 Mailbox Protection Fields
Device protection protects the allocation of nonshareable devices, such as terminals and card readers.
Protection is provided by a device protection mask similar to that of volume protection. The difference is that only the bit corresponding to read access is checked, and that bit determines whether the process can allocate or assign a channel to the device.
You establish device protection with the DCL command SET
PROTECTION/DEVICE. This command sets both the protection mask and the
device owner UIC.
11.2.11 System Privilege
System UIC privilege (SYSPRV) allows a process to be eligible for the
volume or device protection specified for the system protection class,
even if the process does not have a UIC in one of the system groups.
11.2.12 Bypass Privilege
Bypass privilege (BYPASS) allows a process to bypass volume and device
protection completely.
11.3 Physical, Logical, and Virtual I/O
I/O data transfers can occur in any one of three device addressing
modes: physical, logical, or virtual. Any process with device access
allowed by the volume protection mask can perform logical I/O on a
device that is mounted foreign; physical I/O requires privileges.
Virtual I/O does not require privileges; however, intervention by an
ACP to control user access might be necessary if the device is under
ACP control. (ACP functions are described in the OpenVMS I/O User's Reference Manual.)
11.3.1 Physical I/O Operations
In physical I/O operations, data is read from and written to the actual, physically addressable units accepted by the hardware (for example, sectors on a disk or binary characters on a terminal in the PASSALL mode). This mode allows direct access to all device-level I/O operations.
Physical I/O requires that one of the following conditions be met:
If neither of these conditions is met, the physical I/O operation is rejected by the SYS$QIO system service, which returns a condition value of SS$_NOPRIV (no privilege). Figure 11-2 illustrates the physical I/O access checks in greater detail.
The inhibit error-logging function modifier (IO$M_INHERLOG) can be
specified for all physical I/O functions. The IO$M_INHERLOG function
modifier inhibits the logging of any error that occurs during the I/O
operation.
11.3.2 Logical I/O Operations
In logical I/O operations, data is read from and written to logically addressable units of the device. Logical operations can be performed on both block-addressable and record-oriented devices. For block-addressable devices (such as disks), the addressable units are 512-byte blocks. They are numbered from 0 to n -1 , where n is the number of blocks on the device. For record-oriented or non-block-structured devices (such as terminals), logical addressable units are not pertinent and are ignored. Logical I/O requires that one of the following conditions be met:
If none of these conditions is met, the logical I/O operation is
rejected by the SYS$QIO system service, which returns a condition value
of SS$_NOPRIV (no privilege). Figure 11-3 illustrates the logical I/O
access checks in greater detail.
11.3.3 Virtual I/O Operations
You can perform virtual I/O operations on both record-oriented (non-file-structured) and block-addressable (file-structured) devices. For record-oriented devices (such as terminals), the virtual function is the same as a logical function; the virtual addressable units of the devices are ignored.
For block-addressable devices (such as disks), data is read from and written to open files. The addressable units in the file are 512-byte blocks. They are numbered starting at 1 and are relative to a file rather than to a device. Block-addressable devices must be mounted and structured and must contain a file that was previously accessed on the I/O channel.
Virtual I/O operations also require that the volume protection mask allow access to the device (a process having either physical or logical I/O privilege can override the volume protection mask). If these conditions are not met, the virtual I/O operation is rejected by the QIO system service, which returns one of the following condition values:
Condition Value | Meaning |
---|---|
SS$_NOPRIV | No privilege |
SS$_DEVNOTMOUNT | Device not mounted |
SS$_DEVFOREIGN | Volume mounted foreign |
Figure 11-4 shows the relationship of physical, logical, and virtual I/O to the driver.
Figure 11-2 Physical I/O Access Checks
Figure 11-3 Logical I/O Access Checks
Figure 11-4 Physical, Logical, and Virtual I/O
11.4 I/O Function Encoding
I/O functions fall into three groups that correspond to the three I/O
device addressing modes (physical, logical, and virtual) described in
Section 11.3. Depending on the device to which it is directed, an I/O
function can be expressed in one, two, or all three modes.
I/O functions are described by 16-bit, symbolically expressed values that specify the particular I/O operation to be performed and any optional function modifiers. Figure 11-5 shows the format of the 16-bit function value.
Symbolic names for I/O function codes are defined by the $IODEF macro.
Figure 11-5 I/O Function Format
The low-order 6 bits of the function value are a code that specifies the particular operation to be performed. For example, the code for read logical block is expressed as IO$_READLBLK. Table 11-1 lists the symbolic values for read and write I/O functions in the three transfer modes.
Physical I/O | Logical I/O | Virtual I/O |
---|---|---|
IO$_READPBLK | IO$_READLBLK | IO$_READVBLK |
IO$_WRITEPBLK | IO$_WRITELBLK | IO$_WRITEVBLK |
The set mode I/O function has a symbolic value of IO$_SETMODE.
Function codes are defined for all supported devices. Although some of the function codes (for example, IO$_READVBLK and IO$_WRITEVBLK) are used with several types of devices, most are device dependent; that is, they perform functions specific to particular types of devices. For example, IO$_CREATE is a device-dependent function code; it is used only with file-structured devices such as disks and magnetic tapes. The I/O user's reference documentation provides complete descriptions of the functions and function codes.
You should determine the device class before performing any QIO function, because the requested function might be incompatible with some devices. For example, the SYS$INPUT device could be a terminal, a disk, or some other device. Unless this device is a terminal, an IO$_SETMODE request that enables a Ctrl/C AST is not performed. |
The high-order 10 bits of the function value are function modifiers. These are individual bits that alter the basic operation to be performed. For example, you can specify the function modifier IO$M_NOECHO with the function IO$_READLBLK to a terminal. When used together, the two values are written in VAX MACRO as IO$_READLBLK!IO$M_NOECHO. This causes data typed at the terminal keyboard to be entered into the user buffer but not echoed to the terminal. Figure 11-6 shows the format of function modifiers.
Figure 11-6 Function Modifier Format
There are two device- or function-independent modifier bits:
IO$M_INHRETRY and IO$M_DATACHECK (a third bit is reserved).
IO$M_INHRETRY is used to inhibit all error recovery. If any error
occurs and this modifier bit is specified,
the operation is terminated immediately and a failure status is
returned in the I/O status block (see Section 11.10). Use
IO$M_DATACHECK to compare the data in memory with that on a disk or
magnetic tape.
11.5 Assigning Channels
Before any input or output operation can be performed on a physical device, you must assign a channel to the device to provide a path between the process and the device. The Assign I/O Channel (SYS$ASSIGN) system service establishes this path.
When you write a call to the SYS$ASSIGN service, you must supply the name of the device, which can be a physical device name or a logical name, and the address of a word to receive the channel number. The service returns a channel number, and you use this channel number when you write an input or output request.
For example, the following lines assign an I/O channel to the device TTA2. The channel number is returned in the word at TTCHAN.
#include <descrip.h> #include <lib$routines.h> #include <ssdef.h> #include <starlet.h> #include <stdio.h> #include <stsdef.h> main() { unsigned int status; unsigned short ttchan; $DESCRIPTOR(ttname,"TTA2:"); /* Assign a channel to a device */ status = SYS$ASSIGN( &ttname, /* devnam - device name */ &ttchan, /* chan - channel number */ 0, /* acmode - access mode */ 0, /* mbxnam - logical name for mailbox */ 0 ); /* flags */ if (!$VMS_STATUS_SUCCESS(status)) LIB$SIGNAL(status); return SS$_NORMAL; } |
To assign a channel to the current default input or output device, use the logical name SYS$INPUT or SYS$OUTPUT.
For more details on how SYS$ASSIGN and other I/O services handle
logical names, see Section 11.2.5.
11.5.1 Using the Share Privilege with the SYS$ASSIGN and SYS$DASSGN Services
Use of SHARE privilege should be made only with caution, as applications, application protocols, and device drivers coded to expect only exclusive access can encounter unexpected and potentially errant behaviour when access to the device is unexpectedly shared via use of SHARE privilege.
If you use the SHARE privilege to override the exclusivity requested by another process's call to the system service SYS$ASSIGN, and the original process then attempts to deassign its channels via explicit calls to SYS$DASSGN or via the implicit calls to SYS$DASSGN made during image or process rundown, the OpenVMS last-channel-deassign code may not operate as expected due to the assignment of the additional I/O channels to the device. The presence of these extra channels will prevent the last-channel-deassign code from releasing the ownership of the device, potentially resulting in a device owned by the process identification (PID) of a non-existent process.
Unless its use is explicitly supported by the application, the
application protocol, and the device driver, the use of SHARE privilege
is generally discouraged.
11.6 Queuing I/O Requests
All input and output operations in the operating system are initiated with the Queue I/O Request (SYS$QIO) system service. The SYS$QIO system service permits direct interaction with the system's terminal driver. SYS$QIOs permit some operations that cannot be performed with language I/O statements and RTL routines; calls to SYS$QIO reduce overhead and permit asynchronous I/O operations. However, calls to SYS$QIO are device dependent. The SYS$QIO service queues the request and returns immediately to the caller. While the operating system processes the request, the program that issued the request can continue execution.
The format for SYS$QIO is as follows:
SYS$QIO([efn],chan,func[,iosb][,astadr][,astprm][,p1][,p2][,p3][,p4][,p5][,p6] |
Required arguments to the SYS$QIO service include the channel number assigned to the device on which the I/O is to be performed, and a function code (expressed symbolically) that indicates the specific operation to be performed. Depending on the function code, one to six additional parameters may be required.
For example, the IO$_WRITEVBLK and IO$_READVBLK function codes are device-independent codes used to read and write single records or virtual blocks. These function codes are suitable for simple terminal I/O. They require parameters indicating the address of an input or output buffer and the buffer length. A call to SYS$QIO to write a line to a terminal may look like the following:
#include <starlet.h> unsigned int status, func=IO$_WRITEVBLK; . . . status = SYS$QIO(0, /* efn - event flag */ ttchan, /* chan - channel number */ func, /* func - function modifier */ 0, /* iosb - I/O status block */ 0, /* astadr - AST routine */ 0, /* astprm - AST parameter */ buffadr, /* p1 - output buffer */ buflen); /* p2 - length of message */ |
Function codes are defined for all supported device types, and most of the codes are device dependent; that is, they perform functions specific to a particular device. The $IODEF macro defines symbolic names for these function codes. For information about how to obtain a listing of these symbolic names, see the OpenVMS Programming Interfaces: Calling a System Routine. For details about all function codes and an explanation of the parameters required by each, see the OpenVMS I/O User's Reference Manual.
To read from or write to a terminal with the SYS$QIO or SYS$QIOW system
service, you must first associate the terminal name with an I/O channel
by calling the SYS$ASSIGN system service, then use the assigned channel
in the SYS$QIO or SYS$QIOW system service. To read from SYS$INPUT or
write to SYS$OUTPUT, specify the appropriate logical name as the
terminal name in the SYS$ASSIGN system service. In general, use SYS$QIO
for asynchronous operations, and use SYS$QIOW for all other operations.
11.7 Synchronizing Service Completion
The SYS$QIO system service returns control to the calling program as soon as a request is queued; the status code returned in R0 indicates whether the request was queued successfully. To ensure proper synchronization of the queuing operation with respect to the program, the program must do the following:
Optional arguments to the SYS$QIO service provide techniques for synchronizing I/O completion. There are three methods you can use to test for the completion of an I/O request:
The use of these three techniques is shown in the examples that follow. Example 11-1 shows specifying event flags.
Example 11-1 Event Flags |
---|
#include <lib$routines.h> #include <starlet.h> unsigned int status, efn=0, efn1=1, efn=2; . . . status = SYS$QIO(efn1,...); /* Issue 1st I/O request */ if (!$VMS_STATUS_SUCCESS(status)) LIB$SIGNAL( status ); /* Queued successfully? */ (1) . . . status = SYS$QIO(efn2,...); /* Issue second I/O request */ (2) if (!$VMS_STATUS_SUCCESS(status)) /* Queued successfully? */ LIB$SIGNAL( status ); . . .(3) status = SYS$WFLAND( efn, / *Wait until both are done */ &mask,...(4) . . . |
Previous | Next | Contents | Index |
privacy and legal statement | ||
5841PRO_029.HTML |