Remote Procedure Calls Are RPCs the best or worst development to hit distributed computing User...
-
date post
20-Dec-2015 -
Category
Documents
-
view
217 -
download
0
Transcript of Remote Procedure Calls Are RPCs the best or worst development to hit distributed computing User...
Remote Procedure Calls• Are RPCs the best or worst development to hit
distributed computing• User interface for RPC is an emerging standard,
but it is not as simple as it should be• Converts local function call to remote service• There are critical issues such as server state
idempotent calls, and semantics under failures• It is natural to generalize function calls into a
distributed setting to allow calls outside local address space – allows programmer to divert calls from overworked hosts, and take advantage of services not available locally
Standard
The Sun Open Network Computing (ONC) Transport Independent Remote Procedure Call (TI-RCP) is an RPC standard
Ordinary Function Call
user space
calling program called function
thread of execution
ord_funct();ord_funct(void); {
}
Ordinary Function Call
• When a program calls a function, the return address and other state information (activation record) are pushed on a run-time stack and control is transferred to the starting address of the function
• The AR contains locations for parameters and automatic variables declared within the function
• An ordinary function call is single threaded• The function call causes a change in execution
address representing the thread of execution
System Call
user space kernel space
calling program called function
thread of execution
trap -- return
blocked thread
sys_funct();sys_funct(void); {
}
System Call
• Program requests system service by executing a system call
• Works like ordinary function call except that the call refers to code in the OS rather than in the program
• Differences between ordinary function call and system call
System Call/Function Call Differences
• System call is a trap to an entry point in the kernel which causes the thread of execution for the calling program to block
• A separate thread of execution with a stack in the kernel executes the system call
• When the trap returns, the original thread of execution unblocks
• A program may invoke a system call directly or through C library functions
• Library functions form jackets for the underlying services – a jacket could massage the parameters and perform other bookkeeping prior to making the system call
System Call with Jacketuser space
ordinary call ordinary return
trap return from trap
kernel space
user program
C library function or
jacket
system call
System Call with Jacket
• Kernel trap handler gains control, examines request, executes the requested service and returns the result
• System call prevents user from directly accessing code in the kernel to prevent damage
• System call should look as much like function call as possible
• System call is executing with a distinct thread and with a different stack
System Call vs RPC
• What if a program calls a function in the address space of another user instead of in the kernel?
• This is an RPC
Remote Procedure Call
rem_funct();rem_funct(void); {
}
local host
user space
client program
remote host
user space
server program
thread of execution
RPC call -- return
blocked thread
Protocol for RPC
Client Process
rpc rpc
call return
marshaled marshaled request return
client kernel
logical
call
logical
return
network
Server Process
ordinary ordinary
call return
marshaled marshalled request return
server kernel
client program
client Stub server stub
server functions
network services
network services
Protocol for RPC
• Client makes a “logical call” and waits for a “logical return”
• Client is compiled with additional code called client stub to form a single process
Client Stub
• Client is compiled with additional code called client stub to form a single process
• Client stub is analogous to system call jacket
• Responsible for converting arguments and assembling them into a message for network transmission
• Client stub is a jacket to package up arguments for underlying request
Marshaling
• Conversion to a network message is called marshaling the arguments
• Converts to machine independent format so machines with different architectures can participate
• Then the client stub makes a system call to the kernel of the OS (possibly using sockets) to send the message over the network and the client stub waits for a reply
Server Stub• The remote host compiles the remote function
code with additional code called the server stub• The server stub acts as a jacket for server
functions• When a client request arrives, the server kernel
passes it to the waiting server stub• The server stub unmarshals the arguments and
calls the requested service as a local function call• When the function call returns, the server stub
marshals the return values into an appropriate network message and performs a system call (possibly with sockets) to transmit the message to the client
• The kernel passes the message to the client as an ordinary return value
RPC Mechanism
• Transparent to the caller
• Client program only sees an ordinary function call to the client stub
• Server functions are ordinary functions
• The underlying mechanism for transporting requests and returning them is called the transport protocol
• RPC is designed to be independent of the transport protocol
Local Call to RPC
• Most natural approach for developing RPC is create local functions first and then see how remote execution changes them
• Two main issues are:– Establishing a handle to the function so the
correct service is called– Passing parameters that are recognizable by
different server hosts
High-Level RPC Generation
• In an ideal world, RPC calls would be available in programming languages
• Unfortunately, RPC is not available in most languages
rpcgen• Sun provides a command called rpcgen
which generates the remote version from a specification file whose name ends in .x
• The rpcgen program uses information in the function prototypes (return value type and parameter types) and makes skeleton functions into which the programmer inserts code
• The skeletons indicate how to call remote functions and how the remote function returns its value
drand48
• The following slides illustrate a process for converting a simple local service for generating pseudorandom numbers into a remote service
• The service is based on the drand family of pseudorandom-number generators taken from the UNIX library
• The srand48 and drand48 random-number generators are used
Using drand48
• Prior to invoking drand48, srand48 must be called with a long parameter value called the seed
• The seed determines the starting position in a predetermined sequence of pseudorandom numbers
• After initializing the generator with srand48, make successive calls to drand48 to return a sequence of pseudorandom double values that are uniformly distributed over the interval [0,1]
drand48 Example…myseed = 3243;iters = 10;srand48(myseed);for(i=0;i<iters;i++)
printf(“%d : %f\n”, i, drand48());
The above code segment produces ten pseudorandom numbers with 3243 as the seed
Local Service Design#include “rand.h”void initialize_random(long seed){
srand48(seed); }double get_next_random(void){
return drand48();}
initialize_random and get_next random encapsulate srand48 and drand48 respectively
Calling Program…void main(int argc, char *argv[]) {…
myseed = (long)atoi(argv[1]);iters = atoi(argv[2]);initialize_random(myseed);for (i=0;i<iters;i++)
printf(“%d : %f\n”, i, get_next_random());exit(0); }
rand.h
The following is the rand.h header file:
#include <stdlib.h>
void initialize_random(long seed);
double get_next_random(void);
UNIX Random-Number Generators
SYNOPSIS
#include <stdlib.h>
double drand48(void);
double erand48(unsigned short xsubi[3]);
void srand48(long seedval);
unsigned short *seed48(unsigned short seed16v[3]);
Spec 1170
RPC Specification
• Contains three unsigned numbers that identify:– The program– The version– The procedures or functions within the program
rand.x Specification File/* rand.x */program RAND_PROG {
version RAND_VERS {void INITIALIZE_RANDOM(long) = 1;double GET_NEXT_RANDOM(void) = 2;
} = 1} = 0x31111111;
• The program RAND_PROG is 0x31111111• Version number referred to symbolically as
RAND_VERS is 1• RAND_PROG exports services initialize_random and
get_next_random as service numbers 1 and 2 respectively – rpcgen converts function name from caps to lowercase
server files
rpcgen common files
client files
rpcgen Files
proto.x
proto_server.c
proto_svc.c
proto_xdr.c
proto.h
makefile.proto
proto_clnt.c
proto_client.c
rpcgen Files (Cont)
• The –a option of rpcgen creates all of the files shown in the previous slide
• Without the –a option rpcgen only creates the unshaded files
• The –C option indicates ANSI C is used• rpcgen incorporates the name before .x as
the prefix or suffix in the filenames of the various files it generates
rpcgen Files (Cont)makefile.proto makefile for compiling client and server code
proto_clnt.c contains client stub – usually is not modified
proto_svc.c contains server stub – usually is not modified
proto.h header file conatining aal XDR types generated by the spec. Look here to see how rpcgen converted types in .x file
proto_client.c contains a skeleton client main program with dummy calls to remote service – insert code to set up argument values before the dummy call in the client program
proto_server.c contains stubs for the remote services – insert code for local version of services into these stubs and perhaps modify the way these functions use the parameters
proto_xdr.c Contains XDR filters needed by the client and server stubs – usually is not modified
rpcgen Steps with rand.x
• Execute rpcgen to generate the needed files from the rand.x specification file
• Modify the rand_client.c file to contain the client code
• Modify the rand_server.c file to contain the functions to be called remotely
Unmodified rand_client.c (Top)#include "rand.h"voidrand_prog_1(char *host){ CLIENT *clnt; void *result_1; long initialize_random_1_arg; double *result_2; char * get_next_random_1_arg; #ifndef DEBUG clnt = clnt_create(host, RAND_PROG,
RAND_VERS, "netpath"); if (clnt == (CLIENT *) NULL) { clnt_pcreateerror(host); exit(1); }#endif /* DEBUG */
Unmodified rand_client.c (Middle)
result_1 = initialize_random_1(&initialize_random_1_arg, clnt);
if (result_1 == (void *) NULL) { clnt_perror(clnt, "call failed"); } result_2 =
get_next_random_1 ((void *)&get_next_random_1_arg, clnt);
if (result_2 == (double *) NULL) { clnt_perror(clnt, "call failed"); }#ifndef DEBUG clnt_destroy(clnt);#endif /* DEBUG */}
Unmodified rand_client.c (Bottom)
main(int argc, char *argv[]){ char *host; if (argc < 2) { printf("usage: %s server_host\n", argv[0]); exit(1); } host = argv[1]; rand_prog_1(host); }
Unmodified rand_client.c Analysis• clnt_create generates a handle for the remote
service• RAND_PROG and RAND_VERS parameters are
the program and version names in rand.x• “netpath” parameter indicates the program should
look for an available network transport mechanism as specified by the NETPATH environment variable
• initialize_random and get_next_random have version numbers appended to them
• Parameters and return values are designated by pointers that refer to data structures in the client stub
• clnt pointer is handle for the remote service – it should be deallocated with clnt_destroy
Modified rand_client.c (Top)/* Program 14.6 */#include <stdlib.h>#include <stdio.h>#include "rand.h"void main(int argc, char *argv[]){ int iters, i; long myseed; CLIENT *clnt; void *result_1; double *result_2; char *arg; if (argc != 4) { fprintf(stderr, "Usage: %s host seed iterations\n", argv[0]); exit(1); }
Modified rand_client.c (Middle) clnt = clnt_create(argv[1], RAND_PROG, RAND_VERS,
"netpath"); if (clnt == (CLIENT *) NULL) { clnt_pcreateerror(argv[1]); exit(1); } myseed = (long)atoi(argv[2]); iters = atoi(argv[3]); result_1 = initialize_random_1(&myseed, clnt); if (result_1 == (void *) NULL) { clnt_perror(clnt, "call failed"); }
Modified rand.client.c (Bottom) for (i = 0; i < iters; i++) { result_2 = get_next_random_1((void *)&arg, clnt); if (result_2 == (double *) NULL) { clnt_perror(clnt, "call failed"); } else printf("%d : %f\n", i, *result_2); } clnt_destroy(clnt); exit(0);}
Modified rand_client.c Analysis• Modified version is a combination of original
local call on page 499 of the book and the Unmodified rand_client.c
• Start with original local call and place client_create near beginning and clnt_destroy at the end
• Host name is now passed as the first command line argument
• The new main calls the remote functions directly, so there is no need for rand_prog_1
• initialize_random and get_next_random are made into remote calls – they have a 1 appended to their names
• The clnt handle is passed as an additional parameter in the calls
Unmodified rand_server.c (Top)#include "rand.h void *initialize_random_1_svc(long *argp, struct svc_req
*rqstp){ static char * result; /* * insert server code here */ return((void *) &result); }
Unmodified rand_server_c (Bottom)double *
get_next_random_1_svc(void *argp, struct svc_req *rqstp){
static double result; /* * insert server code here */ return (&result);
}
Modified rand.server.c#include <stdlib.h>#include "rand.h"void *initialize_random_1_svc(long *argp, struct svc_req *rqstp){ static char *result; srand48(*argp); result = (void *)NULL; return (void *) &result; }double *get_next_random_1_svc(void *argp, struct svc_req *rqstp){ static double result; result = drand48(); return &result; }
Other Details• Create rand_client and rand_server by
typing:$ make –f makefile.rand
• Register psudorandom-number server on the host by typing: $ rand_serverThen the server can receive remote request
• Sample call:$ rand_client vip.cs.utsa.edu 4323 10
Summary• Get program to work using local functions• Restructure each function so it has only one
parameter passed by value – be sure it works locally
• Create a .x specification file• Call rpcgen with –a and –C options• Compile generated files with generated makefile
before making changes to them – you may catch mistakes
• Insert calling program into _client.c – specification filename appears before _client.c
• Insert local function code into _server.c