Internet Windows Android

Rpc protocol. Remote Procedures: Remote Procedure Calls, Definition and Features

Programs communicating over a network need a communication mechanism. At the lower level, upon receipt of packets, a signal is processed by the network signal processing program. At the top level, the rendezvous mechanism, adopted in the Ada language, works. NFS uses a remote procedure call (RPC) mechanism in which the client communicates with the server (see Figure 1). In accordance with this process, the client first accesses a procedure that sends a request to the server. Upon arrival of a packet with a request, the server calls the procedure for its opening, performs the requested service, sends a response, and control is returned to the client.

The RPC interface can be thought of as having three layers:

The upper level is completely transparent. A program at this level might, for example, call rnusers (), which returns the number of users on the remote machine. You don't need to know about using the RPC mechanism because you are making the call in the program.

The middle tier is for the most common applications. RPC calls at this level are handled by the registerrpc () and callrpc () routines: registerrpc () receives system-wide dark code, and callrpc () executes a remote procedure call. The rnusers () call is implemented using these two routines.

The lower level is used for more complex tasks, changing the default to the values ​​of procedure parameters. At this level, you can explicitly manipulate the sockets used to transmit RPC messages.

As a general rule, you should use the upper layer and avoid using the lower layers unnecessarily.

Despite the fact that in this tutorial we consider the interface only in C, calls to remote procedures can be made from any language. The work of the RPC mechanism for organizing communication between processes on different machines does not differ from its work on the same machine.

RPC (Remote Procedure Call) is an interface between remote users and specific host programs that are invoked by those users. An RPC service for a host typically provides a suite of programs to clients. Each of these programs, in turn, consists of one or more remote procedures. For example, an NFS remote filesystem service that relies on RPC calls can only consist of two programs: for example, one program interacts with high-level user interfaces and the other with low-level I / O functions.

Each RPC call involves two parties: the active client, which sends the procedure call request to the server, and the server, which sends the response to the client.

Note. Note that the terms "client" and "server" in this case refer to a specific transaction. A specific host or software (process or program) can act as either a client or a server. For example, a program that provides the operation of the remote procedure service, at the same time, can be a client in the work with the network file system.

RPC is built on a remote procedure call model similar to that of local procedure calls. When you call a local procedure, you push arguments to a specific memory location, stack, or environment variables, and transfer control of the process to a specific address. After completing the work, you read the results at a specific address and continue your process.

In the case of a remote procedure, the main difference is that the remote function call is served by two processes: the client process and the server process.

The client process sends a message to the server, which includes the parameters of the called procedure and waits for a response message with the results of its work. When a response is received, the result is read and the process continues. On the server side, the call handler process is in the waiting state, and when a message arrives, it reads the procedure parameters, executes it, sends a response, and becomes in the waiting state for the next call.

The RPC protocol does not impose any requirements on additional communications between processes and does not require synchronization of the functions performed, that is, calls can be asynchronous and non-independent, so that the client can execute other procedures while waiting for a response. The RPC server can allocate a separate process or virtual machine for each function, therefore, without waiting for the previous requests to finish, it can immediately accept the next.

However, there are several important differences between local and remote procedure calls:

1. Error processing. The client should in any case be notified of errors that occur when calling remote procedures on the server or on the network.

2. Global variables. Because the server does not have access to the client's address space, you cannot use hidden parameters in the form of global variables in remote procedure calls.

3. Performance. The speed of execution of remote procedures, as a rule, is one or two orders of magnitude lower than the speed of execution of similar local procedures.

4. Authentication. Because remote procedure calls occur over the network, client authentication mechanisms must be used.

Principles of constructing the protocol.

The RPC protocol can use several different transport protocols. The only responsibilities of the RPC protocol are to enforce standards and interpret message transmission. The reliability and reliability of message transmission is entirely ensured by the transport layer.

However, RPC can control the choice and some functions of the transport protocol. As an example of the interaction between RPC and the transport protocol, consider the procedure for assigning an RPC port of an application process via RPC - Portmapper.

This function dynamically (on demand) assigns a specific port to an RPC connection. Function Portmapper is used quite often because the set of transport ports reserved for RPC is limited, and the number of processes that can potentially run concurrently is very high. Portmapper, for example, called when NFS client / server communication ports are selected.

Service Portmapper uses the RPC broadcast message mechanism to a specific port - III. On this port, the client broadcasts a request for the port of a specific RPC service. Service Portmapper processes the tax message, determines the address of the local RPC service, and sends a response to the client. RPC service Portmapper can work with both TCP and UDP protocols.

RPC can work with various transport protocols, but it never duplicates their functions, that is, if RPC runs on top of TCP, RPC leaves all the worries about the reliability and reliability of the connection to TCP. However, if RPC is installed on top of UDP, it can provide additional native functionality to ensure message delivery is guaranteed.

Note. Applications can view the RPC protocol as a defined function call procedure over a Jump Subroutine Instruction (JSR) network.

For the RPC protocol to work, the following conditions must be met:

1. Unique identification of all remotely called procedures on a given host. RPC requests contain three fields of identifiers - the number of the remote program (service), the version number of the remote program, and the number of the remote procedure of the specified program. The program number is assigned by the manufacturer of the service, the procedure number indicates the specific function of this service

2. Identification of the RPC protocol version. RPC messages contain an RPC protocol version field. It is used to match the formats of the transmitted parameters when the client is working with different versions of RPC.

3. Providing mechanisms for authenticating the client to the server. The RPC protocol provides a procedure for authenticating the client in the service, and, if necessary, with each request or sending a response to the client. In addition, RPC allows various additional security mechanisms to be used.

RPC can use four types of authentication mechanisms:

AUTH_NULL - no authentication required

AUTH_UNIX - UNIX standard authentication

AUTH_SHORT - UNIX standard authentication with its own encoding structure

AUTH_DES - DES authentication

4. Identification of messages in response to the corresponding requests. RPC response messages contain the ID of the request they were based on. This identifier can be called the transaction identifier of the RPC call. This mechanism is especially useful when working in asynchronous mode and when executing a sequence of several RPC calls.

5. Identification of protocol errors. All network or server errors have unique identifiers by which each of the participants in the connection can determine the cause of the failure.

Protocol message structures

When transferring RPC messages over a transport protocol, several RPC messages can be located within one transport packet. In order to distinguish one message from another, a record marker (RM - Record Marker) is used. Each RPC message is "marked" with exactly one RM.

An RPC message can be composed of several fragments. Each chunk consists of four bytes of header and (0 to 2 ** 31-1) data. The first bit of the header indicates whether the chunk is the last, and the remaining 31 bits indicate the length of the data packet.

The structure of RPC is formally described in the language of description and representation of data formats - XDR with additions concerning the description of procedures. You could even say that the RPC markup language is an extension of XDR, supplemented by work with procedures.

The structure of the RPC package looks like this:

struct rpc_msg (

unsigned int xid;

union switch (msg_type mtype) (

call_body cbody;

reply body rbody;

where xid is the identifier of the current transaction, call_body is the request packet, reply_body is the response packet. The request structure looks something like this:

struct call body (

unsigned int rpcvers;

unsigned int prog;

unsigned int vers;

unsigned int proc;

opaque_auth cred;

opaque_auth verf;

/ * procedure parameters * /

The reply_body structure can contain either a structure passed on in case of an error (in which case it contains the error code), or a structure for successful processing of the request (in which case it contains the returned data).

High-level programming interface.

Using subroutines in a program is the traditional way to structure a task, to make it clearer. The most frequently used subroutines are collected in libraries, where they can be used by various programs. In this case, we are talking about a local (local) call, that is, both the caller and the called objects work within the same program on the same computer.

In the case of a remote invocation, a process running on one computer starts the process on the remote computer (that is, it actually runs the procedure code on the remote computer). Obviously, a remote procedure call differs significantly from a traditional local one, but from the point of view of a programmer, there are practically no such differences, that is, the architecture of a remote procedure call allows you to simulate a local call.

However, if, in the case of a local call, the program passes parameters to the called procedure and receives the result of its work through the stack or shared memory areas, then in the case of a remote call, the transfer of parameters turns into a transmission of a request over the network, and the result of the work is in the received response.

This approach is a possible basis for creating distributed applications, and although many modern systems do not use this mechanism, the basic concepts and terms in many cases remain. When describing the RPC mechanism, we will traditionally refer to the calling process as the client, and the remote process that implements the procedure as the server.

A remote procedure call includes the following steps:

1. The client program makes a local call to a procedure called a stub. At the same time, the client "seems" that by calling the stub, it actually makes a call to the server procedure. Indeed, the client passes the required parameters to the stub, and it returns the result. However, this is not exactly how the client envisions it. The job of the stub is to accept arguments for the remote procedure, possibly convert them to some standard format, and form a network request. Packing arguments and making a network request is called marshalling.

2. The network request is sent over the network to the remote system. To do this, the stub uses the appropriate calls, for example, those discussed in the previous sections. Note that in this case, various transport protocols can be used, and not only of the TCP / IP family.

3. On the remote host, everything happens in reverse order. The server stub waits for the request and, on receipt, retrieves the parameters — the arguments of the procedure call. Extracting (unmarshalling) can involve necessary conversions (for example, changing the order of the bytes).

4. The stub makes a call to the real server procedure to which the client's request is addressed, passing it the arguments received over the network.

5. After completing the procedure, control returns to the server stub, passing the required parameters to it. Like a client stub; the server stub converts the values ​​returned by the procedure to form a network response message that is sent over the network to the system from which the request came.

6. The operating system passes the received message to the client stub, which, after the necessary transformation, passes the values ​​(which are the values ​​returned by the remote procedure) to the client, which interprets this as a normal return from the procedure.

Thus, from the client's point of view, it makes a remote procedure call as it would for a local one. The same can be said about the server: the procedure is called in the standard way, an object (server stub) calls the local procedure and receives the values ​​returned by it. The client treats the stub as a callable server procedure, and the server interprets its own stub as the client.

Thus, stubs constitute the core of the RPC system, responsible for all aspects of the generation and transmission of messages between the client and the remote server (procedure), although both the client and the server assume that the calls are made locally. This is the basic concept of RPC - to completely hide the distributed (network) nature of communication in the stub code. The advantages of this approach are obvious: both the client and the server are independent of the network implementation, they both operate within a distributed virtual machine, and procedure calls have a standard interface.

Passing parameters

Passing value parameters is straightforward. In this case, the client stub places the parameter value in the network request, possibly performing conversions to the standard form (for example, changing the byte order). The situation with passing pointers is much more complicated, when the parameter is the address of the data, and not their value. Passing an address in a request is meaningless, since the remote procedure is executed in a completely different address space. The simplest RPC solution is to prevent clients from passing parameters otherwise than by value, although this certainly imposes serious restrictions.

Binding

Before a client can call a remote procedure, it must bind to the remote system hosting the required server. Thus, the task of linking is split into two:

Finding the Remote Host with the Desired Server

Finding the required server process on a given host

Various approaches can be used to find a host. A possible option is to create some kind of centralized directory in which hosts announce their servers, and where the client, if desired, can choose the host and procedure address suitable for him.

Each RPC procedure is uniquely identified by a program and procedure number. The program number defines a group of remote procedures, each of which has its own number. Each program is also assigned a version number, so that when minor changes are made to the program (for example, when a procedure is added), there is no need to change its number. Usually, several functionally similar procedures are implemented in one program module, which, when launched, becomes the server of these procedures, and which is identified by the program number.

Thus, when a client wants to call a remote procedure, he needs to know the program, version, and procedure numbers that provide the required service.

To pass the request, the client also needs to know the host's network address and port number associated with the server program providing the required procedures. This is done using the portmap (IM) daemon (called rpcbind (IM) on some systems). The daemon runs on a host that provides remote procedure services and uses a well-known port number. When a server process initializes, it registers its routines and port numbers with portmap (IM). Now, when the client needs to know the port number to call a particular procedure, it sends a request to the portmap (IM) server, which in turn either returns the port number, or redirects the request directly to the RPC server and returns a response to the client when executed. In any case, if the required procedure exists, the client receives the procedure's port number from the portmap (IM) server, and further requests can be made directly to this port.

Handling exceptions

Handling exceptions when calling local procedures is not particularly problematic. UNIX handles process errors such as division by zero, invalid memory accesses, and so on. Calling a remote procedure increases the likelihood of error situations. Added to server and stub errors are errors related to, for example, receiving an erroneous network message.

For example, when using UDP as the transport protocol, messages are retransmitted after a specified timeout. An error is returned to the client if, after a certain number of attempts, a response from the server has not been received. In the case where the TCP protocol is used, an error is returned to the client if the server terminated the TCP connection.

Call semantics

Calling a local procedure unambiguously leads to its execution, after which control returns to the main program. The situation is different when calling a remote procedure. It is impossible to establish when exactly the procedure will be executed, whether it will be performed at all, and if so, how many times? For example, if the request is received by the remote system after the server program terminates abnormally, the procedure will not be executed at all. If the client, after not receiving a response after a certain period of time (timeout), resends the request, then a situation may arise when the response is already being transmitted over the network, and the repeated request is again accepted for processing by the remote procedure. In this case, the procedure will be performed several times.

Thus, the execution of a remote procedure can be characterized by the following semantics:

- One and only one time. This behavior (in some cases the most desirable) is difficult to enforce due to potential server crashes.

- Maximum times. This means that the procedure was either not performed at all, or was performed only once. A similar statement can be made when an error is received instead of a normal response.

- At least one time. The procedure was probably performed once, but more is possible. For normal operation in such a situation, the remote procedure must have the property of idempotency (from the English idemponent). This property is possessed by a procedure, the repeated execution of which does not cause cumulative changes. For example, reading a file is idempotent, but adding text to a file is not.

Data presentation

When the client and server run on the same system on the same computer, there are no data incompatibility issues. The binary data is represented in the same way for both the client and the server. In the case of a remote call, the matter is complicated by the fact that the client and the server can run on systems with different architectures with different data representations (for example, floating point value representation, byte ordering, etc.)

Most RPC implementations define some standard representation of data to which all values ​​passed in requests and responses must be converted.

For example, the format for representing data in RPC from Sun Microsystems is as follows:

Byte Order - Most Significant - Last

Floating Point Representation - IEEE

Character representation - ASCII

In terms of functionality, the RPC system is intermediate between the application layer and the transport layer. According to the OSI model, this provision corresponds to the presentation and session layers. Thus, RPC is theoretically independent from the network implementation, in particular from the transport layer network protocols.

Software implementations of the system, as a rule, support one or two protocols. For example, Sun Microsystems' RPC system supports messaging using the TCP and UDP protocols. The choice of one or another protocol depends on the requirements of the application. The choice of UDP is justified for applications with the following characteristics:

Called procedures are idempotent

The size of the arguments passed and the returned result is less than the size of the UDP packet - 8 KB.

The server provides work with several hundred clients. Since, when working with TCP protocols, the server is forced to maintain a connection with each of the active clients, this takes up a significant part of its resources. UDP is less resource intensive in this regard.

On the other hand, TCP provides efficient operation of applications with the following characteristics:

Application Requires Reliable Transfer Protocol

Called Procedures Are Not Identical

Arguments or returned result is larger than 8KB

The choice of the protocol usually remains with the client, and the system organizes the formation and transmission of messages in different ways. So, when using the TCP protocol, for which the transmitted data is a stream of bytes, it is necessary to separate the messages from each other. This can be done, for example, using the RFC1057 "RPC: Remote Procedure Call Protocol specification version 2" record labeling protocol, which precedes each message with a 32-bit integer specifying the message size in bytes.

The situation is different with the semantics of the call. For example, if RPC is performed using an unreliable transport protocol (UDP), the system retransmits the message at short intervals (timeouts). If the client application does not receive a response, then it is safe to say that the procedure has been executed zero or more times. If a response has been received, the application can conclude that the procedure has been executed at least once. With reliable transport protocol (TCP), when a response is received, the procedure can be said to have been executed once. If no response is received, it is impossible to say for sure that the procedure was not performed3.

How it works?

Essentially, the actual RPC system is built into the client program and the server program. It is gratifying that when developing distributed applications, you do not have to delve into the details of the RPC protocol or program message processing. The system assumes the existence of an appropriate development environment, which greatly facilitates the life of the creators of application software. One of the key points in RPC is that the development of a distributed application begins with the definition of an object interface - a formal description of server functions, written in a special language. Client and server stubs are then automatically generated from this interface. The only thing that needs to be done after this is to write the actual procedure code.

As an example, consider the RPC from Sun Microsystems. The system consists of three main parts:

Rpcgen (1) is an RPC compiler that generates client and server stubs as C programs based on the description of the remote procedure interface.

Library XDR (eXternal Data Representation), which contains functions for converting various types of data into a machine-independent form, allowing the exchange of information between heterogeneous systems.

A library of modules that ensure the operation of the system as a whole.

Let's look at an example of a basic distributed event logging application. The client, at startup, calls the remote procedure to write a message to the log file of the remote computer.

To do this, you will have to create at least three files: the specification of the interfaces of the log.x remote procedures (in the interface description language), the actual text of the log.c remote procedures, and the text of the client's main program main () - client.c (in the C language).

The rpcgen (l) compiler generates three files based on the log.x specification: the C client and server stub text (log clnt.c and log svc.c) and the log.h definition file used by both stubs.

So, let's look at the source code of the programs.

This file specifies the registration parameters of the remote procedure — program, version, and procedure numbers — and defines the calling interface — input arguments and return values. Thus, the RLOG procedure is defined, which takes a string as an argument (which will be written to the log), and the return value, by default, indicates the success or failure of the ordered operation.

program LOG_PROG (

version LOG_VER (

int RLOG (string) = 1;

) = 0x31234567;

The rpcgen (l) compiler generates a header file log.h where, in particular, the procedures are defined:

log.h

* Please do not edit this file.

* It was generated using rpcgen.

#ifndef _LOG_H_RPCGEN

#define _LOG_H_RPCGEN

#include

/ * Program number * /

#define LOG_PROG ((unsigned long) (0x31234567))

#define LOG_VER ((unsigned long) (1)) / * Version number * /

#define RLOG ((unsigned long) (1)) / * Routine number * /

extern int * rlog_l ();

/ * Internal procedure - we won't have to use it * / extern int log_prog_l_freeresult ();

#endif / *! _LOG_H_RPCGEN * /

Let's take a closer look at this file. The compiler translates the RLOG name defined in the interface descriptor into rlog_1, replacing uppercase characters with lowercase ones and adding the program version number with an underscore. The return type has changed from int to int *. This is the rule - RPC allows you to send and receive only the addresses of the parameters declared when describing the interface. The same rule applies to the string passed as an argument. Although this does not follow from the print.h file, in fact, the address of the line is also passed as an argument to the rlog_l () function.

In addition to the header file, the rpcgen (l) compiler generates client stub and server stub modules. Essentially, the text of these files contains all the code for the remote call.

The server stub is the head program that handles all network interaction with the client (more precisely, with its stub). To perform the operation, the server stub makes a local call to the function, the text of which must be written:

log.c

#include

#include

#include

#include "log.h"

int * rlog_1 (char ** arg)

/ * The return value must be defined as static * /

static int result;

int fd; / * Log file descriptor * /

/ * 0 open the log file (create it if it does not exist), in case of failure, return the error code result == 1. * /

if ((fd = open ("./ server .log",

O_CREAT | O_RDWR | O_APPEND))< 0) return (&result);

len = strlen (* arg);

if (write (fd, * arg, strlen (* arg))! = len)

return (& result); / * Return the result - address result * /

The client stub takes an argument passed to the remote procedure, makes the necessary transformations, issues a request to the portmap (1M) server, communicates with the remote procedure server, and finally passes the return value to the client. For the client, a remote procedure call is a stub call and is no different from a regular local call.

client.c

#include

#include "log.h"

main (int argc, char * argv)

char * server, * mystring, * clnttime;

if (argc! = 2) (

fprintf (stderr, "Call format:% s Host_address \ n",

/ * Get the client descriptor. In case of failure, we will inform you about

impossibility of establishing connection with the server * /

if ((с1 = clnt_create (server,

LOG_PROG, LOG_VER, "udp")) == NULL) (

clnt_pcreateerror (server);

/ * Allocate a buffer for the string * /

mystring = (char *) malloc (100);

/ * Determine the time of the event * /

bintime = time ((time_t *) NULL);

clnttime = ctime (& bintime);

sprintf (mystring, "% s - Client started", clnttime);

/ * Let's send a message for the log - the time when the client started working. In case of failure, we will report an error * /

if ((result = rlog_l (& mystring, cl)) == NULL) (

fprintf (stderr, "error2 \ n");

clnt_perror (cl, server);

/ * In case of failure on the remote computer, we will report an error * /

if (* result! = 0)

fprintf (stderr, "Error writing to log \ n");

/ * 0 free the descriptor * /

cint destroy (cl);

The client stub log_clnt.c is compiled with the client.c module to get the client executable.

cc -o rlog client.c log_clnt.c -Insl

The log_svc.c server stub and the log.c routine are compiled to get the server executable.

cc -o logger log_svc.c log.c -Insl

Now on some host server.nowhere.ru it is necessary to start the server process:

Then, when the rlog client is started on another machine, the server will add a corresponding entry to the log file.

The scheme of RPC operation in this case is shown in Fig. 1. Modules interact as follows:

1. When the server process starts, it creates a UDP socket and binds any local port to that socket. The server then calls the svc_register (3N) library function to register program numbers and version numbers. To do this, the function calls the portmap (IM) process and passes the required values. The portmap (IM) server is usually started during system initialization and binds to some well-known port. Portmap (3N) now knows the port number for our program and version. The server is waiting to receive the request. Note that all described actions are performed by a server stub generated by the rpcgen (IM) compiler.

2. When rlog starts, the first thing it does is call the library function clnt_create (3N), giving it the address of the remote system, the program and version numbers, and the transport protocol. The function makes a request to the portmap (IM) server of the remote system server.nowhere.m and obtains the remote port number for the log server.

3. The client calls the rlog_1 () routine defined in the client stub and transfers control to the stub. This, in turn, forms the request (converting the arguments to XDR format) in the form of a UDP packet and forwards it to the remote port received from the portmap (IM) server. Then it waits for a response for some time and, if not received, resends the request. Under favorable circumstances, the request is accepted by the logger server (server stub module). The stub determines which function was called (by the procedure number) and calls the rlog_1 () function of the log.c module. After control returns back to the stub, the stub converts the value returned by the rlog_1 () function into XDR format, and forms the response also in the form of a UDP packet. Upon receiving the response, the client stub extracts the returned value, transforms it, and returns it to the client host.


Any modification of the Windows operating system, starting from the XP version, includes a service component designated as RPC. What it is, ordinary users for the most part do not know, moreover, they do not know what this service is for and how it works. In this regard, it is proposed to consider some basic aspects related to the component itself, the principles of its operation and the area of ​​use without describing unnecessary and complex technical terms. Let us dwell separately on possible service errors and methods for their quick elimination.

Remote procedures (remote procedure call): what is it?

Apparently, many users, based on the name of this service component, have already concluded what it is. Indeed, remote procedures (calling remote procedures) imply some actions when they are executed not on the local computer, but on the remote (most often on the server).

That is, the request is formed on one terminal, then transferred to another, where it is executed, after which a response (report) on the execution is returned to the first computer. But this is only a primitive explanation. In fact, everything is much more complicated, since here you need to take into account the data transfer protocols (UDP, TCP, HTTP) and many other mechanisms.

What is this service for?

Despite its main purpose, RPC RPC can be used on one computer instead of on different computers. The simplest example is calling a function of one program from another application. Many musicians who work with virtual studios and sequencers know that each such application has its own audio editing or processing module, which does not always meet the requirements of the user. And any studio allows you to connect any other external program instead.

For example, in the settings of the FL Studio sequencer, you can specify another application (say, Adobe Audition), which will be used by default for editing sound files (samples) in the main program environment. At the same time, the connection of Adobe Audition to FL Studio will be carried out not through virtual hosts such as VST, RTAS or DX, but directly through the use of the RPC service. It goes without saying that this example is not the only one, since the scope of the described component is much wider.

Very often this service is also associated with the distribution of the computing load on the terminals, between which an interactive connection is established. At the same time, if the load on the computing resources of several computers is evenly distributed, maximum performance can be achieved only if small amounts of data are exchanged and fast response between components.

Remote Procedure Call Failure: What is the Cause?

Unfortunately, due to this demand, the occurrence of failures and errors associated with this service is a fairly common occurrence.

As a result, it becomes impossible not only to use the component itself. Sometimes it is not even possible to access some of the system settings, and Windows XP just crashes, after which it can be quite problematic to restore it to a normal working state. Another issue is the online DISM repair tool included with the operating system.

It is with the violations in its work that the appearance of error 1726 is associated, which directly affects the functioning of the components of the RPC service.

The main reasons for such failures are called the invocation of a system checker or system restore when the DISM process is active or cannot shutdown gracefully (for example, when the DISM and SFC tools are started from two command consoles at the same time); when the service runs in parallel with servicing the RPC components; when the service is blocked by antivirus software.

Therefore, if RPC fails on Windows 7 and above, the first thing to do is exit DISM, restart your computer, and start the service again. If this does not help, you can try to switch to safe mode and completely disable anti-virus protection for the duration of the recovery. We will dwell on additional measures that help fix any failure during a remote procedure call and in any modification of Windows. In the meantime, let's look at the issues related to disabling this system component (alas, many users who do not know the essence of the issue are trying to do just such things).

Can I disable the RPC service?

So let's see how realistic it is to deactivate the RPC. Remote procedures, based on the recommendations of the developers, must not be disabled under any circumstances. It is important! In principle, she herself will not allow this. There are, of course, some workarounds that involve the use of additional software, but for obvious reasons, the names of such applications are not given, since if they are used incorrectly, the entire system can become unusable.

Consequences of Disabling RPC Processes

Even if the user manages to somehow disable remote procedures (remote procedure calls), the consequences, unfortunately, can be very unpredictable. As already mentioned, Windows XP may stop working altogether, and in an OS with a higher rank, as a result, a huge number of system failures may appear, which cannot be eliminated, if only due to the lack of access to critical Windows settings and parameters, moreover, even in a safe mode or when starting from removable media. However, you can fix a crash when calling RPCs on Windows 10 or earlier operating systems. The method is not the easiest one, so you need to be very careful when using it.

Disable Remote Access Locator

So, the main RPC service cannot be disabled. But maybe it makes sense to deactivate some of its accompanying components? Yes, indeed, if you go to the section of system services and their components (services.msc), there you can find the so-called RPC locator.

But it can be deactivated without any fear of catastrophic consequences. After entering the editing of its parameters, you need to stop the component and set the startup type to disabled. Programs that can use remote procedures will make a remote procedure call anyway (without its help).

If for some reason the set parameters do not work, you can use the Windows installation disk, when booting from it, call the command line and enter the following:

  • cd X: \ i386 (X is the letter of the removable drive);
  • expand explorer.ex_% TEMP% \ explorer.exe;
  • expand svchost.ex_% TEMP% \ svchost.exe.

After the restart, the "Task Manager" is called, and it ends then the combination copy% TEMP% \ explorer.exe% SYSTEMROOT% / y is written in the command line, after which absolutely all svchost processes are terminated in the "Task Manager". Now you should be especially careful, because after finishing the processes within only sixty seconds in the command console you need to have time to write the command copy% TEMP% \ svchost.exe% systemroot% \ system32 / y.

If a user, for example, in normal or safe mode, has access to the system registry, in the editor (regedit) in the HKCC branch, find the CSConfigFlags parameter and assign it a value of zero.

Troubleshooting crash 1726

Finally, troubleshooting for error 1726 is also done through the registry. But in this case, in the HKLM branch, you need to find the RpcSs directory, and on the right, edit the value of the Start parameter.

It needs to be changed from four, usually set by default, to two, and then restart the system.

Afterword

That's all there is to RPC calls. Remote procedures, the principles of operation of this component in an extended version can be described for a very long time, but the emphasis in the presented material was made on a general acquaintance with the service and some methods of eliminating errors and failures that it can cause in a computer system. Ordinary users will have to be patient and be very careful, since one incorrect action in the registry can lead to a complete crash of the operating system.

Please note that these types of crashes are not addressed by any other means, such as optimizers and Windows operating system settings adjusters. With all the desire, neither the command line, nor, even more so, intervention in the registry at the level of editing keys in such software packages is not provided.

Lecture 4

4.1 Concept of Remote Procedure Call

The idea behind calling remote procedures (Remote Procedure Call - RPC) consists in extending the well-known and well-understood mechanism for transferring control and data within a program running on one machine to transfer control and data over a network. Remote procedure call facilities are designed to facilitate the organization of distributed computing. The most effective use of RPC is achieved in those applications in which there is interactive communication between remote components with short response times and relatively little data transfer. Such applications are called RPC-oriented.

The characteristic features of a call to local procedures are: asymmetry, that is, one of the interacting parties is the initiator; synchronicity, that is, the execution of the calling procedure when stops from the moment the request is issued and resumes only after returning from the called procedure.

Implementing remote calls is significantly more complex than implementing local procedure calls. To begin with, since the caller and the callee are executed on different machines, they have different address spaces, and this creates problems when passing parameters and results, especially if the machines are not identical. Since RPC cannot count on shared memory, this means that RPC parameters must not contain pointers to non-stack memory locations and that parameter values ​​must be copied from one computer to another. The next difference between RPC and a local call is that it necessarily uses the underlying communication system, but this should not be explicitly seen either in the definition of procedures or in the procedures themselves. Remoteness introduces additional problems. The execution of the calling program and the called local procedure on the same machine is done in a single process. But there are at least two processes involved in RPC implementation - one on each machine. If one of them crashes, the following situations may arise: if the calling procedure crashes, the remotely called procedures will become "orphaned", and if the remote procedures terminate abnormally, the callers will become "deprived parents" of the callers, who will vainly wait for a response from the remote procedures.

In addition, there are a number of problems associated with the heterogeneity of programming languages ​​and operating environments: data structures and procedure call structures supported in any one programming language are not supported in the same way in all other languages.


These and some other problems are solved by the widespread RPC technology that underlies many distributed operating systems.

Basic RPC Operations

To understand how RPC works, consider first executing a local procedure call on a conventional machine that is running autonomously. For example, let it be a system call

count = read (fd, buf, nbytes);

where fd is an integer;

buf - array of characters;

nbytes is an integer.

To make the call, the calling procedure pushes the parameters onto the stack in reverse order. After the call to read is executed, it places the return value in a register, advances the return address, and returns control to the calling procedure, which pops the parameters from the stack, returning it to its original state. Note that in C, parameters can be called either by reference (by name) or by value (by value). With respect to the called procedure, value parameters are initializable local variables. The called procedure can change them without affecting the value of the originals of these variables in the calling procedure.

If a pointer to a variable is passed to the called procedure, then changing the value of this variable by the called procedure will change the value of this variable for the calling procedure as well. This fact is essential for RPC.

There is also another mechanism for passing parameters, which is not used in C language. It is called call-by-copy / restore and consists in the need for the calling program to copy variables onto the stack as values, and then copy them back after the call is made over the original values ​​of the calling procedure.

It is up to the language designers to decide which parameter passing mechanism to use. Sometimes it depends on the type of data being transferred. In C, for example, integer and other scalar data are always passed by value, and arrays are always passed by reference.

The idea behind RPC is to make a remote procedure call look as close as possible to a local procedure call. In other words, make RPC transparent: the caller does not need to know that the called procedure is on a different machine, and vice versa.

RPC achieves transparency in the following way. When the called procedure is indeed remote, instead of the local procedure, another version of the procedure called the client stub (stub) is placed in the library. Like the original procedure, the stub is invoked using the calling sequence, and an interrupt occurs when accessing the kernel. Only unlike the original procedure, it does not put parameters in registers and does not ask the kernel for data, instead it generates a message to send to the kernel of the remote machine.

RPC steps

The interaction of software components when performing a remote procedure call is illustrated in Figure 2.

Figure 2. Remote Procedure Call

After the client stub has been called by the client program, its first task is to fill the buffer with the message being sent. On some systems, the client stub has a single, fixed-length buffer that is filled from the beginning every time a new request arrives. On other systems, a message buffer is a pool of buffers for individual message fields, some of these buffers already full. This method is especially useful when the packet is formatted with a large number of fields, but the values ​​of many of these fields do not change from call to call.

The parameters must then be converted to the appropriate format and inserted into the message buffer. At this point, the message is ready to be sent, so an interrupt is performed on the kernel call.

When the kernel gains control, it switches contexts, saves processor registers and a memory map (page descriptors), and sets up a new memory map that will be used to run in kernel mode. Since the kernel and user contexts are different, the kernel must copy the message exactly to its own address space, so that it can access it, remember the destination address (and possibly other header fields), and it must also pass it on to the network interface. This completes the work on the client side. The transmit timer is enabled, and the kernel can either cyclically poll for a response, or pass control to the scheduler, which chooses some other process to execute. In the first case, the query execution is accelerated, but there is no multiprogramming.

On the server side, the incoming bits are placed by the receiving hardware either in a built-in buffer or in RAM. When all information is received, an interrupt is generated. The interrupt handler verifies the correctness of the packet data and determines which stub should be passed it. If none of the stubs are expecting this packet, the handler must either place it in a buffer or discard it altogether. If there is a pending stub, then the message is copied to it. Finally, a context switch is performed, as a result of which the registers and the memory map are restored, taking the values ​​that they had at the moment when the stub made the receive call.

Now the server stub starts working. It unpacks the parameters and pushes them appropriately onto the stack. When everything is ready, a server call is made. After completing the procedure, the server sends the results to the client. For this, all the steps described above are performed, only in reverse order.

Figure 3 shows the sequence of commands that must be executed for each RPC call.

Figure 3. Stages of the RPC Procedure

The idea behind calling remote procedures (Remote Procedure Call - RPC) consists in extending the well-known and well-understood mechanism for transferring control and data within a program running on one machine to transfer control and data over a network. Remote procedure call facilities are designed to facilitate the organization of distributed computing.

The greatest efficiency of using RPC is achieved in those applications in which there is interactive communication between remote components with short response time and relatively small amount of transmitted data.Such applications are called RPC-oriented.

Local procedure calls are characterized by:

    Asymmetry, that is, one of the interacting parties is the initiator;

    Synchronicity, that is, execution of the calling procedure is suspended from the moment the request is issued and only resumed after the called procedure returns.

Implementing remote calls is significantly more complex than implementing local procedure calls.

1. Let's start with the fact that since the calling and called procedures are executed on different machines, they have different address spaces and this creates problems in transferring parameters and results, especially if the machines are not identical.

Since RPC cannot count on shared memory, this means that RPC parameters must not contain pointers to non-stack memory locations and what parameter values ​​must be copied from one computer to another.

2. The next difference between RPC and a local call is that it necessarily uses the underlying communication system however this should not be clearly visible in either the definition of the procedures or the procedures themselves .

Remoteness introduces additional problems. Executing the calling program and the called local procedure on the same machine implemented withina single process... But involved in RPC implementationat least two processes - one in each car... If one of them crashes, the following situations may arise:

    if the calling procedure crashes, the remotely called procedures become "orphaned", and

    abnormal termination of the remote procedures will make the callers "disadvantaged parents" and wait for a response from the remote procedures to no avail.

In addition, there is a number of problems associated with the heterogeneity of programming languages ​​and operating environments : Data structures and procedure call structures supported in any one programming language are not supported in the same way in all other languages.

These and some other problems are solved by the widespread RPC technology that underlies many distributed operating systems.

The idea behind RPC is to make a remote procedure call look as close as possible to a local procedure call. In other words, make RPC transparent: the caller does not need to know that the called procedure is on a different machine, and vice versa.

RPC achieves transparency in the following way. When the called procedure is indeed remote, instead of the local procedure, another version of the procedure called the client stub (stub) is placed in the library. Like the original procedure, the stub is invoked using the calling sequence (as in Figure 3.1), and an interrupt occurs when accessing the kernel. Only unlike the original procedure, it does not put parameters in registers and does not ask the kernel for data, instead, it generates a message to send to the kernel of the remote machine.

Rice... 3.2. Remote procedure call

Remote Procedure Call (RPC) Remote Procedure Call Concept

The idea behind Remote Procedure Call (RPC) is to extend the well-known and well-understood mechanism for transferring control and data within a program running on a single machine to transfer control and data over a network. Remote procedure call facilities are designed to facilitate the organization of distributed computing. The most effective use of RPC is achieved in those applications in which there is interactive communication between remote components with short response times and relatively little data transfer. Such applications are called RPC-oriented.

Local procedure calls are characterized by:

Asymmetry, that is, one of the interacting parties is the initiator; Synchronicity, that is, the execution of the calling procedure when stops from the moment the request is issued and resumes only after returning from the called procedure.

Implementing remote calls is significantly more complex than implementing local procedure calls. To begin with, since the caller and the callee are executed on different machines, they have different address spaces, and this creates problems when passing parameters and results, especially if the machines are not identical. Since RPC cannot count on shared memory, this means that RPC parameters must not contain pointers to non-stack memory locations and that parameter values ​​must be copied from one computer to another. The next difference between RPC and a local call is that it necessarily uses the underlying communication system, but this should not be explicitly seen either in the definition of procedures or in the procedures themselves. Remoteness introduces additional problems. The execution of the calling program and the called local procedure on the same machine is done in a single process. But there are at least two processes involved in RPC implementation - one on each machine. If one of them crashes, the following situations may arise: if the calling procedure crashes, the remotely called procedures will become "orphaned", and if the remote procedures terminate abnormally, the callers will become "deprived parents" of the callers, who will vainly wait for a response from the remote procedures.

In addition, there are a number of problems associated with the heterogeneity of programming languages ​​and operating environments: data structures and procedure call structures supported in any one programming language are not supported in the same way in all other languages.

These and some other problems are solved by the widespread RPC technology that underlies many distributed operating systems.

Basic RPC Operations

To understand how RPC works, consider first executing a local procedure call on a conventional machine that is running autonomously. For example, let it be a system call

Count = read (fd, buf, nbytes);

where fd is an integer,
buf is an array of characters,
nbytes is an integer.

To make the call, the calling procedure pushes the parameters onto the stack in reverse order (Figure 3.1). After the call to read is executed, it places the return value in a register, advances the return address, and returns control to the calling procedure, which pops the parameters from the stack, returning it to its original state. Note that in C, parameters can be called either by reference (by name) or by value (by value). With respect to the called procedure, value parameters are initializable local variables. The called procedure can change them without affecting the value of the originals of these variables in the calling procedure.

If a pointer to a variable is passed to the called procedure, then changing the value of this variable by the called procedure will change the value of this variable for the calling procedure as well. This fact is essential for RPC.

There is also another mechanism for passing parameters, which is not used in C language. It is called call-by-copy / restore and consists in the need for the calling program to copy variables onto the stack as values, and then copy them back after the call is made over the original values ​​of the calling procedure.

It is up to the language designers to decide which parameter passing mechanism to use. Sometimes it depends on the type of data being transferred. In C, for example, integer and other scalar data are always passed by value, and arrays are always passed by reference.

Rice. 3.1. a) The stack before the read call is made;
b) The stack during the execution of the procedure;
c) Stack after returning to the calling program

The idea behind RPC is to make a remote procedure call look as close as possible to a local procedure call. In other words, make RPC transparent: the caller does not need to know that the called procedure is on a different machine, and vice versa.

RPC achieves transparency in the following way. When the called procedure is indeed remote, instead of the local procedure, another version of the procedure called the client stub (stub) is placed in the library. Like the original procedure, the stub is invoked using the calling sequence (as in Figure 3.1), and an interrupt occurs when accessing the kernel. Only unlike the original procedure, it does not put parameters in registers and does not ask the kernel for data, instead it generates a message to send to the kernel of the remote machine.

RPC steps

The interaction of software components during the execution of a remote procedure call is illustrated in Figure 3.2. After the client stub has been called by the client program, its first task is to fill the buffer with the message being sent. On some systems, the client stub has a single, fixed-length buffer that is filled from the beginning every time a new request arrives. On other systems, a message buffer is a pool of buffers for individual message fields, some of these buffers already full. This method is especially useful when the packet is formatted with a large number of fields, but the values ​​of many of these fields do not change from call to call.

The parameters must then be converted to the appropriate format and inserted into the message buffer. At this point, the message is ready to be sent, so an interrupt is performed on the kernel call.

Rice. 3.2. Remote procedure call

When the kernel gains control, it switches contexts, saves processor registers and a memory map (page descriptors), and installs a new memory map that will be used to run in kernel mode. Since the kernel and user contexts are different, the kernel must copy the message exactly to its own address space so that it can access it, remember the destination address (and possibly other header fields), and it must also pass it on to the network interface. This completes the work on the client side. The transmit timer is enabled, and the kernel can either cyclically poll for a response, or pass control to a scheduler that chooses some other process to execute. In the first case, the query execution is accelerated, but there is no multiprogramming.

On the server side, the incoming bits are placed by the receiving hardware either in a built-in buffer or in RAM. When all information is received, an interrupt is generated. The interrupt handler verifies the correctness of the packet data and determines which stub should be passed it. If none of the stubs are expecting this packet, the handler must either buffer it or discard it altogether. If there is a pending stub, then the message is copied to it. Finally, a context switch is performed, as a result of which the registers and the memory map are restored, taking the values ​​that they had at the moment when the stub made the receive call.

Now the server stub starts working. It unpacks the parameters and pushes them appropriately onto the stack. When everything is ready, a server call is made. After completing the procedure, the server sends the results to the client. For this, all the steps described above are performed, only in reverse order.

Figure 3.3 shows the sequence of commands that must be executed for each RPC call, and Figure 3.4 shows how much of the total RPC execution time is spent executing each of the 14 stages described. The research was carried out on a DEC Firefly multiprocessor workstation, and although the presence of five processors necessarily influenced the measurement results, the histogram shown in the figure provides an overview of the RPC execution process.

Rice. 3.3. RPC Procedure Steps

Rice. 3.4. Allocating Time Between 14 RPC Runs

1. Call stub

2. Prepare the buffer

3. Pack parameters

4. Fill in the title field

5. Calculate the checksum in the message

6. Interrupt to core

7. Package queue for execution

8. Sending a message to the controller via the QBUS

9. Ethernet transmission time

10. Get a packet from the controller

11. Interrupt handling procedure

12. Calculating checksum

13. Switching context to user space

14. Executing a server stub

Dynamic linking

Consider the question of how the client specifies the server location. One method for solving this problem is to directly use the server's network address in the client program. The disadvantage of this approach is its extreme inflexibility: when the server is moved, or when the number of servers is increased, or when the interface is changed, in all these and many other cases, it is necessary to recompile all programs that used a hard assignment of the server address. In order to avoid all these problems, some distributed systems use what is called dynamic linking.

The starting point for dynamic binding is the formal definition (specification) of the server. The specification contains the name of the file server, version number and a list of service procedures provided by this server for clients (Figure 3.5). For each procedure, a description of its parameters is given, indicating whether this parameter is input or output relative to the server. Some parameters can be simultaneously input and output - for example, some array that is sent by the client to the server, modified there, and then returned back to the client (copy / restore operation).

Rice. 3.5. RPC Server Specification

The formal server specification is used as input to a stub generator program that creates both client and server stubs. They are then placed in the appropriate libraries. When the user (client) program calls any procedure defined in the server specification, the corresponding stub procedure is associated with the program binary. Likewise, when a server is compiled, the server stubs are associated with it.

When the server starts up, its very first action is to pass its server interface to a special program called binder. This process, known as the server registration process, involves the server sending its name, version number, unique identifier and descriptor of the server's location. The descriptor is system independent and can be an IP, Ethernet, X.500, or some other address, and may also contain other information such as authentication.

When the client calls one of the remote procedures for the first time, for example, read, the client stub sees that it is not yet connected to the server and sends a message to the binder program asking it to import the interface of the correct version of the required server. If such a server exists, then binder passes a handle and a unique identifier to the client stub.

The client stub uses a descriptor as an address when sending a request message. The message contains parameters and a unique identifier that the server core uses in order to forward the incoming message to the correct server if there are several of them on this machine.

This method of importing / exporting interfaces is very flexible. For example, there may be multiple servers supporting the same interface, and clients are randomly distributed among the servers. Within the framework of this method, it becomes possible to periodically poll the servers, analyze their performance and, in case of failure, automatic shutdown, which increases the overall fault tolerance of the system. This method can also support client authentication. For example, a server might determine that it can only be used by clients from a specific list.

However, dynamic linking has disadvantages, such as the additional overhead (time) of exporting and importing interfaces. The magnitude of these costs can be significant, since many client processes exist for a short time, and at each start of the process, the interface import procedure must be performed again. In addition, in large distributed systems, the binder program can become a bottleneck, and creating multiple programs of a similar purpose also increases the overhead of creating and synchronizing processes.

RPC semantics on failure

Ideally, RPC should function correctly in the event of a failure. Consider the following classes of failures:

The client cannot determine the location of the server, for example, if the required server fails, or because the client program was compiled a long time ago and used an old version of the server interface. In this case, a message containing an error code is received in response to the client's request. Lost client-to-server request. The simplest solution is to repeat the request after a certain time. Lost reply message from server to client. This option is more complicated than the previous one, since some procedures are not idempotent. An idempotent procedure is a procedure whose execution request can be repeated several times, and the result will not change. An example of such a procedure is reading a file. But the procedure for withdrawing a certain amount from a bank account is not idempotent, and if the answer is lost, a repeated request can significantly change the state of the client's account. One of the possible solutions is to bring all procedures to an idempotent form. However, in practice this is not always possible, so another method can be used - sequential numbering of all requests by the client kernel. The server core remembers the number of the most recent request from each of the clients, and upon receipt of each request, it analyzes whether this request is primary or repeated. The server crashed after receiving the request. The property of idempotency is also important here, but unfortunately the query numbering approach cannot be applied. In this case, it matters when the failure occurred - before or after the operation. But the client kernel cannot recognize these situations, it only knows that the response timed out. There are three approaches to this problem: Wait until the server restarts and try again. This approach ensures that the RPC has been completed at least once, and possibly more. Immediately report the error to the application. This approach ensures that the RPC has been executed at most once. The third approach does not guarantee anything. When the server fails, there is no support for the client. RPC may or may not be performed at all, or many times. In any case, this method is very easy to implement.

None of these approaches are very attractive. And the ideal option that would guarantee exactly one RPC execution, in the general case, cannot be implemented for reasons of principle. Suppose, for example, a remote operation is printing some text, which includes loading the printer buffer and setting one bit in some control register of the printer, as a result of which the printer starts. A server crash can occur either a microsecond before or a microsecond after the control bit is set. The moment of failure entirely determines the recovery procedure, but the client cannot know about the moment of failure. In short, the possibility of a server crash radically changes the nature of RPC and clearly reflects the difference between a centralized system and a distributed system. In the first case, a server crash leads to a client crash, and recovery is impossible. In the second case, it is possible and necessary to perform the actions to restore the system.

The client crashed after submitting the request. In this case, calculations are performed on the results that no one expects. Such calculations are called "orphans". The presence of orphans can cause various problems: overhead of CPU time, blocking resources, replacing the response to the current request with the response to a request that was issued by the client machine before the system was restarted.

What to do with orphans? Let's consider 4 possible solutions.

Destruction. Before the client stub sends an RPC message, it makes a note in the log notifying what it will do now. The log is stored on disk or other fault tolerant memory. After the accident, the system reboots, the log is analyzed and the orphans are eliminated. The disadvantages of this approach include, firstly, the increased costs associated with writing about each RPC to disk, and, secondly, the possible inefficiency due to the appearance of second generation orphans generated by RPC calls issued by first generation orphans. Reincarnation. In this case, all problems are solved without using disk writing. The method consists of dividing time into sequentially numbered periods. When the client reboots, it broadcasts to all machines to start a new period. Upon receipt of this message, all remote computations are terminated. Of course, if the network is segmented, then some orphans may survive. Soft reincarnation is similar to the previous case, except that not all remote computations are found and destroyed, but only those of the rebooting client. Expiration date. Each request is assigned a standard time interval T, during which it must be fulfilled. If the request is not completed within the allotted time, then an additional quantum is allocated. Although this requires additional work, if, after a client crash, the server waits for an interval T before rebooting the client, then all orphans are necessarily destroyed.

In practice, none of these approaches is desirable; moreover, killing orphans can exacerbate the situation. For example, suppose an orphan has locked one or more database files. If the orphan is suddenly destroyed, then these locks will remain, in addition, the destroyed orphans may remain standing in various system queues, in the future they may cause the execution of new processes, etc.