STREAMS/UX Programmer’s Guide HP-UX 11i v3 Edition 1 Manufacturing Part Number : 5991-7416 E0207 United States © Copyright 2007 Hewlett-Packard Development Company L.P.
Legal Notices The information in this document is subject to change without notice. Hewlett-Packard makes no warranty of any kind with regard to this manual, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose. Hewlett-Packard shall not be held liable for errors contained herein or direct, indirect, special, incidental or consequential damages in connection with the furnishing, performance, or use of this material.
Contents 1. Overview STREAMS Components. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Stream Head . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . STREAMS Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . STREAMS Driver or Pseudo-Driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Contents fattach (3C) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 fdetach(3C) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 isastream(3C) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 3. Messages Message Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Contents Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 STREAMS Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 Flow Control in Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 Sample Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Contents A. STREAMS IOCTL Commands Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ioctl(2) Commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . I_ATMARK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . I_CANPUT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Contents allocb () 165 backq () 166 bcanput () 167 bcanputnext () 168 bufcall (), streams_bufcall () 169 canenable () 170 canput () 171 canputnext () 172 cmn_err () 173 copyb () 174 copymsg () 175 datamsg () 176 drv_getparm () 177 drv_priv () 178 dupb () 179 dupbn () 180 dupmsg () 181 enableok () 182 esballoc () 183 esbbcall () 184 flushband () 185 flushq () 186 freeb () 187 freemsg () 188 freezestr () 189 getadmin () 190 getmid () 191 getq () 192 insq () 193 linkb () 194 LOCK () 195 LOCK_ALLOC () 196 LOCK_
Contents OTHERQ () 201 pcmsg () 202 pullupmsg () 203 put () 204 putbq () 205 putctl () 206 putctl1 () 207 putctl2 () 208 putnext () 209 putnextctl () 210 putnextctl2 () 211 putq () 212 qenable () 213 qprocsoff () 214 qprocson () 215 qreply () 216 qsize () 217 RD () 218 rmvb () 219 rmvq () 220 SAMESTR () 221 streams_delay () 222 streams_get_sleep_lock () 223 streams_mpsleep () 224 streams_put () 226 streams_time () 227 streams_timeout () 228 streams_untimeout () 229 strlog () 230 strqget () 232 strqset () 23
Contents TRYLOCK () 240 testb () 241 unbufcall () 242 unfreezestr () 243 unlinkb () 244 UNLOCK () 245 unweldq () 246 vtop () 247 WR () 248 weldq () 249 C. Message Types Ordinary Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . M_BREAK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . M_CTL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Contents M_PCRSE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . M_PCSIG. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . M_READ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . M_START and M_STOP. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Contents SV_WAIT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . SV_WAIT_SIG. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . TRYLOCK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . UNLOCK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Contents level synchronization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297 G. STREAMS Commands Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . autopush . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Synopsis. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Contents When Should the Value of This Tunable Be Raised? . . . . . . . . . . . . . . . . . . . . . . . . What are the Side Effects of Raising the Value of This Tunable? . . . . . . . . . . . . . . When Should the Value of This Tunable be Lowered? . . . . . . . . . . . . . . . . . . . . . . . What are the Side Effects of Lowering the Value of This Tunable?. . . . . . . . . . . . . What Other Tunable Should be Changed at the Same Time? . . . . . . . . . . . . . . . . . Warnings . . . . . . . . . . . . . . .
Contents When Should the Value of This Tunable Be Raised? . . . . . . . . . . . . . . . . . . . . . . . . What are the Side Effects of Raising the Value of This Tunable? . . . . . . . . . . . . . . When Should the Value of This Tunable be Lowered? . . . . . . . . . . . . . . . . . . . . . . . What are the Side Effects of Lowering the Value of This Tunable?. . . . . . . . . . . . . What Other Tunable Should be Changed at the Same Time? . . . . . . . . . . . . . . . . . Warnings . . . . . . . . . . . . . . .
Figures Figure 1-1. Stream with a STREAMS Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 Figure 1-2. Stream without a STREAMS Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 Figure 1-3. Multiplexor Configurations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 Figure 2-1. A STREAMS-Based Pipe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Figures 4
About This Document This document describes how to use STREAMS, a generalized, flexible communication framework and set of tools that facilitate the development of communication services for UNIX. The document printing date and part number indicate the document’s current edition. The printing date will change when a new edition is printed. Minor changes may be made at reprint without changing the printing date. The document part number will change when extensive changes are made.
Shows the differences between STREAMS/UX and System V Release 4.2 STREAMS. Appendix F, “Synchronization Levels.” Explains the 5 levels of synchronization provided by STREAMS/UX. Appendix G, “STREAMS Commands.” Describes STREAMS commands. Appendix H, “STREAMS Kernel Tunable Parameters.” Describes the STREAMS kernel tunable parameters. Intended Audience This document is intended for HP-UX developers. This document is not a tutorial.
Typographical Conventions This document uses the following conventions. audit (5) An HP-UX manpage. In this example, audit is the name and 5 is the section in the HP-UX Reference. On the web and on the Instant Information CD, it may be a hot link to the manpage itself. From the HP-UX command line, you can enter “man audit” or “man 5 audit” to view the manpage. See man (1). Book Title The title of a book. On the web and on the Instant Information CD, it may be a hot link to the book itself.
HP Encourages Your Comments HP encourages your comments concerning this document. We are committed to providing documentation that meets your needs. Send comments to: netinfo_feedback@cup.hp.com Include the document title, manufacturing part number, and any comment, error found, or suggestion for improvement you have concerning this document. Email and Internet Resources Interface program and developer resource materials are available at the following locations: • Develop Drivers for HP-UX at http:/www.
Reference Documentation ❏ UNIX SVR4.2 Command Reference Manual ❏ SVR4.2 STREAMS Manual ❏ UNIX SVR4.2 Operation System API Reference Manual ❏ UNIX System V Release 4 Programmer’s Guide: STREAMS ❏ SVR4.2 Driver Manual ❏ UNIX SVR4.
10
1 Overview STREAMS is a generalized flexible communication framework. STREAMS provides a set of tools to facilitate the development of communication services for UNIX. It simplifies the user application interface to character device drivers, and makes the application independent of the underlying implementation. The modularity and dynamic module selection features of STREAMS make it an effective framework for implementing and interacting with kernel level components.
Overview STREAMS Components STREAMS Components A stream consists of the following components shown in Figure 1-1, “Stream with a STREAMS Module.”Figure 1-2 on page 13 shows a stream without a STREAMS module.
Overview STREAMS Components Figure 1-2 Stream without a STREAMS Module User Application User Space Kernel Space Stream Head Downstream Upstream Driver Stream Head The stream head is the interface between the user process and the STREAMS driver or module. It consists of a set of data structures and associated kernel routines. The kernel routines operate on the data structures and interface with the next stream component in the sequence.
Overview Messages and Queues Messages and Queues This section introduces the queues and messages associated with STREAMS. Queues Each stream component is associated with a read queue and write queue pair. The read queue and write queue are the data structures used to record the status of the stream component. These queues record the messages to be processed later. STREAMS allocates the read queue and write queue to the stream component.
Overview Messages and Queues Message Processing Each queue is associated with a put procedure and an optional service procedure to process the messages. The put procedure is used to process the messages from the preceding queue in a stream. Depending on the message type and the availability of the next module, the put procedure can consume this message and pass it to the next queue for further processing. Alternatively, the put procedure may place the messages on its message queue for processing later.
Overview STREAMS Multiplexor STREAMS Multiplexor A stream is a set of components with messages flowing between them. Each module is connected to no more than one downstream module and one upstream module. Advanced applications can require more complex configurations than a one-to-one relationship. For instance, multiple modules can communicate with a driver. Or, a single module may need to route messages to multiple drivers.
2 STREAMS Mechanism and System Calls This chapter describes system calls that create, use, and close a stream. The stream head processes the system calls that are made by a user level process. These system calls provide the user level facilities needed to develop applications.
STREAMS Mechanism and System Calls STREAMS System Calls STREAMS System Calls User applications use system to operate on STREAMS drivers. The following system calls are discussed in this chapter: open(2): Creates a stream to the specified device. close(2): Closes the stream, free the file descriptor, and if it is the last close(2) on this file descriptor, will dismantle the associated stream. read(2): Enables user applications to receive messages from a stream.
STREAMS Mechanism and System Calls Creating a Stream Creating a Stream open(2) Opening a STREAMS Device A user application creates a stream by opening a STREAMS device with the open (2) call. This call is part of the standard UNIX I/O. It opens a UNIX file for reading, writing, or both. Synopsis #include int open(const char *path, int oflag, ... /* [mode_t mode] */ ); Arguments path A pointer to a path name of the STREAMS device file being opened.
STREAMS Mechanism and System Calls Creating a Stream Figure 2-1 A STREAMS-Based Pipe User Process User Process User Space Kernel Space STREAM HEAD Module Module STREAM HEAD STREAMS-based Pipe Each end of the pipe maintains the status of the other end through internal data structures. Subsequent read, write, and close operations are aware of whether the other end of the pipe is open or closed. STREAMS modules can be added to a STREAMS-based pipe with ioctl (2) I_PUSH from either end of the pipe.
STREAMS Mechanism and System Calls Writing to a Stream Writing to a Stream User applications can write to a stream or a STREAMS-based pipe using the write(2), putmsg(2), or putpmsg(2) system call. The three function calls mirror the functionality of the corresponding message retrieval functions read(2), getmsg(2), and getpmsg(2). These system calls are described in the “Reading From a Stream” on page 25.
STREAMS Mechanism and System Calls Writing to a Stream The minimum and maximum acceptable STREAMS packet sizes are defined by the topmost module in the stream. A STREAMS packet is a segment of a message written to the stream. The length of a packet must be less than or equal to the maximum packet size defined in the topmost module. The following conditions apply to STREAMS packet size: • If nbytes falls within the packet size range, nbytes will be written.
STREAMS Mechanism and System Calls Writing to a Stream putmsg(2) and putpmsg(2) The putmsg (2) and putpmsg (2) calls also write messages to streams. These system calls can handle control messages and message priority information. Synopsis #include int putmsg (int fd, struct strbuf *ctlptr, struct strbuf *dataptr, int *priflag); int putpmsg (int fd, struct strbuf *ctlptr, struct strbuf *dataptr, int *msgband, int *priflag); fd STREAMS file descriptor.
STREAMS Mechanism and System Calls Writing to a Stream • If priflags is set to 0, a normal message is written to the stream. • If no control or data part are specified and priflags is set to 0, no message is written. However, putmsg (2) returns 0, indicating successful completion. For putpmsg (2), the priflags argument is a bitwise-OR of the mutually exclusive constants, MSG_HIPRI and MSG_BAND. The priflags and msgband arguments work in conjunction to determine the message priority and band value.
STREAMS Mechanism and System Calls Reading From a Stream Reading From a Stream User applications can read from a stream or a STREAMS-based pipe using the read (2), readv (2), getmsg (2), or getpmsg (2) system calls. read(2) and readv(2) The read (2) and readv (2) system calls are used by user applications to read message data from a stream. By default, control data will be ignored by these calls. Synopsis #include size_t read (int fd, void *buf,size_t nbytes); #include
STREAMS Mechanism and System Calls Reading From a Stream read (2) ignores message boundaries. It continues to retrieve data from the stream until the requested number of bytes is retrieved, there is no more data to be retrieved, or a zero-length message is encountered in the stream. If read (2) terminates on finding a zero-length message, it will place that message block back on the stream to be retrieved by next read (2) call. read (2) then returns the control back to the calling application.
STREAMS Mechanism and System Calls Reading From a Stream Return Values Upon successful completion, read (2) and readv (2) return the actual number of bytes read from the stream it placed in the requested buffer. This number may be less than the number of bytes requested (nbytes). In case of failure, read (2) returns -1and sets errno, as with all standard UNIX File System I/O.
STREAMS Mechanism and System Calls Reading From a Stream • If a buffer pointer is null or the corresponding maxlen is -1, the message is not be processed, and remains on the stream head read queue. If the buffer pointer is null, the corresponding len field returned is set to -1. • If buf is not null, len is greater than 0, and len is equal to or less than maxlen, len bytes are retrieved by getmsg (2), or getpmsg (2), and the return value of the function is set to len.
STREAMS Mechanism and System Calls Reading From a Stream Return Values For getmsg (2) and getpmsg (2), the flagsp and bandp arguments serve as input and output parameters. On successful completion of the getmsg (2) call, flagsp is set to either RS_HIPRI or 0, depending on whether the last retrieved message was of high priority. For getpmsg (2), flagsp is set to MSG_HIPRI, MSG_BAND, or MSG_ANY depending on the priority of the latest message retrieved.
STREAMS Mechanism and System Calls Pushing and Popping Modules Pushing and Popping Modules IOCTL Commands I_PUSH and I_POP Modules are an optional component of a stream. A module performs intermediate operations on messages as they pass between components in a stream. Modules are added into a stream by using the I_PUSH ioctl (2) command. Modules are removed from a stream by using the I_POP ioctl (2) command. Synopsis #include #include int ioctl(int fd, cmd ...
STREAMS Mechanism and System Calls Closing a Stream Closing a Stream The last close() to a STREAMS file dismantles the stream as follows: • It pops modules (if any) from the stream, allowing any messages on the write queue of the module to be drained by the module processing. • It closes the device, allowing any messages on the write queue of the driver to be drained by the driver processing.
STREAMS Mechanism and System Calls Polling Streams Polling Streams Polling, (sometimes referred to as Synchronous Polling) is a mechanism by which a STREAMS application can query one or more file descriptors (stream head read-queues) for specific events. An event can be the arrival of specific message types, the status of a stream to accept certain message types, or the occurrence of specific error conditions.
STREAMS Mechanism and System Calls Polling Streams Events Notified by poll(2) STREAMS supports the following events requests in the poll (2) function: POLLIN A non-high priority message, This is a a regular message or a priority band message at the front of the stream head read-queue. POLLNORM Same as POLLIN. POLLPRI A high priority message is at the front of the stream head read queue. POLLOUT A normal or priority band message can be written to the stream without being blocked by flow control.
STREAMS Mechanism and System Calls Polling Streams the application. However, during application execution, there can be a small number of open streams. The unused file descriptors inside the corresponding pollfd structures must be set to -1. These pollfd structures (with a negative fd) are ignored by poll (2). If all the pollfd structures passed to the poll (2) call have negative fd values, poll (2) returns 0 and has no other results.
STREAMS Mechanism and System Calls Polling Streams int evpfd; evpfd = open(“/dev/poll”, O_RDWR); NOTE The /dev/poll device can be used for write (2) and ioctl (2) operations only by the processes that opened the device. Although file descriptors are generally inherited by forked processes, the event port file descriptor behaves differently. Specifically, a child process inheriting an event port file descriptor can only perform the close (2) operation on it.
STREAMS Mechanism and System Calls Polling Streams • The wait period behavior of the timeout values • Reporting the POLLERR, POLLHUP, and POLLNVAL events Retrieving registered poll conditions for a file descriptor: User applications may query /dev/poll for the registration status of specific file descriptors via the DP_ISPOLLED ioctl (2) command as follows: struct pollfd pfd; int ispolled; pfd.
STREAMS Mechanism and System Calls Polling Streams Differences Between select(2) and poll(2) Unlike the pollfd structure that allows poll (2) to check a virtually unlimited number of file descriptors, the select (2) call expects file descriptors to be specified as three sets of bitmasks. In HP-UX, both functions allow the user process to perform more or less than same function.
STREAMS Mechanism and System Calls Asynchronous Event Notification Asynchronous Event Notification The polling method described in the previous section is synchronous. The application has to explicitly stop what it is doing, and poll each time it needs to check the occurrence of relevant events on different file descriptors.
STREAMS Mechanism and System Calls Asynchronous Event Notification signal (SIGPOLL, OnRecv); OnRecv is a user-specified function to be called when the user process receives a SIGPOLL signal. Refer to the signal (2) manpage for details on signal handling by user applications.
STREAMS Mechanism and System Calls Attaching and Detaching a Stream to a File - Named Streams Attaching and Detaching a Stream to a File - Named Streams User applications can associate a stream or STREAMS-based pipe with an existing node in the file system name space. This enables other processes to communicate with this process. For example, a process creates a pipe and names one end of the pipe using fattach(). When another unrelated process opens this file, it gets access to the named end of the pipe.
STREAMS Mechanism and System Calls Attaching and Detaching a Stream to a File - Named Streams Arguments path Path name of an existing object in the file system. The fdetach () function detaches a file descriptor from its filename in the file system. The path argument refers to the path that was previously attached using fattach (). The caller must own path or have write permission or appropriate privileges (PRIV_MOUNT) to detach a file descriptor.
STREAMS Mechanism and System Calls Attaching and Detaching a Stream to a File - Named Streams 42 Chapter 2
3 Messages Messages are the means of communication within a stream. The objects passed between the stream components are pointers to messages. This chapter covers the structure, processing, and flow control of STREAMS messages.
Messages Message Structures Message Structures All STREAMS messages consists of one or more message blocks as shown in Figure 3-1, “A Message and Its Linkage.” STREAMS message is comprised of two data structures — a message block and a data block. The message block represented by msgb describes the message, the data block represented by datab describes the data and contains the pointer to the variable-length data buffer.
Messages Message Structures The fields perform the following functions: b_next and b_prev Link the messages on a module or driver Queue’s message queue. Builds a complex message from two or more message blocks. b_cont b_rptr and b_wptr Locate the data present in the data buffer. b_band Contains the priority band for a message. b_datap Points to the data block header. b_flag Contains a bitmask of flags interpreted by stream head.
Messages Message Structures Ordinary messages are always put at the end of the message queue. These messages have the priority band (b_band) set to zero. However, any ordinary messages can be changed to priority band messages (also known as Expedited data) by modifying b_band value. STREAMS supports priority band value up to 255. M_DATA User data. M_PROTO Protocol control information. M_IOCTL User IOCTL request generated by stream head. M_PASSFP Passes file descriptor between the processes.
Messages Message Structures Message Queues Message queues are essentially a linked list of messages waiting to be processed by the service procedure. The STREAMS scheduler accesses these lists through the pointers available to the head and tail of the lists in the module or driver queues as explained. A queue will generally not use its message queue if there is no service procedure associated with it.
Messages Message Structures The streamtab Structure Every STREAMS module and driver installed on a system is associated with a struct streamtab structure defined in in addition to other structures. The information provided by the module or driver writer in this structure is used by STREAMS to initialize the queue-pair associated with the module or driver.
Messages Message Structures The q_count field contains the total number of message bytes on the queue inclusive of all normal, banded and high priority messages. When q_count equals or exceeds the queue’s high watermark (q_hiwat), STREAMS marks the queue as full. The q_flag field contains a bitmask indicating the state of the queue. It can have one or more of the following values listed: QREADR Defines a read queue. QNOENB Do not enable the queue when data is placed on it.
Messages Message Structures The qinit Structure The qinit structure contains the addresses of the functions associated with the queue, associated module information, and an optional statistics if present. The streamtab structure as shown earlier for a module or driver has pointers to the qinit structure both for the upstream and downstream processing. The struct qinit is defined in
Messages Message Processing and Flow Control Message Processing and Flow Control Message Processing Each queue in a stream is associated with a put procedure and an optional service procedure. The only exception is the driver’s read-queue, which may not have a put procedure. The put procedure and the service procedure are the two routines to process the messages. The put procedure is used to process messages immediately.
Messages Message Processing and Flow Control Watermarks Each queue is associated with the following watermarks and counter to manage the amount of data accumulated in the message queue: q_hiwat High watermark q_lowat Low watermark q_count Counter When a message is placed onto the message queue, STREAMS increments q_count by the size of the message. When a message is removed from the message queue, STREAMS decrements the q_count accordingly.
Messages Message Processing and Flow Control Figure 3-3 Flow Control queue A with service procedure canput() queue B no service procedure back enable queue As service procedure when QFULL on queue C in not set queue C with service procedure QFULL When queue A uses canput () to check for available space, canput () searches through the stream. canput () starts searching from queue B, until it finds queue C that contains a service procedure. Then, canput () checks if QFULL is set on queue C.
Messages Message Processing and Flow Control Common STREAMS Utilities This section provides an overview of the most common utilities used by modules or drivers. Appendix B, “STREAMS Utilities Supported by HP-UX,” contains the complete set of STREAMS utilities relevant to STREAMS programmers. All these utilities are exported via .
Messages Message Processing and Flow Control mblk_t *copymsg(mblk_t *mp); copymsg () Uses copyb () to copy the message blocks contained in the message pointed by bp to a newly allocated message block, and links the new message blocks to form the new message. mblk_t *dupb(mblk_t *bp); dupb () Takes a pointer to a message block descriptor (mblk_t) as an input parameter, allocates a new message and initialized it by copying the contents of the input message block.
Messages Message Processing and Flow Control Figure 3-4 Pulling Up a Complex Message Before After b_wptr b_cont MA MC b_wptr b_wptr MB b_datap b_datap b_rptr b_rpt b_datap DA DC DB db_base db_lim b_rptr db_lim db_base db_base 100 50 db_lim 150 Message Processing Utilities int putnext(queue_t *q, mblk_t *mp) putnext () Is used for passing messages to the next queue in a stream.
Messages Message Processing and Flow Control The flow control parameters for the q specified are updated. insq () Returns 1 on success. Otherwise it returns 0. mblk_t *getq(queue_t *q) getq () Returns the next available message from the message queue associated with the q. This is typically used by the service procedure to process the messages. If there are no messages, this routine will return a NULL pointer and QWANTR is set so when the next message is placed, the service procedure will be scheduled.
Messages Message Processing and Flow Control 58 Chapter 3
4 Modules and Drivers This chapter describes the various data structures essential to modules and drivers. It also provides design guidelines for developing modules and drivers. Appropriate code examples have been provided.
Modules and Drivers Overview Overview Modules and drivers are the processing elements on a stream, below the stream head. STREAMS modules and drivers are structurally similar. The streamtab, qinit, module_info, and optionally module_stat, structures must be declared for STREAMS drivers and modules. A STREAMS driver is a required element but modules are optional. A STREAMS device driver is similar to a regular UNIX character device driver. It is opened as a regular driver even if it is a pseudo-driver.
Modules and Drivers Overview Dynamically Loadable Kernel Modules Dynamically Loadable Kernel Modules (DLKM) are device drivers and other kernel modules that can be added to a running system without rebooting the system or rebuilding the kernel. Unless otherwise mentioned, the STREAMS modules and drivers are statically linked into the kernel.
Modules and Drivers Data Structures Data Structures A STREAMS module or driver must define and initialize three data structures — module_info, qinit, and streamtab. An optional module_stat structure can also be defined and initialized. In addition to these data structures, HP-UX requires all modules and drivers to define streams_info_t. Drivers must define drv_info_t and drv_ops_t. DLKM modules require additional data structures to be defined. These are described in the “DLKM STREAMS” section.
Modules and Drivers Data Structures The qinit Structure The qinit structure is as follows: int (*qi_putp) __((queue_t *, mblk_t *)); /* put procedure */ int (*qi_srvp) __((queue_t *)); /* service procedure */ int (*qi_qopen)(); /* open procedure */ int (*qi_qclose)(); /* close procedure */ int (*qi_qadmin) __((void)); /* qadmin routine */ struct module_info * qi_minfo; /* module info */ struct module_stat * qi_mstat; /* module stat */ The qinit structure defines the queue pro
Modules and Drivers Data Structures The following code snippet illustrates the declaration of mandatory structures for a dummy STREAMS driver named drv: #include #include #include #include
Modules and Drivers Data Structures The streams_info_t Structure The streams_info_t structure must be defined for both STREAMS modules and drivers.
Modules and Drivers Data Structures SQLVL_DEFAULT Default level synchronization. It is the same as SQLVL_QUEUEPAIR. SQLVL_MODULE Module level synchronization. All the instances of modules/drivers are synchronized. SQLVL_ELSEWHERE Synchronize with respect to the group of co-operating modules/drivers which access each others data. The group name is specified in the inst_sync_info. SQLVL_GLOBAL Provides Global synchronization.
Modules and Drivers Data Structures c_major Assign the major number or set it to -1 for dynamic assignment. If the major number is manually assigned, it is the responsibility of the driver developer to assign a unique number. cdio Set this field to NULL. gio_private Set this field to NULL. cdio_private Set this field to NULL. The drv_ops_t Structure This structure is applicable only for STREAMS drivers. This must be allocated statically. The drv_ops_t has the following fields.
Modules and Drivers Data Structures Configuration Routines The following are the configuration routines for drivers: driver_install(): All STREAMS drivers and modules that are to be statically built into the kernel must implement a driver_install() function. The variable is the name of the module or driver as defined in the module_info structure. The driver must match the name specified in drv_info_t/streams_info_t for drivers.
Modules and Drivers Data Structures -1, -1, NULL, NULL, NULL }; drv_opt_t drv_drv_ops ={ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, }; int drv_install() { int retval; if ((retval = (install_driver(&drv_drv_info, &drv_drv_ops))) !=0) { return retval; } if ((retval = str_install(&drv_str_info)) !=0) { (void)uninstall_driver(&drv_drv_info); return retval; } return 0; } NOTE Chapter 4 The driver_install() routine must never sleep.
Modules and Drivers Entry Points Entry Points This section explains the entry points for drivers and modules in detail. Open The open routine for a driver is called when the device is first opened by the user process with an open (2) system call. The module open routine is called when the module is pushed onto the stream with I_PUSH IOCTL command or with the autopush utility.
Modules and Drivers Entry Points In the close routine the module or driver should free any resources it allocated in the open path and clear any pending timeouts or bufcalls. The close routine must take appropriate action for messages still left in the module or driver queue. For drivers the read-side queue can have messages resulting from device interrupts. Driver developers need to make sure these messages are handled properly prior to actually closing the driver.
Modules and Drivers Entry Points The timeout value for STREAMS IOCTL is infinite except for I_STR IOCTLs where a user can specify a timeout value. Modules must pass an unrecognized M_IOCTL message to the next component on the stream without any modifications to the message. Drivers must respond with an M_IOCNAK message to the stream head for an unrecognized M_IOCTL message. At any point in time only one ioctl (2) system call is active on the stream head.
Modules and Drivers Entry Points } The structure strioctl is defined in and contains the following fields: int ic_cmd; /* downstream command */ int ic_timout; /* ACK/NAK timeout */ int ic_len; /* length of data arg */ char * ic_dp; /* ptr to data arg */ The ic_cmd field describes the command intended for module or driver, ic_timout specifies the number of seconds the I_STR request will wait for an acknowledgement before timing out.
Modules and Drivers Entry Points * (for example count should be exactly of integer size * for this driver user data) */ if (iocp->ioc_count != sizeof(int)) { /* Set error value */ iocp->ioc_error = EINVAL; goto log_error; } if (mp->b_cont == NULL) { goto log_error; } /* Process actual user data from 2nd mesage block */ set_mydrv_options(mydata, *(int *)mp->b_cont->b_rptr); /* Send acknowledgement upstream */ mp->b_datap->db_type = M_IOCACK; /* no data returned to user */ iocp->ioc_count = 0; qreply(q,
Modules and Drivers Entry Points Transparent IOCTL Processing The transparent IOCTL mechanism offers data transfer capability well beyond what is offered by the I_STR IOCTL mechanism. The I_STR mechanism only enables IOCTL commands that are defined in streamio (7). Transparent IOCTL allows user applications and modules to define their own IOCTL commands.
Modules and Drivers Entry Points 7. If the module needs to send data back to the user, a M_COPYOUT message is created by the module and sent to the stream head. The stream head executes a copyout() function that copies the data from the M_COPYOUT message into the user buffer. The M_COPYOUT message contains the address of user data, size and the data. The M_IOCDATA response for the M_COPYOUT will not contain data but only an indication of success or failure.
Modules and Drivers Entry Points The stream head converts the M_COPYIN and M_COPYOUT messages into M_IOCDATA messages by changing the type of the message, so it is absolutely necessary that the copyreq structure be properly formed and initialized. Also, the iocblk, copyreq and copyresp structures all overlay one another. M_COPYIN, M_COPYOUT and M_IOCDATA are high-priority messages and are used for communication between the module that created them and the stream head.
Modules and Drivers Entry Points /* Allocate state buffer */ if ((tmp = allocb(sizeof(struct state), BPRI_LO)) == NULL) { bp->b_datap->db_type = M_IOCNAK; iocbp->ioc_error = EAGAIN; qreply(q, bp); break; } tmp->b_wptr += sizeof(struct state); stp = (struct state *)tmp->b_rptr; stp->st_state = GETSTRUCT; cq->cq_private = tmp; cq->cq_size = sizeof(struct transparent_data); cq->cq_flag = 0; bp->b_datap->db_type = M_COPYIN; bp->b_wptr = bp->b_rptr + sizeof(struct copyreq); } else { /* Send negative acknowledge
Modules and Drivers Entry Points bp->b_cont = nilp(mblk_t); /* reuse M_IOCDATA to copyin data */ bp->b_datap->db_type = M_COPYIN; cq = (struct copyreq *)bp->b_rptr; cq->cq_size = stp->st_data.buflen; cq->cq_addr = stp->st_data.bufaddr; cq->cq_flag = 0; stp->st_state = GETINDATA; /* next state */ qreply(q, bp); break; case GETINDATA: /* data successfully copied in */ /* process input */ ... ...
Modules and Drivers Entry Points } } else { /* M_IOCDATA not for us , so pass to next component */ putnext(q, bp); } break; default: /* Unknown message, so pass to next component */ putnext(q, bp); break; } } Put Procedure Modules and drivers need to use the put or service procedure entry points for providing all the message processing logic. The put procedure is used for immediate processing of the message and is required for all queues in a stream, with a possible exception of driver read-queue.
Modules and Drivers Entry Points The return value from the service procedure is ignored. A service procedure is scheduled to run by placing a message on its queue. When a service procedure is executed by the scheduler, it should process all the messages on its queue. If it cannot process all the messages, then it must ensure that it gets rescheduled so that the remaining messages are processed.
Modules and Drivers Flush Handling Flush Handling The Flush operation involves removing of messages from read queue or write queue or both the queues. It can be initiated by a user process or by a module/driver. The M_FLUSH message is used in flush operation. All drivers and modules must handle the M_FLUSH messages. STREAMS provides two utilities — flushq() and flushqband(), for drivers and modules to flush an entire queue or just a specified band.
Modules and Drivers Flush Handling Flush Handling in a Pipe Message flushing in a pipe is complicated in nature because the write queue of one end of stream head is connected to the read queue of the other, and vice versa. As a result, FLUSHW and/or FLUSHR bits have to switched appropriately to ensure that wrong queues are not flushed. The point of switching is called the midpoint of a pipe. Midpoint in a STREAMS based pipe is where the write queues point to the read queues.
Modules and Drivers Design Guidelines Design Guidelines Some of the common design guidelines for STREAMS modules and drivers have been explained here: • STREAMS modules and drivers are not associated with any process and do not have a process or a user context (except during open and close. Therefore modules and drivers cannot access the information from the u_area of a process.
Modules and Drivers Design Guidelines • STREAMS modules and drivers must not call the put and service procedures directly. They must be executed by calling STREAMS utilities such as putnext, put, putq, or qenable. They cannot be called using the function pointer stored in the q_qinfo structure. • STREAMS modules and drivers can allocate their own spinlocks to protect data structures. If they do, they should use the lock orders reserved for them in /usr/include/sys/semglobal.
Modules and Drivers Design Guidelines Put Procedure 1. A put procedure must be defined in the qinit structure for every queue in a stream to pass messages between the STREAMS components. 2. A put procedure does not have any user context, so it must not sleep and must not call any functions that call sleep(). 3. The put procedure cannot access the information in the u_area of a process as no user context is associated with it. 4.
Modules and Drivers Design Guidelines 6. The service procedure should not put a high priority message back on the queue to avoid getting into an infinite loop.
Modules and Drivers STREAMS Module STREAMS Module A STREAMS module is essentially a pair of queues and a defined set of kernel-level routines and data structures used to process messages as they flow through them in a stream. A stream may have zero or more modules and pushing and popping of these modules happens in a Last In First Out (LIFO) manner. Flow Control in Modules Module flow control is advised and when used helps in limiting the amount of data that can be placed on a modules’ queue.
Modules and Drivers STREAMS Module /* Streams data structures for Modules */ int mod_open __((queue_t *, dev_t *, int, int, cred_t *)); int mod_close __((queue_t *, int, cred_t *)); int mod_rput __((queue_t * q, mblk_t *)); int mod_wput __((queue_t * q, mblk_t *)); int mod_rsrv __((queue_t * q)); int mod_wsrv __((queue_t * q)); #define MOD_ID 0 static struct module_info minfo = { MOD_ID, "MOD", 0, INFPSZ, 65536, 1024 }; static struct qinit mod_rinit = { mod_rput, mod_rsrv, mod_open, mod_clo
Modules and Drivers STREAMS Module Installation Routine STREAMS modules do not have any cdevsw-related information. They only have STREAMS-specific information and this is configured by calling str_install() with a defined streams_info_t. int mod_install() { int retval; if ((retval = str_install(&mod_str_info)) !=0) return retval; /* failure */ return 0; /* Success */ } Any module specific global data structures, spinlocks etc. can be setup and initialized in the installation routine.
Modules and Drivers STREAMS Module if (!modp) { return 1 ; /* Failure */ } /* * Assign the private data structure to both the read and the write * side q_ptr's. */ q->q_ptr = WR(q)->q_ptr = modp; return 0 ; /* Success */ } Based on a module’s requirement, a module should: • Validate the flag value specified in the cflag. • Validate the user credentials passed through credp. • Cancel any pending timeout or bufcall routines that access data that are deinitialized or deallocated during close.
Modules and Drivers STREAMS Module Put Procedure An example of a module’s read-side and write-side put procedure are shown: int mod_rput(q, mp) queue_t *q; mblk_t *mp; { mod_priv_t *modp; /* get the module specific data */ modp = (mod_priv_t *)q->q_ptr; if ((mp->b_datap->db_type >= QPCTL) && mp->b_datap->db_type != M_FLUSH )) { /* * Process the high priority messages immediately * and pass it upstream */ ...
Modules and Drivers STREAMS Module return; } } int mod_wput(q, mp) queue_t *q; mblk_t *mp; { mod_priv_t *modp; modp = (mod_priv_t *)q->q_ptr; if ((mp->b_datap->db_type >= QPCTL) && ( mp->b_datap->db_type != M_FLUSH )) { putnext(q, mp); return; } switch (mp->b_datap->db_type) { case M_DATA: putq(q, mp); return; case M_PROTO: /* process the protocol message */ ... ... case M_FLUSH: /* process the M_FLUSH message */ ... ...
Modules and Drivers STREAMS Module */ ... if (success) { ... mp->b_datap->db_type = M_IOCACK; } else { ... mp->b_datap->db_type = M_IOCNAK; } qreply(q, mp); return; case MOD_IOCTL2: ... ... /* ioctl commands not recognized by the module */ default: /* Pass the ioctl message downstream */ putnext(q, mp); return; } default: /* Pass the message downstream if the module does not * understand it.
Modules and Drivers STREAMS Module Service Procedure The following example shows a generic service procedure: int mod_rsrv(q) queue_t *q; { mblk_t *mp; while ((mp = getq(q)) != NULL) { /* check for flow control */ if (!(mp->b_datap->db_type >= QPCTL) && !canputnext(q) { putbq(q,mp); return; } /* Process the message */ switch (mp->b_datap->db_type) { case M_DATA: ... ...
Modules and Drivers STREAMS Driver STREAMS Driver A STREAMS device driver as mentioned earlier is similar to a regular UNIX character device driver. A STREAMS driver is a necessary part of the stream constituting the stream end. A stream is created when a STREAMS driver is opened. A STREAMS driver can also have multiple streams connected to it. Multiple connections could be a result when more than one minor device of the same driver are opened and in case of multiplexors.
Modules and Drivers STREAMS Driver A device is then accessed by opening, reading, writing or closing the special device file associated with the device with proper major and minor numbers.
Modules and Drivers STREAMS Driver Flow Control in Drivers In general, the same utilities and mechanisms used in implementing module flow control are used by drivers too. STREAMS allows flow control to be used on the driver read-side to handle temporary upstream blocks. The driver or a module has an option of resetting the stream head read-side flow control limits by sending a M_SETOPTS message upstream.
Modules and Drivers STREAMS Driver DRV_CHAR | DRV_PSEUDO | DRV_MP_SAFE, /* Driver flags */ -1, /* Block Major number */ -1, /* Character Major number */ NULL, NULL, NULL /* cdio, gio_private, cdio_private */ } static drv_ops_t test_drv_ops = { NULL, /* d_open */ NULL, /* d_close */ NULL, /* d_strategy */ NULL, /* d_dump */ NULL, /* d_psize */ NULL, /* d_mount */ NULL, /* d_read */ NULL, /* d_write */ NULL, /* d_ioctl */ NULL, /* d_select */ NULL, /* d_option1 */ NULL,
Modules and Drivers STREAMS Driver Installation Routine Like STREAMS modules, STREAMS drivers need to configure the STREAMS specific information by calling str_install() with a defined streams_info_t. In addition, since drivers do have cdevsw information, a call to install_driver() should be made before the configuration for streams is done in str_install().
Modules and Drivers STREAMS Driver * a non-clone open */ if (sflag != CLONEOPEN) { /* Non-clone open */ ... } else { /* Clone open */ ... *dev = makedev(major(*dev), dev_minor); } /* * Allocate the driver specific private data to be assigned to * the q_ptr (per-stream data) */ drvp = (drv_priv_t *)kmem_alloc(sizeof(drv_priv_t), M_NOWAIT); if (!drvp) { return 1 ; /* Failure */ } /* * Assign the private data structure to both the read and the write * side q_ptr's. */ q->q_ptr = WR(q)->q_ptr = drvp; ...
Modules and Drivers STREAMS Driver * this instance of the module. */ if (q->q_ptr) kmem_free((caddr_t)q->q_ptr, sizeof(drv_priv_t)); /* * Free the minor number allocated for this stream */ ... /* * Assign NULL to both the read and the write side q_ptr's */ q->q_ptr = WR(q)->q_ptr = NULL; return 0 ; /* Success */ } Put Procedure The put procedure is the third entry point for the STREAMS driver. Outbound Processing The write (2) and ioctl (2) system calls are only seen by the stream head.
Modules and Drivers STREAMS Driver switch (mp->b_datap->db_type) { case M_DATA: case M_PROTO: /* process the message */ ... ... case M_IOCTL: struct iocblk * iocp = (struct iocblk *)mp->b_rptr; switch (iocp->ioc_cmd) { /* ioctl commands recognized by the driver */ case D_IOCTL1: /* * process and reply back with a positive * or negative acknowledgment */ ... if (success) { ... mp->b_datap->db_type = M_IOCACK; } else { ... mp->b_datap->db_type = M_IOCNAK; } qreply(q, mp); return; case D_IOCTL2: ... ...
Modules and Drivers STREAMS Driver } if (*mp->b_rptr & FLUSHR) { *mp->b_rptr &= ~FLUSHW; /* Flush the read queue if messages can be enqueued */ ... qreply(q, mp); } else freemsg(mp); return; default: /* Free the message if the driver does not * understand it. */ freemsg(mp); return; } } Inbound Processing The read (2)system call is only seen by the stream head, which processes the system call. A STREAMS driver will not be aware of this system call.
Modules and Drivers STREAMS Driver Service Procedure Services procedures are optional for the drivers too and defined when the messages can get enqueued on to a driver’s read-side queue.
Modules and Drivers STREAMS Driver Driver Specific Design Guidelines In addition to the guidelines listed in the “Design Guidelines” section, the driver developers should follow these guidelines: • A driver must be defined and configured in a kernel before it can be opened. • Drivers managing a hardware device must have an interrupt service procedure. • Messages that are not understood by the driver should be freed.
Modules and Drivers DLKM STREAMS DLKM STREAMS Traditionally, kernel modules have been statically bound into the main kernel executable, /stand/vmunix. This method requires system administrators to rebuild the kernel executables and then reboot the system in order to add, remove, or patch a kernel module. A Dynamically Loadable Kernel Module (DLKM) can be loaded into the running kernel without the need for a rebuild or a reboot.
Modules and Drivers DLKM STREAMS 108 Chapter 4
5 Multiplexing This chapter describes the STREAMS multiplexing feature of the STREAMS framework. It provides design guidelines on building, dismantling, and configuring multiplexors.
Multiplexing Overview Overview STREAMS multiplexing is a special feature in the STREAMS framework. It provides a mechanism to connect multiple streams below a driver so that data can be routed among the connected streams. The special purpose STREAMS driver used in implementing STREAMS multiplexing is called a STREAMS multiplexor. A multiplexor is logically partitioned into an upper-half and a lower-half.
Multiplexing Building and Dismantling Multiplexors Building and Dismantling Multiplexors Multiplexor configurations can be built and dismantled at the user level by using I_LINK/I_UNLINK ioctl commands. To Build a Multiplexor Multiplexor configurations are created at the user level via system calls. The multiplexor driver is like any other software driver. It owns a node in the file system and is opened just like any other STREAMS device driver.
Multiplexing Building and Dismantling Multiplexors Figure 5-2 Multiplexor After Link I_LINK returns an integer value muxid that is used by the multiplexing driver to identify the stream connected below it. This value is used for routing data through the multiplexor or dismantling the multiplexor. The stream associated with muxfd is known as the controlling stream of a multiplexor link.
Multiplexing Building and Dismantling Multiplexors To Dismantle a Multiplexor The I_UNLINK ioctl call can be used to disconnect one or all the streams connected below a multiplexor: ioctl(muxfd, I_UNLINK, muxid); muxfd Is the file descriptor associated with the controlling stream, which was used to create the link(s). The muxid is associated with the stream linked below the multiplexor.
Multiplexing Connecting and Disconnecting Multiplexor Configurations Connecting and Disconnecting Multiplexor Configurations The STREAMS framework requires two additional qinit structures when managing a multiplexor. These additional structures are specified in the multiplexors streamtab structure. A multiplexor is logically partitioned into an upper-half and a lower-half. The upper-half uses the st_rdinit and st_wrinit qinit structures specified in streamtab.
Multiplexing Connecting and Disconnecting Multiplexor Configurations The above plumbing causes any messages reaching the top of the stream from the driver below to be delivered to the multiplexing driver’s lower-half read-side put and service procedures. The multiplexing stream becomes the controlling stream. This plumbing relationship is remembered by the STREAMS framework until the controlling stream is closed, or the stream below is unlinked through I_UNLINK.
Multiplexing Connecting and Disconnecting Multiplexor Configurations To Disconnect a Multiplexor Configuration Disconnection of multiplexor configurations involves unlinking lower streams. The unlinking can be accomplished by the following three methods: • An I_UNLINK ioctl referencing a specific stream. • An I_UNLINK ioctl indicating all lower streams. • The last close() on the upper controlling stream. An I_UNLINK ioctl performs the unlink operation as follows: 1.
Multiplexing Connecting and Disconnecting Multiplexor Configurations Characteristics of Multiplexing Configurations In a multiplexing configuration, streams opened to the multiplexor are referred to as upper streams and those linked below the multiplexor are referred to as lower streams. • An I_LINK is required for each lower stream connected to the driver. Additional upper streams can be connected to the multiplexing driver by open() calls.
Multiplexing Persistent Links Persistent Links When I_LINK and I_UNLINK ioctls are used, the file-descriptors associated with the upper stream need to be active through out the operation of the multiplexor configuration. Closing the controlling stream will unplumb the multiplexor configuration. It may not be desirable to keep an application process active only to hold the multiplexor configuration together. This is resolved by using persistent links below a multiplexor.
Multiplexing Persistent Links Figure 5-3 Multiplexor Before I_PLINK Figure 5-4 Multiplexor After I_PLINK Once the persistent link is setup, users can open the mux multiplexor and send the data to the drv driver as the persistent link to the drv driver remains intact. See Fig. 5.
Multiplexing Persistent Links Figure 5-5 120 Data Transfer to the Driver Chapter 5
Multiplexing Persistent Links Dismantling Persistent Links Use ioctl I_PUNLINK to dismantle the persistent link between a stream opened to the multiplexor and the stream connected below the multiplexing driver. Its format is: ioctl(muxfd, I_PUNLINK, muxid); muxfd Is a file descriptor associated with a stream opened to a multiplexing driver (upper stream). muxid Is the muxid returned by the I_PLINK ioctl for the stream that was connected below the multiplexor.
Multiplexing Persistent Links Characteristics of Persistent Links Regular links created through I_LINK cannot be unlinked with I_PUNLINK. Similarly, persistent links created through I_PLINK cannot be unlinked through I_UNLINK. The ioctl will return EINVAL when the I_LINK/I_UNLINK and I_PLINK/I_PUNLINK calls are intermixed.
Multiplexing STREAMS Multiplexor STREAMS Multiplexor A STREAMS multiplexing driver or multiplexor is a special purpose STREAMS driver that provides a way to route messages between different streams. Various multiplexor configurations can be built and dismantled as explained in the previous sections. The upper-half of the multiplexor: • Deals with the streams opened to the multiplexor. • Follows the same rules as the streams drivers do regarding unrecognized messages, flushing, and M_IOCTL processing.
Multiplexing STREAMS Multiplexor Ioctl Processing in a Multiplexor For M_IOCTL processing, the upper-half of the multiplexor must follow the same rules as drivers. It must always process an M_IOCTL message from the stream head and acknowledge it with a M_IOCACK/M_IOCNAK. If the upper-half of the multiplexor does not understand the ioctl, it must send an M_IOCNAK upstream.
Multiplexing STREAMS Multiplexor A Sample Multiplexing Driver This section contains an example of a STREAMS multiplexing driver that implements an N-to-1 configuration. Multiplexor Declaration /* Sample Multiplexor inclusions */ #include #include #include #include
Multiplexing STREAMS Multiplexor static struct qinit mux_uwinit = { /* upper write */ mux_uwput, mux_uwsrv, NULL, NULL, NULL, &minfo }; static struct qinit mux_lrinit = { /* lower read */ mux_lrput, mux_lrsrv, NULL, NULL, NULL, &minfo }; static struct qinit mux_lwinit = { /* lower write */ NULL, mux_lwsrv, NULL, NULL, NULL, &minfo }; static drv_info_t mux_info = { "MUX", /* Driver name */ "pseudo", /* Driver Class */ DRV_CHAR | DRV_PSEUDO | DRV_MP_SAFE, /* Driver flags */ -1, /* Block Major n
Multiplexing STREAMS Multiplexor -1, /* major no */ { &mux_urinit, &mux_uwinit, &mux_lrinit, &mux_lwinit}, /* streamtab */ STR_IS_DEVICE | MGR_IS_MP | STR_SYSV4_OPEN, /* streams flags */ SQLVL_QUEUEPAIR, /* sync level */ "", /* elsewhere sync name */ }; struct streamtab mux_strtab = { &mux_urinit, &mux_uwinit, &mux_lrinit, &mux_lwinit }; /* data structures private to the multiplexor used in this example */ /* Number of upper streams allowed in this N-to-1 configuration */ #define MUXCNT 10 stru
Multiplexing STREAMS Multiplexor Installation Routine Like other STREAMS drivers, STREAMS multiplexing drivers also need to configure the STREAMS specific information by calling str_install() with a defined streams_info_t.
Multiplexing STREAMS Multiplexor */ if (sflag != CLONEOPEN) { /* Non-clone open */ minor_dev = minor(*dev); } else { /* Clone open */ for(minor_dev=0; minor_dev < MUXCNT; minor_dev++) if (mux_list[minor_dev].top_rq == NULL) break; } if (minor_dev >= MUXCNT) return ENOENT; /* Failure */ muxp = &mux_list[minor_dev]; muxp->top_rq = q; /* * Assign the private data structure to both the read and the write * side q_ptr’s.
Multiplexing STREAMS Multiplexor Put Procedure In a multiplexing configuration: • The upper write put and the lower read put procedures are mandatory. • The upper read put and the lower write put procedures can be skipped over and the message put to the next queue if they are not mandatory. In this example, the upper read side put procedure is not used. The lower stream read queue procedures transfer the messages directly to the read queue upstream from the multiplexor.
Multiplexing STREAMS Multiplexor case I_LINK: case I_PLINK: if (muxbot_wq != NULL) /* lower stream is already linked */ mp->b_datap->db_type = M_IOCNAK; else { /* Obtain the linkblk from the message * and set up the link */ linkp = (struct linkblk *)mp->b_cont->b_rptr; muxbot_wq = linkp->l_qbot; muxerr = 0; iocp->ioc_count = 0; mp->b_datap->db_type = M_IOCACK; } qreply(q,mp); break; case I_UNLINK: case I_PUNLINK: muxbot_wq = NULL; mp->b_datap->db_type = M_IOCACK; iocp->ioc_count = 0; qreply(q, mp); break;
Multiplexing STREAMS Multiplexor case D_IOCTL2: ... /* ioctl commands not recognized by the driver */ default: /* Send a negative acknowledgement upstream */ mp->b_datap->db_type = M_IOCNAK; qreply(q, mp); break; } break; case M_FLUSH: if (*mp->b_rptr & FLUSHW) { /* Flush the write queue */ ... } if (*mp->b_rptr & FLUSHR) { *mp->b_rptr &= ~FLUSHW; /* Flush the read queue if messages can be enqueued */ ...
Multiplexing STREAMS Multiplexor Lower Read Put Procedure The lower read put procedure receives upstream bound data from the lower stream. If the upper streams are flow controlled then messages can be queued on the lower read queue. The lower read put procedure acting like a stream head should do the following: • Handle the M_FLUSH messages. • Handle the M_ERROR and M_HANGUP messages appropriately. • Route other data messages to the upper streams based on the criteria set by the multiplexor.
Multiplexing STREAMS Multiplexor freemsg(mp); break; } /* end switch */ return; } 134 Chapter 5
Multiplexing STREAMS Multiplexor Service Procedure In a multiplexing configuration, the lower write side and the upper read side service procedures are required to handle the flow control in the lower and the upper streams respectively. The upper write side and the lower read side service procedures are optional.
Multiplexing STREAMS Multiplexor Upper Read Service Procedure The upper read service procedure is provided for flow control purposes only. It is scheduled to run when the flow control on the upper stream’s read side is lifted. If the multiplexor still has the lower stream linked to it, mux_ursrv() will enable the lower streams read queue.
Multiplexing STREAMS Multiplexor Lower Read Service Procedure The lower read service procedure is responsible for taking the messages of the read queue and routing them to the appropriate upper stream if there are no errors. It is assumed here that the messages arriving at the multiplexor's lower read queue contain the information regarding the destination stream, like a minor device number associated with the upper stream. The information is extracted and the message is appropriately routed.
Multiplexing STREAMS Multiplexor Multiplexor Specific Design Guidelines The following is a list of general multiplexor design guidelines, in addition to the guidelines specified for the driver development in Chapter 4. 1. The upper-half of the multiplexor must be designed to act as the stream end, or driver, for the streams above the multiplexor. 2. The lower-half of the multiplexor must be designed to act as the stream head for the streams linked below the multiplexor. 3.
A STREAMS IOCTL Commands Overview This appendix discusses the various STREAMS ioctl(s) commands. ioctl(2) Commands The STREAMS ioctl () commands are a subset of the ioctl (2) commands supported by HP-UX. They enable the user process to perform a variety of control functions on a stream. Synopsis The general syntax of an ioctl() directive is shown: #include #include int ioctl(int fildes, int command, ... /* arg */); fildes An open file descriptor that refers to a stream.
STREAMS IOCTL Commands Overview I_CANPUT Checks if a certain band is writable. The arg parameter is set to the priority band in question. The return value is 0, if the priority band arg is flow controlled. The return value is 1, if the band is writable, or -1 on error. On failure, errno may be set to the following value: [EINVAL] arg has an illegal value. I_CKBAND This command is used to check if the message of a given priority band exists on the stream head read queue.
STREAMS IOCTL Commands Overview On failure, errno is set to one of the following values: [EINVAL] The fildes parameter in the strfdinsert structure is an invalid open file descriptor. [EINVAL] The size of the pointer plus offset exceeds the value of the len field for the buffer specified through ctlptr. [EINVAL] Offset does not specify a properly aligned location in the data buffer. [EINVAL] Flags contains an undefined value.
STREAMS IOCTL Commands Overview If a pipe does not have any modules pushed, the read queue of the stream head on either end is flushed depending on the value of arg. If FLUSHR is set and fildes is a pipe, the read queue for that end of the pipe is flushed and the write queue for the other end is flushed. If FLUSHW is set, the read queue for the other end of the pipe is flushed and the write queue for this end is flushed. If FLUSHRW is set, the read queue of both ends of the pipe are flushed.
STREAMS IOCTL Commands Overview On failure, errno is set to the following value: [EINVAL] The arg has an illegal value. I_GETSIG This command returns the events for which the calling process has registered to receive a SIGPOLL signal. Events are returned as in arg bitmask as defined for the I_SETSIG command. On failure, errno is set to one of the following values: [EINVAL] User process is not registered to receive the SIGPOLL signal. [EFAULT] The arg points outside the allocated address space.
STREAMS IOCTL Commands Overview Acknowledgement message not received at stream head before timeout. [ETIME] The I_LINK IOCTL can also fail if an M_ERROR or M_HANGUP message is received at the stream head for fildes before receiving the driver acknowledgement. In addition, an error can be returned in an M_IOCACK or M_IOCNAK message. When these occur, the I_LINK IOCTL fails with errno set to the value in the message.
STREAMS IOCTL Commands Overview I_PEEK Allows the user process to look (peek) at the contents of the first message on the stream head read queue. This is done without taking the message off the queue. The I_PEEK IOCTL operates the same way as the getmsg() function, except that it does not remove the message. The arg parameter points to a strpeek structure (in the
STREAMS IOCTL Commands Overview The I_PLINK IOCTL can also fail if it is waiting for the multiplexing driver to acknowledge the link request and an error (M_ERROR) message, or hangup (M_HANGUP) message is received at the stream head for fildes. In addition, an error can be returned in an M_IOACK or M_IONAK message. When these occur, the I_PLINK fails with errno set to the value in the message. I_POP Removes the module just below the stream head of the stream pointed to by fildes.
STREAMS IOCTL Commands Overview I_RECVFD Retrieves the file descriptor associated with the message sent by an I_SENDFD IOCTL over a stream pipe. The arg is a pointer to a data buffer large enough to hold a strrecvfd data structure containing the following members: int fd; uid_t uid; gid_t gid; char fill[8]; The fd is an integer file descriptor, uid and gid are the user ID and group ID, respectively, of the sending stream.
STREAMS IOCTL Commands Overview I_SETSIG Informs the stream head that the user wants the kernel to issue the SIGPOLL signal (see signal (2)) when a particular event has occurred on the stream associated with fildes. The I_SETSIG supports an asynchronous processing capability in STREAMS. The value of arg is a bitmask that specifies the events for which the user should be signaled.
STREAMS IOCTL Commands Overview Setting both RMSGD and RMSGN is an error. RMSGD and RMSGN override NORM. In addition, treatment of control messages by the stream head may be changed by setting the following flags in arg: RPROTNORM Fail read with EBADMSG if a control message is at the front of the stream head read queue. This is the default behavior. RPROTDAT Deliver the control portion of a message as data when a user issues read.
STREAMS IOCTL Commands Overview [EFAULT] The arg points, or the buffer area specified by ic_dp or ic_len is, outside the allocated address space. [ENOSR] Buffers could not be allocated for the IOCTL request because of a lack of STREAMS memory resources. [ENXIO] A hangup was received on the stream referred to by fildes. [ETIME] The IOCTL request timed out before an acknowledgement was received.
B STREAMS Utilities Supported by HP-UX This Appendix deals with the STREAMS utilities supported by HP-UX. STREAMS utility routines are used to perform specific operations/functions in module and driver development. The streams utility routines are listed in alphabetical order.
STREAMS Utilities Supported by HP-UX NAME adjmsg () – Trim bytes in a message. SYNOPSIS #include int adjmsg (mblk_t *mp , int len); PARAMETERS mp Pointer to a message block in a message. This block will be treated as the start of the message. len The number of bytes to be removed. DESCRIPTION adjmsg() trims a specific number of bytes from either the head or tail of the message pointed by mp.
STREAMS Utilities Supported by HP-UX NAME allocb () – Attempts to allocate a new message block. SYNOPSIS #include mblk_t *allocb (int size, int pri); ARGUMENTS size The number of bytes in the message block. pri This field is no longer in use. It is provided for portability. DESCRIPTION The allocb() utility tries to allocate a message block with the requested data buffer. If the memory is not available, it will return with a NULL pointer.
STREAMS Utilities Supported by HP-UX NAME backq () – Returns a pointer to the queue behind a specified queue. SYNOPSIS #include queue_t *backq (queue_t *q); ARGUMENTS q Pointer to the head of the queue for a stream queue whose back queue is to be returned. RETURN VALUES backq() walks backwards from the specified q and returns a pointer to the queue whose q_next pointer is q. If no such queue exists, backq() returns NULL.
STREAMS Utilities Supported by HP-UX NAME bcanput () – Checks for the existence of a flow control condition in the queue for a specified priority band. SYNOPSIS #include int bcanput (queue_t *q, int pri); ARGUMENTS q Pointer to the queue. pri Priority band for which the flow control check is requested. DESCRIPTION bcanput() routine tests if there is room left in the queue for the band specified by pri.
STREAMS Utilities Supported by HP-UX NAME bcanputnext () – Checks for the existence of flow control in the queue for the specified priority band. SYNOPSIS #include int bcanputnext (queue_t *q, int pri); ARGUMENTS q Pointer to the queue. pri Priority band for which the flow control check is requested. DESCRIPTION bcanputnext() routine tests if there is room left in the queue (q->q_next) for the band specified in pri.
STREAMS Utilities Supported by HP-UX NAME bufcall (), streams_bufcall () – Recover from allocb() failures. SYNOPSIS include toid_t bufcall, (uint size, int prilev, (*func)(void *arg), void *art): toid_t streams_bufcall(uint size, int prilev, bufcall_fcn_t func, bufcall_arg_t arg); PARAMETERS size Requested buffer size prilev It is no longer used. This parameter is provided only for portability purposes. func Address of function to be called when requested memory is available.
STREAMS Utilities Supported by HP-UX NAME canenable () – Test whether queue can be enabled for running service procedure. SYNOPSIS #include int canenable (queue_t *q); PARAMETERS q Pointer to a queue. DESCRIPTION This function checks whether a service procedure for the specified queue can be scheduled for running. RETURN VALUES It returns 1 if the queue has not been disabled from running a service procedure and returns 0 if the queue is disabled.
STREAMS Utilities Supported by HP-UX NAME canput () – Test for available room in a queue. SYNOPSIS #include #include int canput (queue_t *q); PARAMETERS q Pointer to a queue. DESCRIPTION canput() routine tests if there is room left in the queue. If the queue does not have a service procedure, then it finds the queue that contains a service procedure in the direction of message flow and tests to see if messages can be enqueued.
STREAMS Utilities Supported by HP-UX NAME canputnext () – Checks for the flow control conditions in a stream. SYNOPSIS #include int canputnext (queue_t *q); PARAMETERS q Pointer to a queue. DESCRIPTION canputnext() routine tests if there is room left in the queue (q->q_next). If the queue does not have a service procedure, then it finds the queue that contains service procedure in the direction of message flow starting at q->q_next and tests to see if a message priority can be enqueued.
STREAMS Utilities Supported by HP-UX NAME cmn_err () – Display a message on the console and optionally panic the system. SYNOPSIS #include void cmn_err(int level, char *format...);/* args */ PARAMETERS level format Severity of the error condition. Takes one of the following values: CE_CONT Used to continue a previous message or to display an informative message not connected with an error. CE_NOTE To display the message preceded with NOTICE:.
STREAMS Utilities Supported by HP-UX NAME copyb () – Creates a copy of a specified message block. SYNOPSIS #include mblk_t *copyb (mblk_t *mp); PARAMETERS mp Pointer to message block from which data is to be copied. DESCRIPTION copyb() calls allocb() to allocate a new message. The new block will be at least as large as the block being copied.
STREAMS Utilities Supported by HP-UX NAME copymsg () – Makes a copy of a specified message. SYNOPSIS #include mblk_t *copymsg (mblk_t *mp); PARAMETERS mp Pointer to message to be copied. DESCRIPTION This function uses the copyb() utility to allocate and then copy message blocks from the message pointed by mp. It then forms the new message by appropriately linking the new message blocks together via b_cont pointer.
STREAMS Utilities Supported by HP-UX NAME datamsg () – Checks to see if a specified message type is a data message. SYNOPSIS #include int datamsg (unsigned char type); PARAMETERS type Type of the message to be tested. DESCRIPTION This function is typically invoked with the message type parameter mp->b_datap->db_type, where mp is a message pointer. This utility checks if it is a data message type: M_DATA, M_DELAY, M_PROTO or M_PCPROTO.
STREAMS Utilities Supported by HP-UX NAME drv_getparm () – Get kernel information. SYNOPSIS #include int drv_getparm (unsigned long parm, unsigned long *value_p); PARAMETERS parm A kernel parameter of: LBOLT, PPGRP, UPROCP, PPID, PSID, TIME, or UCRED. value_p A pointer to the address to put the result field into. DESCRIPTION Return the value of the parameter in parm. RETURN VALUES drv_getparm() returns 0 if the parm is recognized or -1 if not.
STREAMS Utilities Supported by HP-UX NAME drv_priv () – Get driver privilege. SYNOPSIS #include int drv_priv (cred_t * cr); PARAMETERS cr A pointer to a struct cred_t. DESCRIPTION Determine if the user has the correct credentials to perform a function. RETURN VALUES drv_priv() returns 0 if the caller has super user privilege otherwise EPERM. CONSTRAINTS drv_priv() can be called from thread or interrupt context. Spinlocks can be held across this call.
STREAMS Utilities Supported by HP-UX NAME dupb () – Pointer to the message block, which is to be duplicated. SYNOPSIS #include mblk_t *dupb (mblk_t *mp); PARAMETERS mp Pointer to message block descriptor that will be duplicated. DESCRIPTION dupb() allocates a new message block structure, and copies into it the message block structure pointed by mp. It does not copy the data buffer.
STREAMS Utilities Supported by HP-UX NAME dupbn () – Pointer to the message block, which is to be duplicated n times. SYNOPSIS #include mblk_t *dupbn (mblk_t *mp, int n); PARAMETERS mp Pointer to message block descriptor that will be duplicated. n Number of duplicates. DESCRIPTION dupbn() allocates a new message block structure, and copies into it the message block structure pointed by mp. It does not copy the data buffer.
STREAMS Utilities Supported by HP-UX NAME dupmsg () – Duplicates a message. SYNOPSIS #include mblk_t *dupmsg (mblk_t *mp); PARAMETERS mp Pointer to a message block, which is to be duplicated. DESCRIPTION This function calls dupb() to duplicate all message block descriptors starting at mp, and then links the message block descriptors to form a new message. It does not copy data buffers.
STREAMS Utilities Supported by HP-UX NAME enableok () – Allows the service procedure for the specified queue to be scheduled. SYNOPSIS #include void enableok(q); PARAMETERS q Queue pointer. DESCRIPTION This function allows the service procedure for a queue to be scheduled. It does not actually schedule the service procedure. It simply undoes the effect of a previously executed noenable() function on this queue. If the queue was already enabled for servicing, enableok() has no effect.
STREAMS Utilities Supported by HP-UX NAME esballoc () – Allocate a message block using a caller specified buffer. SYNOPSIS #include mblk_t *esballoc(uchar_t *base, int size, int pri, frtn_t *fr_rtnp); PARAMETERS base Pointer to caller data buffer. size Size of the data block. pri Priority of data block. It is no longer used. It is provided only the portability. fr_rtnp Pointer to free_rtn structure.
STREAMS Utilities Supported by HP-UX NAME esbbcall () – Call a function when a caller-supplied buffer can be allocated. SYNOPSIS #include toid_t esbbcall(int pri, void (*bufcall_fcn_t), long bufcall_arg_t); PARAMETERS pri It is no longer used. This parameter is provided only for portability purposes. bufcall_fcn_t Address of function to be called when requested memory is available. bufcall_arg_t Pointer to argument list to be passed to the function pointed to by bufcall_fcn_t.
STREAMS Utilities Supported by HP-UX NAME flushband () – Flushes the messages specified in the priority band. SYNOPSIS #include #include void flushband (queue_t *q, unsigned char pri, int flag); PARAMETERS q Queue pointer pri Priority band to be flushed flag Determines the type of the messages to be flushed. Valid flag values are: FLUSHDATA Flush data messages only (M_DATA, M_PROTO, M_PCPROTO and M_DELAY). FLUSHALL Flush all messages.
STREAMS Utilities Supported by HP-UX NAME flushq () – Flushes the specified queue. SYNOPSIS #include void flushq(queue_t *q, int flag); PARAMETERS q Queue pointer. flag Determines messages to be flushed. Valid flag values are: FLUSHDATA Flush data messages only (M_DATA, M_PROTO, M_PCPROTO, M_DELAY). FLUSHALL Flush all messages. DESCRIPTION flushq() uses the freemsg() function to free each relevant message in the queue, based on the flag parameter value.
STREAMS Utilities Supported by HP-UX NAME freeb () – Deallocates a message block. SYNOPSIS #include void freeb (mblk_t *mp); PARAMETERS mp Pointer to the message block to be deallocated. DESCRIPTION freeb() deallocates a message block, and if the db_ref count of the datab structure it is pointing to is greater than 1, it decrements the db_ref count by 1 and deallocates only the message block descriptor.
STREAMS Utilities Supported by HP-UX NAME freemsg () – Frees a STREAMS message. SYNOPSIS #include void freemsg (mblk_t *mp); PARAMETERS mp Pointer to the message to be freed. DESCRIPTION This function calls freeb() to free all message blocks and corresponding data blocks and data buffers associated with the message, beginning at mp. RETURN VALUES None CONSTRAINTS freemsg() can be called from thread or interrupt context.
STREAMS Utilities Supported by HP-UX NAME freezestr () – Freeze the state of a queue. SYNOPSIS #include pl_t freezestr(queue_t *q); PARAMETERS q Pointer to a message queue. DESCRIPTION For modules/drivers configured at a synchronization level other than SQLVL_NOSYNC, STREAMS/UX uses a different mechanism to protect the queues. The freezestr() utility in these modules/drivers returns the current interrupt priority level, and is only provided to make porting code from SVR4 MP easier.
STREAMS Utilities Supported by HP-UX NAME getadmin () – Returns a pointer to the module administration function. SYNOPSIS #include #include int (*getadmin(ushort_t mid))(); PARAMETERS mid Module ID of module/driver, for which the administration function pointer is needed. DESCRIPTION getadmin() returns a pointer to the module administration function. The module administration function is pointed to by qqadmin, a member of the qinit structure.
STREAMS Utilities Supported by HP-UX NAME getmid () – getmid returns the module identifier for a specified module or driver name. SYNOPSIS #include #include ushort_t getmid (char *name); PARAMETERS name Name of module/driver. DESCRIPTION This function looks into the module_info structure for the module/driver as specified in name and retrieves the mi_idnum value.
STREAMS Utilities Supported by HP-UX NAME getq () – gets the next message from the head of the queue. SYNOPSIS #include mblk_t *getq(queue_t *q); PARAMETERS q Pointer to the queue from which the message is to be retrieved. DESCRIPTION getq() is used typically by the service procedure of a module/driver to retrieve the messages from the message queue. RETURN VALUES If there is a message left in the queue to be retrieved, getq returns a pointer to that message.
STREAMS Utilities Supported by HP-UX NAME insq () – To insert a message into a queue. SYNOPSIS #include int insq (queue_t *q, mblk_t *mp, mblk_t *newmp); PARAMETERS q Queue pointer. mp Pointer to message before which the new message is to be inserted. newmp Pointer to the new message to be inserted. DESCRIPTION The new message is inserted before the message pointed to by mp. The new message will be placed in an appropriate priority order, i.e.
STREAMS Utilities Supported by HP-UX NAME linkb () – Concatenates two messages. SYNOPSIS #include void linkb (mblk_t *mp1, mblk_t *mp2); PARAMETERS mp1 Pointer to first message block. mp2 Pointer to the second message block that will be linked to mp1. DESCRIPTION linkb() links message mp2 to message mp1. Data blocks and data buffers remain untouched.
STREAMS Utilities Supported by HP-UX NAME LOCK () – Acquire a spinlock. SYNOPSIS #include spl_t LOCK (lock_t *lockptr, spl_t prilev); PARAMETERS lockptr Pointer to lock to be acquired. prilev Priority level to be set for the calling interrupt, while it holds the lock. In STREAMS/UX this parameter is ignored. DESCRIPTION LOCK acquires the lock specified by lockp. If the lock is not available the caller thread will busy wait until the lock becomes available.
STREAMS Utilities Supported by HP-UX NAME LOCK_ALLOC () – Allocates spinlock structure. SYNOPSIS #include #include lock_t *LOCK_ALLOC (uchar_t hierarchy, spl_t min_prilev, lkinfo_t *lkinfoptr, int flag); PARAMETERS hierarchy Hierarchy determines the order in which this lock is to be acquired. The STREAMS/UX LOCK_ALLOC() accepts the following hierarchy of parameter values. These are reserved for STREAMS/UX modules and drivers.
STREAMS Utilities Supported by HP-UX NAME LOCK_DEALLOC () – Deallocates an acquired lock. SYNOPSIS #include void LOCK_DEALLOC(lock_t *lockptr); PARAMETERS lockptr Pointer to the lock that is to be deallocated. RETURN VALUES None CONSTRAINTS LOCK_DEALLOC() can be called from thread or interrupt context. Only spinlocks with STREAMS/UX user lock order can be held across this call.
STREAMS Utilities Supported by HP-UX NAME msgdsize () – Gets the number of data bytes in a message. SYNOPSIS #include int msgdsize (mblk_t *mp); PARAMETERS mp Pointer to the message. DESCRIPTION msgdsize() returns the total number of bytes in a message block of type M_DATA. RETURN VALUES msgdsize() returns the number of bytes of data in the message. CONSTRAINTS msgdsize() can be called from thread or interrupt context. Spinlocks can be held across this call.
STREAMS Utilities Supported by HP-UX NAME msgpullup () – Concatenates a specified number of bytes from a message into a new message. SYNOPSIS #include mblk_t *msgpullup (mblk_t *mp, int len); PARAMETERS mp Pointer to the message. len Number of bytes to be concatenated. If len is set to -1, all data bytes are concatenated. DESCRIPTION msgpullup concatenates and aligns the first len data bytes of the message pointed to by mp, copying the data into a new message.
STREAMS Utilities Supported by HP-UX NAME noenable () – Prevents a queue from being scheduled. SYNOPSIS #include void noenable (queue_t *q); PARAMETERS q Pointer to a queue. DESCRIPTION This function prevents the scheduling of the service procedure for the queue pointed by q. The noenable() does not prevent the queue’s service procedure from being scheduled when a high priority message is enqueued, or by an explicit call to qenable.
STREAMS Utilities Supported by HP-UX NAME OTHERQ () – Returns the pointer to queue’s partner queue. SYNOPSIS #include queue_t *OTHERQ (queue_t *q); ARGUMENTS q Pointer to the queue. DESCRIPTION The OTHERQ() returns a pointer to the other of the queue-pair structures that make up a STREAMS module/driver. If q points to the read queue, the write queue will be returned and vice versa. RETURN VALUES OTHERQ() returns a pointer to a queue’s partner.
STREAMS Utilities Supported by HP-UX NAME pcmsg () – Checks if a specified message type is a priority control message. SYNOPSIS #include int pcmsg (uchar_t type); PARAMETERS type The type of the message to be tested. DESCRIPTION pcmsg() is used by put and service procedures of a module or driver. Typical use of pcmsg is for a put procedure to determine whether to process the message immediately or to place it on the queue for deferred processing.
STREAMS Utilities Supported by HP-UX NAME pullupmsg () – pullupmsg concatenates multiple message blocks into a single message block. SYNOPSIS #include int pullupmsg (mblk_t *mp, int len); PARAMETERS mp Pointer to message whose message blocks are to be concatenated. len Number of bytes to be concatenated. If len = -1, all message blocks from the original message are concatenated into a single message block.
STREAMS Utilities Supported by HP-UX NAME put () – Calls a driver or module’s put procedure. SYNOPSIS #include void put(queue_t *q, mblk_t *mp); PARAMETERS q Pointer to a queue. mp Pointer to a message block. DESCRIPTION This function is called by modules and drivers to invoke their own put procedure (for the specified queue) to operate on the specified message. RETURN VALUES None CONSTRAINTS put() can be called from thread or interrupt context.
STREAMS Utilities Supported by HP-UX NAME putbq () – Places a message back at the head of a queue. SYNOPSIS #include int putbq (queue_t *q, mblk_t *mp); PARAMETERS q Pointer to the queue. mp Pointer to the message. DESCRIPTION This function places the specified message at its assigned priority as close to the head of the queue as possible.
STREAMS Utilities Supported by HP-UX NAME putctl () – Send a control message to the queue. SYNOPSIS #include int putctl(queue_t *q, int type); PARAMETERS q The queue to which the message is sent. type The type of control message to be allocated and passed to the put procedure of the queue. DESCRIPTION This function allocates a message block and assigns the specified control message type. Then it invokes the put procedure for the specified queue with this newly allocated message.
STREAMS Utilities Supported by HP-UX NAME putctl1 () – Send a control message with one data byte. SYNOPSIS #include int putctl1 (queue_t *q, int type, int parm); PARAMETERS q Pointer to queue. type The type of the control message to be passed to the queue. DESCRIPTION putctl1() works exactly like putctl() with the addition that it allows a 1-byte parameter to be part of the control message. The parameter addition allows for stronger control message functionality.
STREAMS Utilities Supported by HP-UX NAME putctl2 () – Send a control message with two byte data. SYNOPSIS #include int putctl2 (queue_t *q, int type, int parm1, int parm2); PARAMETERS q Pointer to the queue to which the control message is to be sent. type Message type parm1 & parm2 Two 1-byte data parameters DESCRIPTION putctl2() is an enhanced version of putctl1(). It allows for two 1-byte parameters to accompany the control message.
STREAMS Utilities Supported by HP-UX NAME putnext () – To pass a message to the next queue. SYNOPSIS #include int putnext (queue_t *q, mblk_t *mp); PARAMETERS q Pointer to the queue from which this message is to be sent. mp Pointer to the message block to be sent. DESCRIPTION putnext() is used for passing messages to the next queue in a stream. This utility calls put procedure associated with the next queue (q->q_next) in a stream and passes it a message block pointer as an argument.
STREAMS Utilities Supported by HP-UX NAME putnextctl () – Send control message with one byte parameter to the next queue. SYNOPSIS #include int putnextctl1 (queue_t *q, int type, int parm); PARAMETERS q Pointer to the queue from which the control message is to be sent. type Type of the control message. parm 1-byte data parameter. DESCRIPTION putnextctl1() behaves exactly like putnextctl() with the addition of a 1-byte parameter to the control message.
STREAMS Utilities Supported by HP-UX NAME putnextctl2 () – Send control message with two byte parameter to the next queue. SYNOPSIS #include int putnextctl2 (queue_t *q, int type, int parm1, int parm2); PARAMETERS q Pointer to the queue from which the control message is being sent. type Message type. parm1 & parm2 Two one byte parameters.
STREAMS Utilities Supported by HP-UX NAME putq () – Enqueue message on the queue for deferred processing. SYNOPSIS #include int putq (queue_t *q, mblk_t *mp); PARAMETERS q Pointer to the queue in which the message is to be put. mp Pointer to the message. DESCRIPTION putq() is typically used by put procedure for deferred processing of the messages. The putq() enqueues the message mp in the message queue based on its priority.
STREAMS Utilities Supported by HP-UX NAME qenable () – Schedule service procedure to run. SYNOPSIS #include void qenable (queue_t *q); PARAMETERS q Pointer to the queue whose service procedure is to be scheduled. DESCRIPTION qenable() places the specified queue in a linked list of queues whose corresponding service procedure is to be executed by the STEAMS scheduler. When invoked, this function ignores the noenable() status of the queue, and schedules the service procedure.
STREAMS Utilities Supported by HP-UX NAME qprocsoff () – Disable put and service procedures. SYNOPSIS #include void qprocsoff(queue_t *q); PARAMETERS q Pointer to a read queue. DESCRIPTION STREAMS/UX only provides stubs which are no-ops for qprocson and qprocsoff to make porting easier.
STREAMS Utilities Supported by HP-UX NAME qprocson () – Enable put and service procedures. SYNOPSIS #include void qprocson(queue_t *q); PARAMETERS q Pointer to a read queue. DESCRIPTION STREAMS/UX only provides stubs which are no-ops for qprocson and qprocsoff to make porting easier.
STREAMS Utilities Supported by HP-UX NAME qreply () – Sends a message back in a opposite direction. SYNOPSIS #include void qreply (queue_t *q, mblk_t *mp); PARAMETERS q Pointer to queue from which a message is to be passed in the opposite direction. mp Pointer to message to be passed as a reply. DESCRIPTION This function passes a message back in the opposite direction from the currently processing flow.
STREAMS Utilities Supported by HP-UX NAME qsize () – Returns the number of messages in a queue. SYNOPSIS #include int qsize (queue_t *q); PARAMETERS q Pointer to queue. RETURN VALUES This function returns the number of messages in the specified queue. If the message queue is empty, 0 is returned. CONSTRAINTS qsize() can be called from thread or interrupt context.
STREAMS Utilities Supported by HP-UX NAME RD () – get a pointer to the read queue. SYNOPSIS #include queue_t *RD(queue_t *q); PARAMETERS q Pointer to the queue whose read queue is to be returned. DESCRIPTION The RD() macro accepts a queue pointer, q, as argument and returns a pointer to the read queue of the same module. RETURN VALUES The pointer to the read queue. CONSTRAINTS RD() can be called from thread or interrupt context. Spinlocks can be held across calls to this function.
STREAMS Utilities Supported by HP-UX NAME rmvb () – Removes a message block from a message. SYNOPSIS #include mblk_t *rmvb (mblk_t *mp, mblk_t *bp); PARAMETERS mp Pointer to message from which message block is to be removed. bp Pointer to message block targeted for removal. DESCRIPTION rmvb() removes the message block pointed to by bp from the message pointed to by mp, and returns a pointer to the altered message. The message block is just removed from the message.
STREAMS Utilities Supported by HP-UX NAME rmvq () – Removes a message from a queue. SYNOPSIS #include void *rmvq (queue_t *q, mblk_t *mp); PARAMETERS q Pointer to the queue from which a message is to be removed. mp Pointer to the message targeted for removal. DESCRIPTION rmvq() removes a message pointed to by mp from the queue specified by q. All flow control parameters for the queue are appropriately updated.
STREAMS Utilities Supported by HP-UX NAME SAMESTR () – Test if next queue is of the same type. SYNOPSIS #include int SAMESTR(queue_t *q); PARAMETERS q Pointer to the queue. DESCRIPTION The SAMESTR() macro checks whether the next queue in a stream (if it exists) is of the same type (read/write) as the current queue. This macro can be used to determine the midpoint in a STREAMS-based pipe or welded streams where the read queue is linked to the write queue.
STREAMS Utilities Supported by HP-UX NAME streams_delay () – Delay process execution for a specified number of clock ticks. SYNOPSIS #include #include void streams_delay(int ticks); PARAMETERS ticks The number of clock ticks to delay. DESCRIPTION streams_delay() causes the caller to sleep for at least the amount of time specified by ticks, which is in units of clock ticks.
STREAMS Utilities Supported by HP-UX NAME streams_get_sleep_lock () – Obtain the sleep lock. SYNOPSIS #include #include lock_t *streams_get_sleep_lock(caddr_t event); PARAMETERS event Kernel address signifying an event for which the caller wishes to wait in sleep. DESCRIPTION streams_get_sleep_lock() should be called by modules and drivers in their open/close routines before sleeping to prevent missing wakeups.
STREAMS Utilities Supported by HP-UX NAME streams_mpsleep () – Suspend process execution pending occurrence of an event. SYNOPSIS #include #include int streams_mpsleep(caddr_t event, int pri, caddr_t mesg, int tmo, void *lockp, int flags); PARAMETERS event Kernel address signifying an event for which the caller wishes to wait. pri Priority value the caller wishes to sleep at. mesg Not used, provided for portability.
STREAMS Utilities Supported by HP-UX ETIME — the process was woken up after tmo ticks elapsed. CONSTRAINTS streams_mpsleep() will block and so must only be called from the driver/module’s open or close routine. Only spinlock specified by lockp and the sleep lock can be held on entry (these locks will be released by streams_mpseleep()). Spinlocks (with the exception of those previously mentioned) cannot be held across this call.
STREAMS Utilities Supported by HP-UX NAME streams_put () – Allows non-STREAMS code to safely call STREAMS/UX utilities. SYNOPSIS #include void streams_put(streams_put_t func, queue_t *q, mblk_t *mp, void *arg); PARAMETERS func Function to be executed in the STREAMS context. q Queue pointer. mp Pointer to valid message block. arg Argument pointer to be passed to func. DESCRIPTION Non-STREAMS/UX code can call streams_put, passing it a function and a queue.
STREAMS Utilities Supported by HP-UX NAME streams_time () – Get time. SYNOPSIS #include #include time_t streams_time(); PARAMETERS None DESCRIPTION streams_time() returns the value of time in seconds since the Epoch. RETURN VALUES streams_time() returns the value of time in seconds since the Epoch. CONSTRAINTS streams_time() can be called from thread or interrupt context. Spinlocks must not be held across this function call.
STREAMS Utilities Supported by HP-UX NAME streams_timeout () – Schedule a timeout to execute a specified function after a specified time delay. SYNOPSIS #include #include toid_t *streams_timeout (timeout_fcn_t func, timeout_arg_t arg, int ticks, pl_t prilev, int call_mp_timeout); PARAMETERS func Function to be executed after a specified time interval. arg Argument passed to the timeout handler. ticks Number of ticks after which the function is to be executed.
STREAMS Utilities Supported by HP-UX NAME streams_untimeout () – Cancel pending timeout request scheduled through streams_timeout(). SYNOPSIS #include #include int streams_untimeout(toid_t id); PARAMETERS id Non-zero identifier returned from a prior call to streams_timeout(). DESCRIPTION The streams_untimeout() cancels the pending timeout request specified by id, scheduled through a call to streams_timeout() earlier.
STREAMS Utilities Supported by HP-UX NAME strlog () – Submit messages for logging to streams log driver. SYNOPSIS #include #include #include int strlog(short mid, short sid, char level, ushort_t flags, char *fmt, ... /* args */); PARAMETERS mid STREAMS module id for the module/driver submitting the message for logging. sid Refers to the sub-ID number of a minor device of the driver associated with the STREAMS module or driver identified by mid.
STREAMS Utilities Supported by HP-UX CONSTRAINTS strlog() can be called from thread or interrupt context. Spinlocks must not be held across this call.
STREAMS Utilities Supported by HP-UX NAME strqget () – Retrieves information about a queue or priority band of the queue. SYNOPSIS #include #include int strqget (queue_t *q, qfields_t what, uchar_t band, long *valp); PARAMETERS q Pointer to the queue. what The field of the queue about which to return information. Valid what values are: QHIWAT High water mark of the specified priority band. QLOWAT Low water mark of the specified priority band.
STREAMS Utilities Supported by HP-UX NAME strqset () – Set the information in a queue or a queue band. SYNOPSIS #include #include int strqset (queue_t *q, qfields_t what, uchar_t pri, long newval); PARAMETERS q Pointer to the queue. what The field of the queue about which to return information. Valid what values are: QHIWAT High water mark of the specified priority band. QLOWAT Low water mark of the specified priority band.
STREAMS Utilities Supported by HP-UX CONSTRAINTS strqset() can be called from thread or interrupt context. Only spinlocks of STREAMS/UX user lock order can be held across this call.
STREAMS Utilities Supported by HP-UX NAME SV_ALLOC () – Allocate and initialize a synchronization variable. SYNOPSIS #include sv_t *SV_ALLOC(int flag); PARAMETERS flag Specifies whether the caller is willing to sleep waiting for memory. Valid flags are: KM_SLEEP Caller willing to sleep. KM_NOSLEEP Caller cannot sleep. DESCRIPTION SV_ALLOC dynamically allocates and initializes an instance of a synchronization variable.
STREAMS Utilities Supported by HP-UX NAME SV_BROADCAST () – Wake up all processes sleeping on a synchronization variable. SYNOPSIS #include void SV_BROADCAST(sv_t *svp, int flags); PARAMETERS svp Pointer to the synchronization variable to be broadcast signaled. flags Bit field for flags. No flags are currently defined for use in drivers and the flags argument must be set to zero.
STREAMS Utilities Supported by HP-UX NAME SV_DEALLOC () – Deallocate an instance of a synchronization variable. SYNOPSIS #include void SV_DEALLOC(sv_t *svp); PARAMETERS svp Pointer to the synchronization variable to be deallocated. DESCRIPTION SV_DEALLOC deallocates the synchronization variable specified by svp. RETURN VALUES None CONSTRAINTS SV_DEALLOC() does not sleep and so can be called from thread and the interrupt context.
STREAMS Utilities Supported by HP-UX NAME SV_WAIT () – Sleep on a synchronization variable. SYNOPSIS #include void SV_WAIT(sv_t *svp, int priority, lock_t *lkp); PARAMETERS svp Pointer to the synchronization variable on which to sleep. priority The priority value passed here is subtracted from PZERO-1. pridisk, prinet, pritty, pritape, prihi, primed and prilo are defined to be 0 and do not affect the caller’s priority.
STREAMS Utilities Supported by HP-UX NAME SV_WAIT_SIG () – Sleep on a synchronization variable. SYNOPSIS #include bool_t SV_WAIT_SIG(sv_t *svp, int priority, lock_t *lkp); PARAMETERS svp Pointer to the synchronization variable on which to sleep. priority The priority value passed here is added to PZERO+1 and ORed with PCATCH. pridisk, prinet, pritty, pritape, prihi, primed and prilo are defined to be 0 and do not affect the caller’s priority.
STREAMS Utilities Supported by HP-UX NAME TRYLOCK () – Try to acquire a basic lock. SYNOPSIS #include spl_t TRYLOCK(lock_t *lockp, spl_t pl); PARAMETERS lockp Pointer to the basic lock to be acquired. pl This value is ignored, and retained for portability only. DESCRIPTION If the lock specified by lockp is immediately available (can be acquired without waiting) TRYLOCK acquires the lock. If the lock is not immediately available, the function returns without acquiring the lock.
STREAMS Utilities Supported by HP-UX NAME testb () – Tests for an available buffer. SYNOPSIS #include int testb (int bufsize, unsigned int pri); PARAMETERS bufsize Message buffer size in bytes. pri This field is obsolete. DESCRIPTION testb() tests if a STREAMS message of specified size can be allocated. It returns 1 if memory is available, otherwise it returns 0. Successful return from this call does not guarantee successful memory allocation for a subsequent allocb() call.
STREAMS Utilities Supported by HP-UX NAME unbufcall () – Cancels a pending bufcall() or esbcall() request specified by ID. SYNOPSIS #include void unbufcall (toid_t id); PARAMETERS id A Non zero identifier returned from a prior bufcall() or esbbcall(). DESCRIPTION If unbufcall() is invoked while any function called by the pending bufcall() or esbbcall() request is running, unbufcall() will not return until the function completes or the pending request is cancelled.
STREAMS Utilities Supported by HP-UX NAME unfreezestr () – Unfreeze the frozen queue. SYNOPSIS #include void unfreezestr(queue_t *q, pl_t pl); PARAMETERS q Pointer to a message queue. pl The interrupt priority level to be set after unfreezing the stream. (This value is ignored, but has been retained for portability.) DESCRIPTION unfreezestr() unfreezes the queue specified by q.
STREAMS Utilities Supported by HP-UX NAME unlinkb () – Removes the first message block from the head of a message. SYNOPSIS #include mblk_t *unlinkb(mblk_t *mp); PARAMETERS mp Pointer to message from which the first block is to be removed. DESCRIPTION unlinkb() will unlink the first message block from the message and the altered message is returned to the caller. It is the responsibility of the module or driver to actually free the message block.
STREAMS Utilities Supported by HP-UX NAME UNLOCK () – Release the previously acquired lock. SYNOPSIS #include void UNLOCK (lock_t *lockptr, spl_t prilev); PARAMETERS lockptr Pointer to lock targeted for release. prilev This parameter is ignored as STREAMS always acquires the spinlock at SPL6. DESCRIPTION UNLOCK() calls the native HP-UX spinunlock primitive to release the previously acquired lock. RETURN VALUES None CONSTRAINTS UNLOCK() can be called from thread or interrupt context.
STREAMS Utilities Supported by HP-UX NAME unweldq () – Disconnects previously established weld connection. SYNOPSIS #include int unweldq (queue_t *d1_wq, queue_t *d2_rq, queue_t *d2_wq, queue_t *d1_rq, weld_fcn_t func, weld_arg_t arg, queue_t *protect_q); PARAMETERS d1_wq, d1_rq First drivers’ write and read queues. d2_wq, d2_rq Second drivers’ write and read queues func and arg Optional callback function pointer and argument for callback.
STREAMS Utilities Supported by HP-UX NAME vtop () – Convert virtual address to physical address. SYNOPSIS #include paddr_t vtop(caddr_t vaddr, proc_t *p); PARAMETERS vaddr Virtual address to convert. p Pointer to the process structure used. To indicate that the address is in kernel virtual space, p must be set to NULL. DESCRIPTION vtop() converts a virtual address to a physical address. RETURN VALUES On success, vtop() returns the physical address.
STREAMS Utilities Supported by HP-UX NAME WR () – Get pointer to the write queue. SYNOPSIS #include queue_t *WR(queue_t *q); PARAMETERS q Pointer to the queue whose write queue is to be returned. DESCRIPTION The macro WR() accepts a queue pointer as an argument and returns a pointer to the write queue of the same module. RETURN VALUES The pointer to the write queue. CONSTRAINTS WR() can be called from thread or interrupt context. Spinlocks can be held across the calls to WR().
STREAMS Utilities Supported by HP-UX NAME weldq () – Establish connections between two drivers’ queues. SYNOPSIS #include int weldq (queue_t *d1_wq, queue_t *d2_rq, queue_t *d2_wq, queue_t *d1_rq, weld_fcn_t func, weld_arg_t arg, queue_t *protect_q); PARAMETERS d1_wq, d1_rq First drivers’ write and read queues. d2_wq, d2_rq Second drivers’ write and read queues func and arg Optional callback function pointer and argument for callback.
STREAMS Utilities Supported by HP-UX 238 Appendix B
C Message Types This section describes the fixed set of message types recognized by STREAMS/UX. As described in Chapter 3, “Messages,” STREAMS messages can be classified as ordinary (non-priority) messages that are subject to flow control, and high priority messages that are not subject to flow-control. STREAMS defined message types differ in their intended purposes, their treatment at the stream head, and their message queueing priority.
Message Types Ordinary Messages Ordinary Messages M_BREAK This message is sent to a driver to transmit a BREAK on the device controlled by the driver. The message format for an M_BREAK is defined by the driver developer. This message is never generated from a user process, and is discarded when received by the stream head. This message may be considered as a special case of the M_CTL message.
Message Types Ordinary Messages Where ic_cmd describes the command intended for module or driver, ic_timout specifies the number of seconds that the I_STR request will wait for an acknowledgement before timing out. ic_dp points to the data buffer, and ic_len is the length of the data buffer passed in and, on return from the call, it contains the length of the data (if any) in the being returned to the user. An M_IOCTL message consists of an M_IOCTL message block followed by zero or more M_DATA blocks.
Message Types Ordinary Messages No data can be sent to the user with an M_IOCNAK message. The stream head will free any M_DATA blocks linked to the M_IOCNAK message block. If the stream head does not receive an M_IOCACK or M_IOCNAK message in response to an M_IOCTL (same ioc_id) message, it will block for all IOCTL calls except for I_STR IOCTL.
Message Types Ordinary Messages Where so_flags specifies the options to be altered. The options can be any combination of the following: SO_ALL Update all options according to the values specified in the remaining fields of the stroptions structure. SO_READOPT Set the read mode as specified in the so_readopt field.
Message Types Ordinary Messages SO_ISTTY Notify the stream head that the stream is acting as a controlling terminal. SO_ISNTTY Notify the stream head that the stream is no longer a controlling terminal. For SO_ISTTY, the stream may or may not be allocated as a controlling terminal via an M_SETOPTS message arriving upstream during open processing.
Message Types Ordinary Messages • If the signal is not SIGPOLL and the stream is not a controlling tty, no signal is sent, except in case of SIOCSPGRP and TIOCSPGRP. These two IOCTL commands set the process group field in the stream head so the stream can generate signals even if it is not a controlling tty. M_TRAIL This message is generated and sent upstream by a driver after the M_HANGUP message. It marks the end of data after an M_HANGUP message.
Message Types High Priority Messages High Priority Messages M_CLOSE This message is generated by the stream head to notify driver of a close (2) when the driver specifies C_ALLCLOSES in the d_flags field of drv_ops_t structure. When the C_ALLCLOSES flag is set, STREAMS sends an M_CLOSE message downstream when a close is issued on the driver. It then waits for a reply from the driver.
Message Types High Priority Messages M_COPYOUT The M_COPYOUT message is generated by modules or drivers to request a copyout() to be performed on their behalf by stream head. This message is valid only after receiving the M_IOCTL message by a module or driver and before an M_IOCACK or M_IOCNAK message is sent upstream by a module or driver. The format of a M_COPYOUT message is one message block of M_COPYOUT linked to one more M_DATA blocks containing data to be copied to the user’s buffer.
Message Types High Priority Messages • If FLUSHR or FUSHRW is set, it flushes the read-queue, clears the FLUSHW flag and sends the message upstream. When a stream head receives an M_FLUSH message, it does the following: • If only FLUSHR is set, it flushes the read-queue and frees the message. • If FLUSHW or FLUSHRW is set, it flushes the write-queue, turns the M_FLUSH message around, and sends it downstream.
Message Types High Priority Messages M_IOCNAK This message is generated by a module and sent back to the stream as a negative acknowledgment of an M_IOCTL message. The M_IOCNAK message format is one M_IOCNAK block (containing iocblk structure, see M_IOCTL). The ioc_error field in iocblk structure can be used to communicate any processing errors, back to the user in errno. Unlike the M_IOCACK message, no user data or return values can be sent with the M_IOCNAK message.
Message Types High Priority Messages M_PCRSE This is a priority message type reserved for internal use. Modules that do not recognize this message must pass it on. Drivers that do not recognize it must free it. M_PCSIG This message is similar to the M_SIG message type, except for the priority. M_PCSIG is generally preferred over M_SIG, as it is not subject to flow control.
D STREAMS Administrative Driver Overview This appendix discusses the STREAMS Administrative Driver (SAD). SAD The STREAMS Administrative Driver (SAD) provides an interface to the autopush facility using the ioctl (2) function. As an interface, the sad driver enables administrative tasks to be performed on STREAMS modules and drivers.
STREAMS Administrative Driver Overview SAP_CLEAR Clears the previous settings. Specifies only the sap_major and sap_minor fields when using this command. If a previous entry specified SAP_ALL, set the sap_minor field to 0 (zero). If a previous entry was specified as SAP_RANGE, set the sap_minor field to the lowest minor device number in the range. sap_major: Major device number. sap_minor: Minor device number. sap_lastminor: Range of minor devices. sap_npush: Number of modules to push.
STREAMS Administrative Driver Overview Return Value Unless specified otherwise, upon successful completion, the sad IOCTL commands return a value of 0 (zero). Otherwise, a value of -1 is returned. Errors If any of the following conditions occur, the sad IOCTL commands return the corresponding value: SAD_SAP [EEXIST] The specified major/minor device number pair (sad_major/sad_minor) has already been configured. [EFAULT] The arg parameter points outside the allocated address space.
STREAMS Administrative Driver Overview 254 Appendix D
E Differences Between STREAMS/UX and System V Release 4 STREAMS This appendix summarizes the differences between STREAMS/UX and System V Release 4.2 STREAMS. This appendix will be divided into the following categories for describing differences between HP-UX and SVR4.
Differences Between STREAMS/UX and System V Release 4 STREAMS HP-UX Changes to STREAMS Commands HP-UX Changes to STREAMS Commands STREAMS/UX supports the commands listed below: • autopush • fdetach • strace • strchg • strclean • strconf • strerr • strvf HP versions of supported STREAMS/UX commands operate somewhat differently from the way the commands are described in the UNIX SVR4.2 Command Reference manual. NLS catalogs exist for the commands. The catalogs are called autopush.
Differences Between STREAMS/UX and System V Release 4 STREAMS HP-UX Changes to STREAMS/UX System Calls HP-UX Changes to STREAMS/UX System Calls STREAMS/UX supports the following system calls: • close • fattach • fcntl • fdetach • getmsg • getpmsg • ioctl • isastream • open • pipe • poll • putmsg • putpmsg • read • readv • select • signal • write • writev For STREAMS-based termio, see the following manpages (which are part of the STREAMS-TIO product): grantpt (3C), ptsn
Differences Between STREAMS/UX and System V Release 4 STREAMS HP-UX Changes to STREAMS/UX System Calls NOTE The multiplexor ID number returned by I_LINK and I_PLINK is opaque to the user and not a small integer such as 0, 1, 2, 3. pipe Modifications STREAMS/UX supports STREAMS-based pipes as an optional feature. STREAMS/UX’s STREAMS-based pipes behave as described in the UNIX SVR4.2 Operating System API Reference and the UNIX System V Release 4 Programmer’s Guide: STREAMS.
Differences Between STREAMS/UX and System V Release 4 STREAMS HP-UX Changes to STREAMS/UX System Calls Write Offset A module or driver can send the stream head an M_SETOPTS message, telling the STREAM head to put an offset in the beginning of the first data block in a message sent by a putmsg call. STREAMS/UX will not put the offset into the data block if the amount of memory required is greater than the page size. select Modifications STREAMS/UX supports the select system call for STREAMS devices.
Differences Between STREAMS/UX and System V Release 4 STREAMS HP-UX Changes to STREAMS/UX System Calls • Closing an event port The poll (7) manpages provide more information on this interface. signal Modifications STREAMS/UX supports signals and the HP-UX signal system call. However, STREAMS/UX does not support extended signals or the siginfo_t structure described in the siginfo (5) manpage.
Differences Between STREAMS/UX and System V Release 4 STREAMS HP-UX Modifications to STREAMS/UX Utilities HP-UX Modifications to STREAMS/UX Utilities STREAMS/UX supports the following kernel utilities described in the SVR4.2 Driver manual, although some of the utilities have been modified for HP-UX.
Differences Between STREAMS/UX and System V Release 4 STREAMS HP-UX Modifications to STREAMS/UX Utilities unweldq weldq The strenv.h file redefines some native HP-UX kernel utilities to conform to System V Release 4.2. The strenv.h file redefines delay, get_sleep_lock, kmem_alloc, kmem_free, lbolt, max, min, sleep, time, timeout, and untimeout. These defines might collide with declarations in STREAMS/UX modules and drivers. The strenv.
Differences Between STREAMS/UX and System V Release 4 STREAMS HP-UX Modifications to STREAMS/UX Utilities get_sleep_lock STREAMS/UX provides some extra support for modules and drivers which use the native HP-UX get_sleep_lock primitive. Alternatively, modules and drivers can call the SVR4 MP SV_WAIT and SV_WAIT_SIG. Open and close routines call get_sleep_lock before sleeping to prevent missing wakeups. After calling get_sleep_lock, the open or close can release spinlocks before sleeping.
Differences Between STREAMS/UX and System V Release 4 STREAMS HP-UX Modifications to STREAMS/UX Utilities The compiler options to turn on deadlock checking for HP-UX are different than those documented in the SVR4.2 Driver manual. The entire HP-UX kernel and the module or driver must be compiled with SEMAPHORE_DEBUG to enable deadlock checking. According to the SVR4.2 Driver manual, the min_pl parameter can be ignored by implementations which do not need to raise the priority level.
Differences Between STREAMS/UX and System V Release 4 STREAMS HP-UX Modifications to STREAMS/UX Utilities streams_put utility STREAMS/UX provides a new utility streams_put(), which allows non-STREAMS software to safely call STREAMS/UX utilities. timeout and bufcall user functions and other non-STREAMS code cannot call several of the STREAMS utilities or share data with modules and drivers. Non-STREAMS code can call streams_put(), passing it a function and a queue.
Differences Between STREAMS/UX and System V Release 4 STREAMS HP-UX Modifications to STREAMS/UX Utilities • The last difference is that the SVR4 MP SV_WAIT_SIG returns if the process is first stopped by a job control signal and then continued. The HP-UX SV_WAIT_SIG continues to sleep until it receives a signal which does not stop the process or an SV_BROADCAST wakes up the process. TRYLOCK The STREAMS/UX TRYLOCK calls the native HP-UX cspinlock primitive.
Differences Between STREAMS/UX and System V Release 4 STREAMS HP-UX Modifications to STREAMS/UX Utilities The weld daemon will call func with arg as an argument after it finishes the request. The protect_q specifies which queue the callback function can access safely. If the driver does not need to be notified when the daemon finishes the weld request, pass weldq zero for the func, arg and protect_q parameters. On successful completion, weldq returns 0.
Differences Between STREAMS/UX and System V Release 4 STREAMS HP-UX Modifications to STREAMS/UX Utilities vtop The STREAMS/UX vtop only accepts a NULL process structure pointer. In other words, it only converts kernel space addresses.
Differences Between STREAMS/UX and System V Release 4 STREAMS HP-UX Changes to STREAMS/UX Drivers and Modules HP-UX Changes to STREAMS/UX Drivers and Modules The unsupported drivers and modules include: connld console ports sxt xt NOTE Some STREAMS-based terminal I/O functionality is contained in a separate product called STREAMS-TIO. It is part of the HP-UX runtime product. See the following manpages (which are part of the STREAMS-TIO product): pts (7), ptm (7), ldterm (7), pterm (7) and pckt (7).
Differences Between STREAMS/UX and System V Release 4 STREAMS HP-UX Changes to STREAMS/UX Drivers and Modules The STREAMS/UX log driver is named strlog instead of log. The special device file is /dev/strlog. strlog provides the same functionality for logging as described in the UNIX SVR4.2 System Files and Devices Reference, with the exceptions described: • The strlog kernel utility formats binary arguments before sending messages up the stream.
Differences Between STREAMS/UX and System V Release 4 STREAMS HP-UX Changes to STREAMS/UX Drivers and Modules The sc provides auxiliary functions for the sad driver. timod Module ID Number: 5006 Maximum Packet Size: INFPSZ Minimum Packet Size: 0 High Water Mark: 2048 Low Water Mark: 128 The timod provides TLI functionality as described in the UNIX SVR4.2 System Files and Devices Reference manual.
Differences Between STREAMS/UX and System V Release 4 STREAMS HP-UX Changes to STREAMS/UX Drivers and Modules The pipemod handles M_FLUSH messages in STREAMS/UX-based pipes. The pipemod is described in Chapter 4, “Modules and Drivers.
Differences Between STREAMS/UX and System V Release 4 STREAMS HP-UX Changes to STREAMS/UX Data Structures HP-UX Changes to STREAMS/UX Data Structures STREAMS/UX data structures are almost identical to those described in the SVR4.2 Driver manual. STREAMS/UX places additional restrictions on how some of these structures can be accessed. STREAMS/UX data structures that differ from the descriptions in the SVR4.2 Driver manual are described here. Data structures identical to those described in the SVR4.
Differences Between STREAMS/UX and System V Release 4 STREAMS HP-UX Changes to STREAMS/UX Data Structures If streams_put cannot be used, the code that accesses a STREAMS/UX queue must, at a minimum, follow these additional rules: • The software must ensure that it is accessing an allocated, opened queue. • It cannot dereference the q_first, q_last, or q_next pointers. In other words, it cannot read or write data pointed at by the pointers.
Differences Between STREAMS/UX and System V Release 4 STREAMS HP-UX Changes to Message Types HP-UX Changes to Message Types STREAMS/UX supports all the message types as in SVR 4.2. However STREAMS/UX differs from SVR4.2 STREAMS only in the way it behaves on the receipt of M_HANGUP message at the stream head for controlling terminals. For the controlling terminals, the stream head sends a SIGHUP signal to the foreground process group and not the controlling terminal when it receives a M_HANGUP message.
Differences Between STREAMS/UX and System V Release 4 STREAMS HP-UX Changes to Cloning HP-UX Changes to Cloning STREAMS/UX supports two methods of cloning. See the SVR4.2 STREAMS manual for more information about cloning. Chapter 4, “Modules and Drivers,” explains the two HP-UX cloning methods in detail. The major number for the clone driver in HP-UX is 72 while SVR4.2 cloning uses 63 as the major number of the clone driver.
Differences Between STREAMS/UX and System V Release 4 STREAMS Differences Between SVR4 MP and HP-UX MP STREAMS Differences Between SVR4 MP and HP-UX MP STREAMS HP-UX STREAMS provides MP scalability differently from SVR4 MP STREAMS. There are two main differences. 1. The first pertains to which STREAMS/UX entities run in parallel. SVR4 MP STREAMS executes put and service procedures for the same queue concurrently although only one instance of a service procedures can run at a time.
Differences Between STREAMS/UX and System V Release 4 STREAMS Differences Between SVR4 MP and HP-UX MP STREAMS combination of these two strategies may make sense. For example, suppose several modules and drivers share the same structure, but do not access it on the main read and write paths. Use SVR4 MP spinlocks to protect this data, but use the STREAMS/UX synchronization levels to protect other structures.
Differences Between STREAMS/UX and System V Release 4 STREAMS The STREAMS/UX Scheduler The STREAMS/UX Scheduler The STREAMS/UX scheduler runs service routines that are scheduled by STREAMS/UX utilities such as putq. The scheduler will run all scheduled service procedures before returning to user level. The scheduler is a real time daemon that runs at priority 100. (A low priority number denotes a high priority. For example, a priority number of 50 would be of higher priority than the number 100).
Differences Between STREAMS/UX and System V Release 4 STREAMS The STREAMS/UX Scheduler 280 Appendix E
Differences Between STREAMS/UX and System V Release 4 STREAMS The STREAMS/UX Scheduler Appendix E 281
Differences Between STREAMS/UX and System V Release 4 STREAMS The STREAMS/UX Scheduler 282 Appendix E
F Synchronization Levels STREAMS/UX supports MP scalable drivers and modules. Modules and drivers need to select the level of parallelism consistent with their use of shared data structures. STREAMS/UX allows the degree of parallelism to be configured by providing the following levels of synchronization: 1. Queue level synchronization — SQLVL_QUEUE 2. Queue-pair level synchronization — SQLVL_QUEUEPAIR 3. Module level synchronization — SQLVL_MODULE 4. Elsewhere level synchronization — SQLVL_ELSEWHERE 5.
Synchronization Levels Queue Level Synchronization Queue Level Synchronization The queue level synchronization serializes access to a queue so that only one request is processed at a time. Requests to different queues can run in parallel. For example, if the echo driver in Figure F-1, “Synchronization Levels,” is configured for queue synchronization, the following procedures will not execute concurrently: • ECHO-A’s echo_rput and echo_rsrv procedures. • ECHO-A’s echo_wput and echo_wsrv procedures.
Synchronization Levels Elsewhere Level Synchronization Elsewhere Level Synchronization The elsewhere level synchronization serializes a group of different modules. This synchronization ensures that only one request to the entire group of modules can be processed at a time. Requests to other queues that are not in this group can run concurrently.
Synchronization Levels NOSYNC Level synchronization • Multiple instances of ECHO-A's echo_wput and a single instance of echo_wsrv procedures. • Any of ECHO-A's procedures with any of ECHO-B, DLPI-A, or SAD-A's procedures. If a module uses NOSYNC synchronization, STREAMS/UX can concurrently execute multiple instances of a queue's put procedure and a single instance of the same queue's service procedure.
G STREAMS Commands Overview This appendix discusses the various STREAMS/UX commands.
STREAMS Commands autopush autopush The autopush command manages the system database of automatically pushed STREAMS modules. The HP-UX autopush command has been enhanced with respect to UNIX SVR4.2, to allow the user to specify the device name in place of the major number, which is recommended since HP-UX provides dynamic major numbers. The name can be specified in the autopush file and on the command line. Device names are located in the HP-UX modmeta files. The major number can still be used if needed.
STREAMS Commands autopush If a range of minors has been previously configured then autopush -g returns the configuration information for the first minor in the range, in addition to other information. -r -M major -m minor Remove configuration information from the system database for the STREAMS device specified by the major device number (or device name for the device from the modmeta file and minor number). Removal is performed on the database only, not on the original configuration file.
STREAMS Commands strace and strerr strace and strerr The strace and strerr commands use the STREAMS log driver, /dev/strlog. SVR4.2 calls this driver /dev/log, but HP-UX already includes a non-streams driver named /dev/log. Therefore, STREAMS logging uses /dev/strlog. strace strace gets STREAMS event trace messages from STREAMS drivers and modules via the STREAMS log driver (strlog(7)), and writes these messages to standard output.
STREAMS Commands strace and strerr strace runs until it is terminated by the user.
STREAMS Commands strace and strerr pri Tracing priority level as defined by the STREAMS driver or module that created the messages. ind Can be any combination of the following three message indicators: T: The message has also been saved in the trace log. F: The message signalled a fatal error. N: The message has also been mailed to the system administrator. mod Module identification number of the trace message source. text trace message text. strace runs until it is terminated by the user.
STREAMS Commands strchg and strconf strchg and strconf The strchg and strconf commands are used to change or query the configuration of the stream associated with the user's standard input. The strchg command pushes modules on and/or pops modules off the stream. The strconf command queries the configuration of the stream. Only a user with appropriate privileges or owner of a STREAMS device may alter the configuration of that stream.
STREAMS Commands strchg and strconf 75 -1 0 modA modB test 0 5 modC modA autopush -f /tmp/autopush.example will cause modA and modB to be pushed whenever major device # 75 is opened, and modC and modA to be pushed for the first six opens of test.
STREAMS Commands strclean strclean strclean cleans the STREAMS error logger directory of log files (error.mm-dd) that contain error messages sent by the STREAMS log driver strlog(7). If the -d option is not used to specify another directory, strclean removes the error log files in the /var/adm/streams directory. If the -a option is not used to specify another age, strclean removes the error log files that have not been modified over the last three days.
STREAMS Commands strclean 296 Appendix G
H STREAMS Kernel Tunable Parameters Overview The following kernel parameters can be configured and used for managing the resources used by STREAMS. NSTREVENT Maximum number of outstanding streams bufcalls that are allowed to exist at any given time. This number should be greater than or equal to the maximum number of bufcalls that can be generated by all modules pushed onto a given stream. This serves to limit runaway bufcalls.
STREAMS Kernel Tunable Parameters NSTREVENT NSTREVENT The maximum number of outstanding STREAMS bufcalls. Values Failsafe 50 Default 50 Allowed 0 - 2147483647 Recommended 50 Description This tunable limits the maximum number of outstanding bufcalls that are allowed to exist at any given time. This tunable is intended to protect the system against resource overload caused by the combination of modules running in all streams issuing an excessive number of bufcalls.
STREAMS Kernel Tunable Parameters NSTREVENT What are the Side Effects of Lowering the Value of This Tunable? Network commands may fail if the value is too low. What Other Tunable Should be Changed at the Same Time? None. Warnings All HP-UX kernel tunable parameters are release specific. This parameter may be removed or have its meaning changed in future releases of HP-UX. Author NSTREVENT was developed by HP.
STREAMS Kernel Tunable Parameters NSTRPUSH NSTRPUSH The maximum number of STREAMS modules in a single stream. Values Failsafe 16 Default 16 Allowed 0 - 2147483647 Recommended 16 Description This tunable defines the maximum number of STREAMS modules that can be pushed onto a stream. This provides some protection against run-away processes that might automatically select modules to push onto a stream. It is not intended as defense against malicious use of STREAMS modules by system users.
STREAMS Kernel Tunable Parameters NSTRPUSH When Should the Value of This Tunable be Lowered? If the tunable is increased for a particular STREAMS module/driver, this tunable can be lowered when that STREAMS module/driver is removed. It should be returned to its previous value. However, HP does not recommend a value lower than the default value. What are the Side Effects of Lowering the Value of This Tunable? System performance will be lowered during low memory situations.
STREAMS Kernel Tunable Parameters NSTRSCHED NSTRSCHED The number of STREAMS scheduler daemons to be run. Values Failsafe 0 Default 0 Allowed 0 - 2147483647 Recommended 0 Description This tunable defines the number of STREAMS scheduler daemons to be run on a system. If the tunable value is set to zero, the system determines the number of daemons to run based on the number of processors in the system.
STREAMS Kernel Tunable Parameters NSTRSCHED When Should the Value of This Tunable be Lowered? This tunable is for use by specific HP products only. It may be removed in future HP-UX releases. What are the Side Effects of Lowering the Value of This Tunable? It could change the system performance unpredictably. What Other Tunable Should be Changed at the Same Time? None. Warnings This tunable is for use by specific HP products only. All HP-UX kernel tunable parameters are release specific.
STREAMS Kernel Tunable Parameters STRCTLSZ STRCTLSZ The maximum size of streams message control (bytes). Values Failsafe 1024 Default 1024 Allowed 0 - 2147483647 Recommended 1024 Description STRCTLSZ limits the maximum number of bytes of control data that can be inserted by putmsg() in the control portion of any streams message on the system. If the tunable is set to zero, there is no limit on how many bytes can be placed in the control segment of the message.
STREAMS Kernel Tunable Parameters STRCTLSZ When Should the Value of This Tunable be Lowered? The tunable could be lowered if the STREAMS modules or drivers do not require a longer message size than the current value in the control portion. What are the Side Effects of Lowering the Value of This Tunable? Improper functioning in any of the STREAMS modules or drivers may result. There may be some performance degradation, particularly in networking.
STREAMS Kernel Tunable Parameters STRMSGSZ STRMSGSZ The maximum size of streams message data (bytes). Values Failsafe 0 Default 0 Allowed 0 - 2147483647 Recommended 0 Description This tunable limits the number of bytes of message data that can be inserted by putmsg() or write() in the data portion of any streams message on the system. If the tunable is set to zero, there is no limit on how many bytes can be placed in the data segment of the message.
STREAMS Kernel Tunable Parameters STRMSGSZ When Should the Value of This Tunable be Lowered? The tunable could be lowered if the STREAMS modules or drivers do not require a longer message size than the current value in the data portion. What are the Side Effects of Lowering the Value of This Tunable? Improper functioning in any of the STREAMS modules or drivers may result. There may be some performance degradation, particularly in networking. What Other Tunable Should be Changed at the Same Time? None.
STREAMS Kernel Tunable Parameters streampipes streampipes Forces all pipes to be STREAMS-based. Values Failsafe 0 Default 0 Allowed 0 - 2147483647 Recommended 0 Description This tunable determines the type of pipe that is created by the pipe() system call. If set to the default value of zero, all pipes created by pipe() are normal HP-UX file-system pipes. If the value is non-zero, pipe() creates STREAMS-based pipes, and STREAMS modules can be pushed onto the resulting stream.
STREAMS Kernel Tunable Parameters streampipes be turned off. What are the Side Effects of Switching Off This Tunable? Applications that try to push STREAMS modules onto the pipe will fail. What Other Tunable Should be Changed at the Same Time? If this tunable is set to a non-zero value, the pipemod and pipedev module and driver must be configured in /stand/system. Warnings This tunable is for use by specific HP products only. All HP-UX kernel tunable parameters are release specific.
STREAMS Kernel Tunable Parameters streampipes 310 Appendix H
A ANYMARK 151 arg 151, 301 autopush 72, 268 B b_major 78 building 123 bytes len 67 C C_ALLCLOSES 79 C_CLONESMAJOR 79 c_major 79 canput() 98, 100 canputnext() 100 cdio 79 cdio_private 79 characteristics 129, 134 clone 281 Cloning 288 cloning 72, 109 close (2) 30 close routine 82 cmn_err 274 command 151, 300, 305 Commands autopush 268 fdetach 268 strace 268 strchg 268 strclean 268 strconf 268 strerr 268 strvf 268 commands I_ATMARK 151 I_CANPUT 152 I_CKBAND 152 I_FDINSERT 152 I_FIND 153 I_FLUSH 153 I_FLUSHBAND
dblk_t 67 Data Structures Message 285 Queue 285 Restrictions 285 data structures module_info 74 module_stat 74 qinit 74 streamtab 74 datab data block 26 datab structure 255 databuf 152 dblk_t data block 67 design guidelines 150 disconnecting configuration 126 dismantling 125, 133 DLKM Dynamically Loadable Kernel Module 119 Dynamically Loadable Kernel Modules 73 DLPI-A 296 dp_fds 47 DP_ISPOLLED 48 dp_nfds 47 dp_timeout 47 DRV_BLOCK 78 DRV_CHAR 78 drv_info_t 78 DRV_MP_SAFE 78 drv_ops_t 79 DRV_SAVE_CONF 78 DRV
M_COPYOUT 58, 259 M_ERROR 58, 259 M_FLUSH 58, 259 M_HANGUP 58, 260 M_IOCACK 58, 260 M_IOCDATA 58, 261 M_IOCNAK 261 M_PCPROTO 58, 261 M_PCRSE 58, 262 M_PCSIG 58, 262 M_READ 58, 262 M_START 58, 262 M_STARTI 58, 262 M_STOP 58, 262 M_STOPI 58, 262 I I_ATMARK 151 I_CANPUT 152 I_CKBAND 152 I_FDINSERT 152 I_FIND 153 I_FLUSH 94, 153 I_FLUSHBAND 94, 154 I_GETBAND 154 I_GETCLTIME 154 I_GETSIG 155 I_GRDOPT 155 I_GWROPT 155 I_LINK 155 I_LIST 156 I_LOOK 156 I_NREAD 156 I_PEEK 157 I_PLINK 157 I_POP 42, 158 I_PUNLINK 158
M_COPYIN 58, 87, 88, 258 M_COPYOUT 58, 88, 259 M_CTL 58, 252 M_DATA 58, 252 M_DELAY 58, 252 M_ERROR 58, 259 M_FLUSH 58, 94, 259 M_HANGUP 58, 260 M_IOCACK 58, 87, 260 M_IOCDATA 58, 87, 261 M_IOCNAK 58, 261 M_IOCTL 58, 85, 252 M_PASSFP 58, 254 M_PCPROTO 58, 107, 261 M_PCRSE 58, 262 M_PCSIG 58, 262 M_PROTO 58, 107, 254 M_READ 58, 262 M_RSE 58, 254 M_SETOPTS 58, 97, 254 M_SIG 58, 256, 257 M_START 58, 262 M_STARTI 58, 262 M_STOP 58, 262 M_STOPI 58, 262 main() 108 MAXAPUSH 264 mblk_t message block descriptor 67 m
POLLIN 45 POLLMSG 45 POLLNORM 45 POLLNVAL 45, 271 POLLOUT 45, 271 POLLPRI 45 POLLRDBAND 45 POLLRDNORM 45, 271 POLLWRBAND 45 POLLWRNORM 45, 271 popped 102 popping 100 priflags 36 pushed 102 pushing 100 put procedure 98 put procedure entry point 92 putctl2 276 putmsg 270 putmsg (2) 30 putnext() 98, 100 putnextctl2 276 putpmsg 270 putpmsg (2) 30 putq() 100 putqb() 100 Q q_count 100 q_hiwat 74 q_lowat 74 QB_BACK 62 QB_FULL 62 QB_WANTW 62 QBACK 61 qband 62 qband structure 62 QENAB 61 QFULL 61, 100 qinit 75 qinit
SAD_SAP 263, 265 SAD_VML 264, 265 SAD-A 296 sample driver 137 sc 282 scheduler 291 select 271 select (2) 30 service procedure 98 service procedure entry point 92 signal 272 SIGPOLL 50, 52, 53 sleep() 98 SO_ALL 255 SO_BAND 255 SO_HIWAT 255 SO_ISNTTY 256 SO_ISTTY 97, 256 SO_LOWAT 255 SO_MAXPSZ 255 SO_MINPSZ 255 SO_MREADOFF 255 SO_MREADON 255 SO_NDELOFF 256 SO_NDELON 256 SO_READOPT 255 SO_TONSTOP 256 SO_TOSTOP 256 SO_WROFF 255 SQLVL_DEFAULT 78 SQLVL_ELSEWHERE 78, 295 SQLVL_GLOBAL 78, 295 SQLVL_MODULE 78, 295 S
SV_WAIT_SIG 277 Synchronization Levels 289 synchronous polling 44 System Calls close 269 close (2) 30 fattach 269 fcntl 269 fdetach 269 getmsg 269 getpmsg 269 ioctl 269 ioctl (2) 30 isastream 269 open 269 open (2) 30 pipe 269 poll 269 poll (2) 30 putmsg 269 putpmsg 269 read 269 read (2) 30 readv 269 select 269 select (2) 30 signal 269 write 269 write (2) 30 writev 269 T timod 283 tirdwr 283 TRYLOCK 278 U unfreezestr 274 UNLOCK 278 unweldq 279 Utilities adjmsg() 164 allocb() 165 backq() 166 bcanput() 167 bca
qreply() 216 qsize() 217 RD() 218 rmvb() 219 rmvq() 220 SAMESTR() 221 streams_bufcall() 169 streams_delay() 222 streams_get_sleep_lock() 223 streams_mpsleep() 224 streams_put() 226 streams_time() 227 streams_timeout() 228 streams_untimeout() 229 strlog() 230 strqget() 232 strqset() 233 SV_ALLOC() 235 SV_BROADCAST() 236 SV_DEALLOC() 237 SV_WAIT() 238 SV_WAIT_SIG() 239 testb() 241 TRYLOCK() 240 unbufcall() 242 unfreezestr() 243 unlinkb() 244 UNLOCK() 245 unweldq() 246 vtop() 247 weldq() 249 WR() 248 utilities