49
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

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

  • View
    217

  • Download
    0

Embed Size (px)

Citation preview

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

External Data Representation (XDR)

Standard format for machine independent representation of data

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

proto.x

$ rpcgen –C –a proto.x

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

Summary (Cont)

• Compile programs with generated makefile

• Fiddle with it until it works the way you want