aio(HW)


aio -- pseudo-device driver for asynchronous disk I/O on raw disk partitions

Description

AIO I/O control commands (ioctls) are a subset of ioctl(S) system calls that perform asynchronous I/O operations on raw disk partitions. This allows a program to do other processing while the kernel performs the I/O requests; a later ioctl command polls the status of issued operations. A program may have several disk partitions open, and have multiple AIO requests issued to each partition.

Use of AIO requires disk driver support; all SCO hard disk drivers support AIO. The DKIOCASTAT ioctl can be used to query whether a given open file descriptor supports AIO.

Support for AIO is not present in the default kernel. In order to use AIO, the administrator must first run mkdev aio.

AIO supports the option of locking an area of physical memory for the use of AIO transfers; this can be configured by the UNIX system administrator by using the /usr/lib/aiomemlock file and the aiolkinit(ADM) command. AIO can be performed whether or not such a lock is available.

ioctl commands


DKIOCMLOCK
Signals the intent of the program to perform AIO on the provided file descriptor; this call also locks physical memory if this is permitted for the user. The arg argument to ioctl points to the following structure:
typedef struct	asyncmlock
{
    char  *avaddr;  /* starting user virtual addr */
    uint   asize;    /* size of area to be locked */
} ASYNCMLOCK;
The area of memory spanned by the ASYNCMLOCK structure must already be allocated to the calling program, for example, by a previous call to malloc(S). If asize is 0, or the user does not have AIO memory lock privileges, DKIOCMLOCK does not lock physical memory, but returns without an error. Possession of memory locking privileges by a user does not affect the success or failure of a locking call, but determines whether or not the call does anything.
Similarly, a memory locking length of zero is not an error, but is treated as a no-op.

If the program is doing AIO to multiple partitions, DKIOCMLOCK must be called on each open file descriptor. The DKIOCMLOCK for all calls by one process must refer to the same area of memory, and DKIOCMLOCK should only be called once for each file descriptor. Memory should not be locked more than once for any file descriptor.

On failure, errno is set to one of the following values:


[EAGAIN]
No internal AIO per-process structure could be allocated (too many processes doing AIO).

[EFAULT]
The arg pointer is not within the user's space, or the memory area specified is not within the user's space.

[EINVAL]
DKIOCMLOCK has been called with different ASYNCMLOCK values than a previous call, or AIO is not supported for this file descriptor, or AIO has not been linked into the running kernel.

[ENOMEM]
Not enough memory was available to satisfy the lock request.

DKIOCASTRT
Initiates an AIO request. arg is a pointer to the following structure:
typedef struct  areqbuf {
        long	au_cmd;	
        long	au_daddr;	
        char	*au_maddr;
        long	au_size;
        char	*au_ref;
} AREQBUF;

/* * Command bits */

#define AU_READ 01 #define AU_WRITE 02

au_cmd is set to either AU_READ or AU_WRITE.

au_daddr is the (512-byte) disk block number where the I/O is to start from.

au_maddr is the user's address for I/O.

au_size is the length in bytes of the transfer.

au_ref is a context pointer for the caller's use. It is returned with the status from the I/O request.

The AIO facility imposes restrictions on the I/O request parameters. au_size must be a multiple of 512 (that is, only multiples of 512-byte disk blocks are permitted). au_maddr must be aligned on a 512-byte address boundary. The entire transfer must fit within an MMU page, that is, within a 4KB aligned page in the user's space.
Finally, for a given process doing asynchronous I/O, only one memory range can be locked, and the same range must be specified for all file descriptors; otherwise an error will result.

On failure, aio sets errno to one of the following values (the disk driver itself may set other values on errors).


[EFAULT]
The arg pointer is not within the user's space, or the transfer address is not in the user's space.

[EINVAL]
One of the above alignment restrictions has been violated, or au_cmd is unrecognized, or the user has locked AIO memory and the transfer is not within this locked range, or AIO is not supported for this file descriptor, or AIO has not been linked into the running kernel.

[EAGAIN]
Some AIO resource could not be allocated (for example, too many AIO requests for the system, or for this user).

[ENXIO]
The disk block was beyond the range of the partition.

DKIOCASTAT
Returns information for any completed requests (up to 15) on this file descriptor. If more than 15 requests have been issued on this file descriptor, or if all the requests have not completed, then DKIOCASTAT will need to be called more than once.

DKIOCASTAT also determines whether a particular open file descriptor supports AIO. If AIO is not supported, the ioctl returns -1, and errno is set to EINVAL.

arg is a pointer to an ASYNCSTATUS structure, which is filled in by the ioctl system call:

#define	MAXSTATUS	15

typedef struct asyncstatus { long acount; IOSTAT astatus[MAXSTATUS]; } ASYNCSTATUS;

typedef struct aiostat { short iostatus; short iobsize; char *iomaddr; char *ioref; } IOSTAT;

acount is set to the number of IOSTAT structures actually returned in this call. iostatus is set to 0 for a successful I/O request, and to nonzero (typically a valid errno code) on an error. iobsize is set to the number of bytes transferred. iomaddr is the user's transfer address as given in the AREQBUF structure, and ioref is the context pointer; these two values associate the returned status with the initial request.

On failure, aio sets errno to one of the following values:


[EFAULT]
The arg pointer is not within the user's space, or AIO is not supported by this driver, or AIO is not configured into the kernel.

[EINVAL]
AIO is not supported on this file descriptor.

Diagnostics

The following error messages may be displayed on the console. See messages(M) for general information about kernel error messages, including a list of generic device driver errors. Also see aio(F) for a list of tunable parameters specific to asynchronous I/O.

NOTICE: AIO: aio_dma_xfer: invalid vtop
The virtual address specified to an AIO data transfer request is invalid.
NOTICE: AIO: aio_memlock: not enough memory for lock
Not enough memory is available to lock a chunk of user memory prior to a data transfer.
NOTICE: AIO: no dmaable buffers (DMAABLEBUF)
No buffers are available in DMA memory (below 16MB in physical address space).

Files


/usr/include/sys/async.h
definitions for asynchronous I/O

/usr/lib/aiomemlock
permissions file to control how much memory can be locked by whom

/etc/aiolkinit
command to lock physical memory for AIO transfers

/usr/bin/aioinfo
command to print statistics on AIO usage

See also

aio(F), aioinfo(ADM), aiolkinit(ADM), aiomemlock(F)
© 2005 The SCO Group, Inc. All rights reserved.
SCO OpenServer Release 6.0.0 -- 03 June 2005