RPC restructuring finished (mostly).

Jeremy Allison jeremy at valinux.com
Tue Feb 27 00:48:13 GMT 2001


Hi all,

	I've been very busy lately splitting the RPC pipe
serving code in smbd into interface and implementation parts. The
ultimate goal (for Samba 3.0) is that the interface parts
will be auto-generated from IDL files, and only the implementation
backend part will need to be written by hand.

If you take a look at the new code, you'll find that the
files in rpc_server/ have been split in two. A srv_XXX.c
file, which is the interface part, and a srv_XXX_nt.c
file, which is the implementation part.

The srv_XXX.c files are now very simple (other than srv_spoolss.c
which still needs a little work), and have a completely
regular format.

For example, if the RPC call is sent a SERVER_Q_XXX structure
(Q is for query) and returns a SERVER_R_XXX structure (R is
for reply) then the code to set up the interface and call the
implementation looks like (where the "server" prefix is replaced
by the RPC pipe name in the real code) :

static BOOL api_server_XXX(pipes_struct *p)
{
    SERVER_Q_XXX q_u;
    SERVER_R_XXX r_u;
    prs_struct *data = &p->in_data.data;
    prs_struct *rdata = &p->out_data.rdata;

    ZERO_STRUCT(q_u);
    ZERO_STRUCT(r_u);

    if(!server_io_q_xxx("", &q_u, data, 0)) {
        DEBUG(0,("api_server_XXX: unable to unmarshall SERVER_Q_XXX.\n"));
        return False;
    }

    r_u.status = _server_XXX(p, &q_u, &r_u);

    /* store the response in the SMB stream */
    if(!server_io_r_XXX("", &r_u, rdata, 0)) {
        DEBUG(0,("api_server_XXX: unable to marshall SERVER_R_XXX.\n"));
        return False;
    }

    return True;
} 

Given the RPC name server_XXX then everything in this
function can be auto-generated from IDL files. In addition,
the implementation interface is standardised to be (as mentioned,
the spoolss interface is currently the only exception to this) :

uint32 _server_XXX(pipes_struct *p, SERVER_Q_XXX *q_u, SERVER_R_XXX *r_u)

All the current srv_XXX_nt.c files (except srv_spoolss_nt.c)
follow this format, and so it should be much easier to add
more RPC functions as they are decoded. To add a new RPC call
you write the structure definition in the include/rpc_XXX.h
file, add the interface function to the rpc_server/srv_XXX.c
file in the above format and then do the real work of fleshing
out the implementation in the rpc_server/srv_XXX_nt.c file.

In addition, the memory allocation has been greatly improved.
A talloc context is created when an RPC call is begun, and is
guarenteed to stay alive until the last packet in the reply
RPC has been read by the client. This means that all malloc()/free()
code that has to back out mallocs on error can be replaced with
either prs_alloc_mem() or talloc() calls - they both allocate
from the same RPC talloc context. I've used this to throw out a
lot of fragile error processing code, and make the flow easier
to understand.

I know this is a lot of changes, but it should give us a 
very robust framework for adding more services/rpc's and
make Andrew's job of moving us to IDL generated RPC code
(which will be more correct and make it easier to add NT
RPCs) much more simple.

HEAD is currently lagging behind slightly in this work in
that the SAMR pipe has not been converted in HEAD, due to
the passdb database interface changes there. I intend to
work on that as soon as 2.2 has stabilized.

Just letting everyone know what the flurry of CVS commits
on 2.2 have been about - let me know any comments/questions.

Cheers,

	Jeremy Allison,
	Samba Team.

-- 
--------------------------------------------------------
Buying an operating system without source is like buying
a self-assembly Space Shuttle with no instructions.
--------------------------------------------------------




More information about the samba-technical mailing list