• Keine Ergebnisse gefunden

PORTING STORAGETEK XDR ROUTINES

Im Dokument Cartridge Syste·m (Seite 160-166)

to return the response to the correct client. The data structure retrieved is of type cs I_HEADER.

The SSI sends requests down-layer from a client application to the NI.

When it receives the request, the SSI stores the IPC return address information in the return address queue. The data structure is of type

IPC HEADER.

The csi_lminput routine can be used by both the CSI and the SSI to receive and process messages down-layer. The difference between the CSI and SSI functions is accomplished with an tifdef statement in the code.

Sending Messages Up-Layer

When sending messages up-layer, the CSI stores return addresses, whereas the SS! retrieves them.

The CSI sends requests up-layer from the NI to the ACSLM. When it sends requests up-layer, the CSI stores the network return address in the return address queue. The data structure is of type cs I _HEADER.

The SSI sends responses up-layer from the NI to the client

application. When it sends responses up-layer, the SSI retrieves the

!PC address information structure from the return address queue. The data structure is of type IPC_HEADER. The SSI uses the key value ssi_identifier in th~ CSI_HEADER structure in order to direct the response to the correct client application.

The csi_rpcdisp.c routine can be used by both the CSI and the SSI to receive and process messages up-layer. The difference between the CSI and SSI functions is accomplished with an tifdef statement in the code.

CSI and SSllnitialization

During RPC initialization, the CSI registers as a permanent server at a predefined permanent program number, whereas the SSI registers as a transient server at a transient program number.

The csi_rpctinit. c routine can be used by both the CSI and the SSI for RPC TCP initialization, and the csi_rpcuinit. c routine can used for RPC UDP initialization. The difference between the initialization sequences of the CSI and SS! is accomplished with an tifdef

statement in the code.

PORTING STORAGETEK XDR ROUTINES

StorageTek offers XDR translation functions in "C" source code fonnat, either as a template for, or for direct porting to, client SSI source code. These routines perform XDR serialization and

551 Requirements XDR functions deserialization of Storage Server packets. These routines are

structured with a common'high-Ievel interface for the SS!. The interface has the following two parameters:

• A pointer to the network packet buffer supplied by the programmer (of type CSI_MSGBUF)

• A pointer to the XDR handle (of type XDR) supplied by RPC.

These XDR interfaces are never called directly by the programmer.

They are always indirectly called on behalf of the programmer via RPC routines. When porting the StorageTek XDR routines to the customer host system, the programmer must be careful to preserve the intrinsic order and structure of translation.

Serialization of Requests

The SSI serializes message packets when it sends a request to the CSI via the NI. The SSI calls clnt_call () , which in turn calls

csi_xdrrequest (). Figure 6-1 shows the layering of calls.

csi_xdrrequest ()

Figure 6-1. Layering of Calls - Request Serialization Deserialization of Responses

The SSI deserializes message packets when it receives a response from the CSI via the NI. The SSI calls the svc_getreq () routine, which calls the SSI's RPC dispatcher function (defined by the SSI programmer). The dispatcher function calls svc_getargs (), which in turn calls csi_ xdrresponse (). Figure 6-2 shows the layering of these calls.

rpc-dispatcher

Programming an SSI SSI Requirements

PROGRAMMING AN 551

Initializing the 551 as a Callback Server

When the SSI receives responses from the CSI, it functions as a server, apart from its normal role as primary client. This provides the CSI with port, program number, and procedure number mapping to direct an RPC callback.

gettransient () socket ()

Because the SSI functions as a transient server it must be assigned a transient program number. The transient number is dynamically assigned when the SSI is initiated and should be unmapped with the portmapper when the SSI is terminated in an orderly manner. When the SSI is restarted later, a new program number will be assigned.

Figure 6-3 depicts the process of initializing the SSI as a transient server.

/* 55I non-communications Initialization */

/* establish application IPC or other connections */

/* unmap residual port mappings */

/* get transient RPC programt & socket */

/* create a TCP/IP callback socket */

bind() /* bind socket to get port */

getsockname() /* retrieve assigned port number */

loop {

pmap_set ()

/* count up from starting transient program t, when pmap_set succeeds you have a transient program number */

return (program-number) + socket file descriptor, by reference */

svctcp_create() /* establish callback service port */

svc_register () ssiyrocess () svc_destroy ()

/* register callback service with port mapper */

/* enter main 55I processing loop */

/* de-allocate the service transport resources */

Figure 6-3. Initializing the SSI Server

SSI Requirements Programming an SSI

To initialize the SSI as a network service, the following is required:

A unique transient program nwnber, which the CSI can use when issuing an RPC callback to the SS!.

A version number, assigned to each program number so that the program number does not need to change when the NI transport service is changed.

A procedure number.

Obtaining a Unique Program Number

In order to obtain a unique transient program number, which the CSI will use to issue an RPC callback to the SSI (for transmitting Storage Server responses), the SSI programmer must code a function that obtains a transient port mapping. The gettransient () function, shown in Figure 6-4, is a sample of such a function.

The gettransient () function is derived from the following sources:

• A prototype application

• The Sun Network Programming Manual, "Remote Procedure Call Programming Guide," (subsection: "More Examples/Callback Procedures").

The number obtained by the function must be in the range for transient program numbers. See Communications Methodology in Chapter 5 for this range.

Initializing the SSI - Application Interface

There are no constraints on the design of the interface between the SSI and the application that it services. It is defined by the customer.

Programming an SSI SSI Requirements

tinclude <rpc/rpc.h>

tinclude <stdio.h>

tinclude <sys/socket.h>

tdefine START TRANSIENT Ox40000000 tdefine END TRANSIENT OxSffffffe

/* start number for transient progs' * /

Description: Returns the next available RPC transient program number Assign a socket if the contents of sockp RPC_ANYSOCK.

socktype-- SOCK DGRAMf

break;

-case IPPROTO TCP:

socktype-- SOCK STREAM;

break;

addr.sin-family-- AF INET;

addr.sin~ort - 0;

SSI Requirements Programming an SSI

Allocating the Network Buffer

The SSI must allocate a buffer for network input which both stores and describes the state of network packets. This buffer is of type

CSI_MSGBUF. See Message Translation Structures in Chapter 7 for the fonnat and content of this structure. For clarification, the defmition is duplicated below.

The network buffer is to be allocated to the size of the CSI MSGBUF data structure (which is the size of the structure from offset through data),

plus the size of data for the maximum size of messages that are expected. A

"e"

source code algorithm for this allocation is:

buffer yointer=malloc (name, sizeof (CSI_MSGBUF) +MAX_MESSAGE_SIZE)

The cha r data [1] "C" coding construct used in defining CS I _ MSGBUF,

allows the data area to be dynamically allocated at the same time as the other portions of the buffer structure. See your UNIX documentation for a description of the malloc () system routine.

Polling for Application or NI Input

The SSI must poll for input from both the network and client applications resident on the client host. The method of polling for network and application input varies depending on the client host.

Under 4.3BSD UNIX the select () system call is employed, for example.

The following are requirements for using select ( ) :

• Establish a file descriptor from which the SSI can read application input

• Establish the RPC input file descriptors used in managing RPC network services

• Construct an input flie descriptor mask to be passed to select ( )

• Upon return from select (), differentiate NI input from application input and make the appropriate function call:

Programming an SSI SSI Requirements

Im Dokument Cartridge Syste·m (Seite 160-166)