Sophie

Sophie

distrib > Mandriva > 8.2 > i586 > media > contrib > by-pkgid > 211238da6d926d1ca4390483bb29f586 > files > 61

coda-doc-5.2.0-4mdk.noarch.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<HTML>
<HEAD>
 <META NAME="GENERATOR" CONTENT="SGML-Tools 1.0.9">
 <TITLE> RPC2 User Guide and Reference Manual: MultiRPC</TITLE>
 <LINK HREF="rpc2_manual-7.html" REL=next>
 <LINK HREF="rpc2_manual-5.html" REL=previous>
 <LINK HREF="rpc2_manual.html#toc6" REL=contents>
</HEAD>
<BODY>
<A HREF="rpc2_manual-7.html">Next</A>
<A HREF="rpc2_manual-5.html">Previous</A>
<A HREF="rpc2_manual.html#toc6">Contents</A>
<HR>
<H2><A NAME="s6">6. MultiRPC</A></H2>

<P>
<A NAME="MultiChapter"></A> <H2><A NAME="ss6.1">6.1 Design Issues</A>
</H2>

<P>
<P>The MultiRPC facility 
<@@ref>Satyanarayanan90[Satyanarayanan 90]</A> is an extension to RPC2 that  provides a parallel RPC capability for sending a single request to multiple  servers and awaiting their individual responses. Although the actual transmission is done sequentially, the resultant concurrent processing by the servers results in a significant increase in time and efficiency over a sequence of standard RPC calls. The RPC2 runtime overhead is also reduced as the number of servers increases. For the purposes of this discussion, the base RPC2 facility will be referred to simply as <B>RPC2</B>.
<P>
<P>A noteworthy feature of the MultiRPC design is the fact that the entire implementation is contained on the client side of the RPC2 code. The packet which is finally transmitted to the server is identical to a packet generated by an RPC2 call, and the MultiRPC protocol requires only a normal response from a server. 
<P>
<P>A major design goal was the desire to automatically provide MultiRPC capability for any subsystem without requiring any additional support from the subsytem designer or implementor. This has been achieved through modifications to RP2Gen, the RPC2 stub generation package (see chapter 
<@@ref>Satyanarayanan90[Satyanarayanan 90]</A><@@ref>RP2GenRP2Gen</A>). RP2Gen generates an array of argument descriptor structures for each server operation in the specification file, and these arrays are inserted in the beginning of the client side stub file. These structures are made available to the client through definitions in the associated <EM>.h</EM> file, and allow the use of MultiRPC with any routine in any subsystem with RP2Gen generated interfaces. 
<P>
<P>The orthogonality of the MultiRPC modifications also extends to the side
effect mechanism. Side effects for MultiRPC work exactly as in the RPC2 case except that the client must supply a separate <B>SE_Descriptor</B> for each connection.  Side effects can be omitted on a subset of the connections by specifying a the Tag field value of <EM>OMITSE</EM> for those <B>SE_Descriptor</B>s. This used, for example, in the Coda file system where  a MultiRPC call is made to obtain file version information from a set of servers, but data from only one of those servers. 
<P>
<P>Parameter packing and unpacking for MultiRPC is provided in the RPC2 runtime library by a  pair of routines. These library  routines provide the functionality of the client side interface generated by RP2Gen as well as some additional modifications to support MultiRPC. It was decided to perform the packing and unpacking in RPC2 library routines rather than in individual client side stub routines as in the  RPC2 case; this requires some extra processing time, but saves a significant amount of space in the client executable file. This approach has the added advantage of modularity; execution of  RPC2 calls will not be affected at all, and even for MultiRPC calls the additional processing time is negligable in comparison to the message transmission overheads imposed by the UNIX kernel.
<P>
<P>Another feature of MultiRPC is the client supplied handler routine. Through the handler routine the client is allowed to process each server response as it arrives rather than waiting for the entire MultiRPC call to complete. After processing each response, the client can decide whether to continue accepting server responses or whether to abort the remainder of the call. This facility can be useful if only a subset of responses are required, or if one failed message renders the entire call useless to the client. This capability is discussed further in section 
<A HREF="rpc2_manual-18.html#handler">XXX</A>.
<P>
<P>MultiRPC also provides the same correctness guarantees as  RPC2 except in the case where the client exercises his right to terminate the call. RPC2 guarantees that a request (or response) will be processed exactly once in the absence of network and machine crashes; otherwise, it guarantees that it will be processed at most once. If the call completes normally, a return code of <EM>RPC2_Success</EM> guarantees that all messages have been received by the appropriate servers.
<P>
<P>
<H2><A NAME="ss6.2">6.2 Examples</A>
</H2>

<P>
<P>To illustrate the use of MultiRPC, we revisit Example 
<A HREF="rpc2_manual-2.html#Example-rtime">XXX</A> from Chapter 
<A HREF="rpc2_manual-2.html#Intro">XXX</A> and Example 
<A HREF="rpc2_manual-5.html#Example-rcat">XXX</A> from Chapter 
<A HREF="rpc2_manual-5.html#SFTPChapter">XXX</A>. The interface specification files (<EM>rtime.rpc</EM> and <EM>rcat.rpc</EM>) and the files for the server code (<EM>rtime_srv.c</EM> and <EM>rcat_srv.c</EM>) remain unchanged.  Only the client files (<EM>rtime_clnt.c</EM> and  <EM>rcat_lowbar;clnt.c</EM>) have to be modified.
<P>
<H3><A NAME="MultiExample1"></A> MultiRPC Client for Example <A HREF="rpc2_manual-2.html#Example-rtime">XXX</A> (<EM>in file multi_rtime_clnt.c</EM>)  </H3>

<P>
<P>This example specifies no handler, and does not perform any side
effects. The client will prompt for the number of servers to which the
request is to be made, and for their connection ids.  Note that
<EM>RPC2_MultiRPC</EM> is used even when only one server is requested.
<P>
<BLOCKQUOTE><CODE>
@include(multi_rtime_clnt.c.mss)
</CODE></BLOCKQUOTE>
<P>
<H3><A NAME="MultiExample2"></A> MultiRPC Client for Example <A HREF="rpc2_manual-5.html#Example-rcat">XXX</A><EM>(in file multi_rcat_clnt.c</EM>)  </H3>

<P>
<P>In this example, a minimal handler routine is supplied for each server operation. It is adequate to demonstrate the format of the routine even though it does little actual processing of the responses. This example also demonstrates the use of MultiRPC in conjunction with side effects.
<P>
<BLOCKQUOTE><CODE>
@include(multi_rcat_clnt.c.mss)
</CODE></BLOCKQUOTE>
<P>
<P>
<H2><A NAME="ss6.3">6.3 C Interface Specification</A>
</H2>

<P>
<A NAME="interface"></A> <P>The following table shows the C type interface between the client routine and <EM>MRPC_MakeMulti</EM> for all the possible combinations of legal parameter declarations and types. In all cases it is the clients responsibility to allocate storage for all parameters, just as in the RPC2 case. For all types except RPC2_EncryptionKey, IN parameters are handled the same as in the single MakeRPC case; RPC2_EncryptionKeys must be passed as pointers in the MultiRPC case. For OUT and INOUT parameters, arrays of pointers to parameters must be supplied in order to hold the multiple server responses. The array for each parameter must contain the same number of items as the number of servers contacted, and they must be filled sequentially starting from element zero. For all INOUT parameters except for <B>SE_Descriptors</B>, only the first element of the array need be filled in. For <B>SE_Descriptors</B>, all elements must be filled in. 
<P>
<P>The following table should be consulted for specific formats. 
<P>
<CENTER><TABLE BORDER><TR><TD>
<BR>
RPC2 Type </TD><TD> <B>in</B> </TD><TD> <B>out</B> </TD><TD> <B>in out</B>&gt;)RPC2_Integer </TD><TD> long </TD><TD> long *[ ] </TD><TD> long *[ ]</TD></TR><TR><TD>
RPC2_Unsigned </TD><TD> unsigned long </TD><TD> unsigned long *[ ] </TD><TD> unsigned long *[ ]</TD></TR><TR><TD>
RPC2_Byte </TD><TD> unsigned char </TD><TD> unsigned char *[ ] </TD><TD> unsigned char *[ ]</TD></TR><TR><TD>
RPC2_String </TD><TD> unsigned char * </TD><TD> unsigned char **[ ] </TD><TD> unsigned char **[ ]</TD></TR><TR><TD>
RPC2_CountedBS </TD><TD> RPC2_CountedBS) * </TD><TD> RPC2_CountedBS) *[ ] </TD><TD> RPC2_CountedBS) *[ ]</TD></TR><TR><TD>
RPC2_BoundedBS </TD><TD> RPC2_BoundedBS) * </TD><TD> RPC2_BoundedBS) *[ ] </TD><TD> RPC2_BoundedBS) *[ ]</TD></TR><TR><TD>
RPC2_EncryptionKey </TD><TD> RPC2_EncryptionKey * </TD><TD> RPC2_EncryptionKey *[ ] </TD><TD> RPC2_EncryptionKey *[ ]</TD></TR><TR><TD>
SE_Descriptor </TD><TD> <EM>illegal</EM> </TD><TD> <EM>illegal</EM> </TD><TD> SE_Descriptor *[ ]</TD></TR><TR><TD>
RPC2_Enum <EM>name</EM> </TD><TD> <EM>name</EM> </TD><TD> <EM>name</EM> *[ ] </TD><TD> <EM>name</EM> *[ ]</TD></TR><TR><TD>
RPC2_Struct <EM>name</EM> </TD><TD> <EM>name</EM> * </TD><TD> <EM>name</EM> *[ ] </TD><TD> <EM>name</EM> *[ ]</TD></TR><TR><TD>
RPC2_Byte <EM>name[...]</EM> </TD><TD> <EM>name</EM> </TD><TD> <EM>name</EM> *[ ] </TD><TD> <EM>name</EM> *[ ]</TD></TR><TR><TD>

<CAPTION>
<A NAME="MCDecls"></A> 
RP2Gen representation of MultiRPC parameters</CAPTION>
</TD></TR></TABLE></CENTER>
<P>
<P>The client is only responsible for understanding the parameter type interface to the <EM>MakeMulti</EM> and <EM>HandleResult</EM> routines, and for allocating all necessary storage. <EM>MRPC_MakeMulti</EM> and <EM>MRPC_UnpackMulti</EM> are included in the RPC2 libraries.
<P>@newpage
<H2><A NAME="ss6.4">6.4 Runtime Calls</A>
</H2>

<P>
<P>
<H3>MRPC_MakeMulti -- <EM>Pack arguments and initialize state for RPC2_MultiRPC</EM></H3>

<P>
<H3>Call:</H3>

<P><EM> MRPC_MakeMulti (</EM> <B>in</B> long Server <B>in</B> ARG ArgTypes[], <B>in</B> long HowMany, <B>in</B> RPC2_Handle CIDList[], <B>out</B> RPC2_Integer RCList[], <B>in out</B> RPC2_Multicast *MCast, <B>in</B> long (*HandleResult) (), <B>in</B> struct timeval *Timeout, Variable Length Argument List[]<EM>)</EM>
<H3>Parameters:</H3>

<P>
<DL>
<DT><B>ServerOp</B><DD><P>For server routine foo, "foo". RP2GEN generated opcode, defined in include file. Note that subsystems with overlapping routine names may cause problems in a MakeMulti call.,
<DT><B>ArgTypes</B><DD><P>For server routine foo, "foo;PTR". RP2GEN generated array of argument type specifiers. A pointer to this array is located in the generated include file <EM>foo.h</EM>.,
<DT><B>HowMany</B><DD><P>How many servers are being called,
<DT><B>CIDList</B><DD><P>Array of HowMany connection handles, one for each of the servers,
<DT><B>RCList</B><DD><P>Array of length HowMany, into which RPC2 will place return codes for each of the connections specified in ConnHanleList.  May be specified as NULL if return codes will not be examined.,
<DT><B>MCast</B><DD><P>Pointer to multicast sturcture.  Set to NULL for now.,
<DT><B>HandleResult</B><DD><P>User procedure to be called after each server response. Responses are processed as they come in. Client can indicate when he has received sufficient responses (see below). @MRPC(MakeMulti) will not return the server responses.,
<DT><B>Timeout</B><DD><P>User specified timeout. Note that the default timeout set in the .rpc file will not be active here: a NULL value will be passed through to MultiRPC, where it will indicate infinite patience as long as RPC2 believes that the server is alive. Note that this timeout value is orthogonal to the RPC2 internal timeout for determining connection death.,
<DT><B>&lt;Variable Length Argument List&gt;</B><DD><P>This is just the list of the server arguments as they are declared in the <EM>.rpc2</EM> file. It is represented in this form since each call will have a different argument list.,
</DL>
<H3>Completion Codes:</H3>

<P>
<DL>
<DT><B>@RPC2(SUCCESS)</B><DD><P>All went well,
<DT><B>@RPC2(TIMEOUT)</B><DD><P>The user specified timeout expired
before all the server responses were received,
<DT><B>@RPC(FAIL)</B><DD><P>Something other than SUCCESS or TIMEOUT occurred. Individual server response is supplied via UnpackMulti to the client handler routine.
</DL>
<H3>Description:</H3>

<P>Text=`For all <B>in</B> or <B>in out</B> parameters, an array of HowMany of the appropriate type should be allocated and supplied by the client. For example, if one argument is an <B>out</B> integer, an array of HowMany integers (i.e. int foo[HowMany]) should be used. For structures, an array of structures and NOT an array of pointers to structures should be used. <B>in</B> arguments are treated as in the @RPC2(MakeRPC) case.
)
<P>
<P>
<H3>RPC2_MultiRPC -- <EM>Make a collection of remote procedure calls</EM> </H3>

<P>
<H3>Call:</H3>

<P><EM>  RPC2_MultiRPC(</EM><B>in</B> long HowMany <B>in</B> RPC2_Handle ConnHandleList[], <B>in</B> RPC2_PacketBuffer *Request, <B>in</B> SE_Descriptor SDescList[], <B>in</B> long (*UnpackMulti) (), <B>in out</B> @ARG(INFO) *ArgInfo, <B>in</B> struct timeval *Patience  <EM>)</EM>
<H3>Parameters:</H3>

<P>
<DL>
<DT><B>HowMany</B><DD><P>How many servers to contact,
<DT><B>ConnHandleList</B><DD><P>List of HowMany connection handles for the connections on which calls are to be made.,
<DT><B>Request</B><DD><P>A properly formatted request buffer.,
<DT><B>SDescList</B><DD><P>List of HowMany side effect descriptors,
<DT><B>UnpackMulti</B><DD><P>Pointer to unpacking routine called by RPC2
when each server response as received. If RP2Gen is used, this will be
supplied by @MRPC(MakeMulti). Otherwise, it must be supplied by the client.,
<DT><B>ArgInfo</B><DD><P>A pointer to a structure containing argument information. This
structure is not examined by RPC2; it is passed untouched to 
UnpackMulti. If RP2Gen is used, this structure will be supplied by
@MRPC(MakeMulti). Otherwise, it can be used to pass any structure desired by the
client or supplied as NULL.,
<DT><B>Patience</B><DD><P>Maximum time to wait for remote sites to respond. A NULL pointer indicates infinite patience as long as RPC2 believes that the server is alive. Note that this timeout value is orthogonal to the RPC2 internal timeout for determining connection death.,
</DL>
<H3>Completion Codes:</H3>

<P>
<DL>
<DT><B>RPC2_SUCCESS)</B><DD><P>All servers returned successfully, or all servers until client-initiated abort returned successfully. Individual server response information is supplied via UnpackMulti to the user handler routine supplied in the ArgInfo structure.,
<DT><B>RPC2_TIMEOUT)</B><DD><P>The user specified timeout expired before all the servers responded.,
<DT><B>RPC2_FAIL)</B><DD><P>Something other than SUCCESS or TIMEOUT occurred. More detailed information is supplied via UnpackMulti to the user handler routine supplied in the ArgInfo structure.,
</DL>
<H3>Description:</H3>

<P>Logically identical to iterating through ConnHandleList and making RPC2_MakeRPC) calls to each specified
connection using Request as the request block, but this call will be considerably faster than explicit
iteration. The calling lightweight process
blocks until either the client requests that the call abort or one of the following is true about each of
the connections specified in ConnHandleList: a reply has been received, a hard error has been detected for
that connection, or the specified timeout has elapsed.
<P>The ArgInfo structure exists to supply argument packing and
unpacking information in the case where RP2Gen is used. Since its value is
not examined by RPC2, it can contain any pointer that a non-RP2Gen generated
client wishes to supply.
<P>Similarly, UnpackMulti will point to a specific unpacking routine in
the RP2Gen case. If the RP2Gen interface is not used, you should assume that the return
codes of the supplied routine must conform to the specifications in section
<@@ref>UnpackMultiXXX</A>.
<P>Side effects are supported as in the RPC2 case except that the
client must supply a separate <B>@SE[Descriptor]</B> for each connection. The
format for the <B>@SE[Descriptor]</B> argument is described in section 
<A HREF="#interface">XXX</A>. It will often be useful to supply
connection specific information such as unique file names in the
<B>@SE[Descriptor]</B>.
<P>
<P>
<H3>MRPC_UnpackMulti -- <EM>Unpack server arguments and callclient handler routine </EM> </H3>

<P>
<H3>Call:</H3>

<P><EM>  MRPC_UnpackMulti(</EM><B>in</B> long HowMany, <B>in</B> RPC2_Handle ConnHandleList[], <B>in out</B> @ARG(INFO) *ArgInfo, <B>in</B> RPC2_PacketBuffer *Response, <B>in</B> long rpcval, <B>in</B> long  <EM>)</EM>
<H3>Parameters:</H3>

<P>
<DL>
<DT><B>HowMany</B><DD><P>How many servers were included in the MultiRPC
call,
<DT><B>ConnHandleList</B><DD><P>Array of HowMany connection ids,
<DT><B>ArgInfo</B><DD><P>Pointer to argument information structure. This pointer is the same one passed in to MultiRPC, so for the non-RP2Gen case its type is determined by the client.,
<DT><B>Response</B><DD><P>RPC2 response buffer,
<DT><B>rpcval</B><DD><P>Individual connection error code or server response code,
<DT><B>thishost</B><DD><P>Index into ConnHandleList to identify the
returning connection,
</DL>
<H3>Completion Codes:</H3>

<P>
<DL>
<DT><B>0</B><DD><P>Continue accepting and processing server responses,
<DT><B>-1</B><DD><P>Abort MultiRPC call and return,
</DL>
<H3>Description:</H3>

<P>This routine is fixed in the RP2Gen case, and can be ignored
by the client. For the non-RP2Gen case, a pointer to a routine with the
argument structure described must be supplied as an argument to
RPC2_MultiRPC). The functionality of such a client-supplied routine is
unconstrained, but note that the return codes have an important effect on
the process of the MultiRPC call.
<P>
<P>
<H3>HandleResult, -- <EM>Process incoming server replies as they arrive</EM> </H3>

<P>
<H3>Call:</H3>

<P><EM>  HandleResult(</EM><B>in</B> long HowMany, <B>in</B> RPC2_Handle ConnArray[], <B>in</B> long WhichHost, <B>in</B> long rpcval, [Variable Length Argument List]  <EM>)</EM>
<H3>Parameters:</H3>

<P>
<DL>
<DT><B>HowMany</B><DD><P>number of servers from @MRPC(MakeMulti) call,
<DT><B>ConnArray</B><DD><P>array of connection ids as supplied to @MRPC(MakeMulti),
<DT><B>WhichHost</B><DD><P>this is an offset into ConnArray and into any OUT or IN;OUT parameters. Using this to index the arrays will yield the responding server and its corresponding argument values.,
<DT><B>rpcval</B><DD><P>this is the RPC2 return code from the specified server,
p5=`&lt;Variable Length Argument L
</DL>
<H3>Completion Codes:</H3>

<P>
<DL>
<DT><B>0</B><DD><P>Continue processing server responses,
<DT><B>-1</B><DD><P>Terminate @MRPC(MakeMulti) call and return,
</DL>
<H3>Description:</H3>

<P>This routine must return either 0 or -1. A return value of zero indicates that the client
wants to continue receiving server responses as they come in (normal case). A return value
of -1 indicates that the client has received enough responses and wants to terminate the
MakeMulti call (in which the client is still blocked). This allows the client to call
a large number or servers and terminate after the first <EM>n</EM> responses are received.
<P>Note that the name of this routine is arbitrary and may be determined by the client. RPC2_MultiRPC) sees it only as a pointer
supplied as an argument to @MRPC(MakeMulti). The parameter list is predefined, however, and the client must follow the structure
specified here in writing the routine. 
<P>
<P>
<P>
<HR>
<A HREF="rpc2_manual-7.html">Next</A>
<A HREF="rpc2_manual-5.html">Previous</A>
<A HREF="rpc2_manual.html#toc6">Contents</A>
</BODY>
</HTML>