Motr  M0
Rpc-at

Data Structures

struct  rpc_at_bulk
 
struct  m0_rpc_at_bulk_rep
 
struct  m0_rpc_at_extra
 
struct  m0_rpc_at_buf
 

Enumerations

enum  m0_rpc_at_type {
  M0_RPC_AT_EMPTY = 0, M0_RPC_AT_INLINE = 1, M0_RPC_AT_BULK_SEND = 2, M0_RPC_AT_BULK_RECV = 3,
  M0_RPC_AT_BULK_REP = 4, M0_RPC_AT_TYPE_NR
}
 
enum  { M0_RPC_AT_UNKNOWN_LEN = 0 }
 

Functions

 M0_TL_DESCR_DECLARE (rpcbulk, M0_EXTERN)
 
 M0_TL_DECLARE (rpcbulk, M0_INTERNAL, struct m0_rpc_bulk_buf)
 
static struct rpc_at_bulkrpc_at_bulk (const struct m0_rpc_at_buf *ab)
 
static m0_bcount_t rpc_at_bulk_cutoff (const struct m0_rpc_conn *conn)
 
static struct m0_net_domainrpc_at_bulk_ndom (const struct rpc_at_bulk *atbulk)
 
static struct m0_rpc_connfom_conn (const struct m0_fom *fom)
 
static uint64_t rpc_at_bulk_segs_nr (const struct rpc_at_bulk *atbulk, m0_bcount_t data_size, m0_bcount_t *seg_size)
 
static int rpc_at_bulk_nb_alloc (struct m0_rpc_at_buf *ab, uint64_t size)
 
static void rpc_at_bulk_nb_free (struct rpc_at_bulk *atbulk)
 
static int rpc_at_bulk_init (struct m0_rpc_at_buf *ab, const struct m0_rpc_conn *conn)
 
static void rpc_at_bulk_store_del (struct m0_rpc_bulk *rbulk)
 
static enum m0_net_queue_type rpc_at_bulk_qtype (struct m0_rpc_bulk *rbulk)
 
static void rpc_at_bulk_fini (struct rpc_at_bulk *atbulk)
 
static int rpc_at_bulk_csend (struct m0_rpc_at_buf *ab, const struct m0_buf *buf)
 
static int rpc_at_bulk_srecv (struct m0_rpc_at_buf *ab, struct m0_fom *fom)
 
static int rpc_at_bulk_srecv_rc (const struct m0_rpc_at_buf *ab, struct m0_buf *buf)
 
static int rpc_at_bulk_crecv (struct m0_rpc_at_buf *ab, uint32_t len)
 
static void rpc_at_ssend_ast_cb (struct m0_sm_group *grp, struct m0_sm_ast *ast)
 
static bool rpc_at_ssend_complete_cb (struct m0_clink *clink)
 
static int rpc_at_bulk_ssend (struct m0_rpc_at_buf *in, struct m0_rpc_at_buf *out, struct m0_buf *buf, struct m0_fom *fom)
 
M0_INTERNAL int m0_rpc_at_get (const struct m0_rpc_at_buf *ab, struct m0_buf *buf)
 
M0_INTERNAL int m0_rpc_at_load (struct m0_rpc_at_buf *ab, struct m0_fom *fom, int next_phase)
 
M0_INTERNAL void m0_rpc_at_init (struct m0_rpc_at_buf *ab)
 
M0_INTERNAL void m0_rpc_at_fini (struct m0_rpc_at_buf *ab)
 
M0_INTERNAL int m0_rpc_at_add (struct m0_rpc_at_buf *ab, const struct m0_buf *buf, const struct m0_rpc_conn *conn)
 
M0_INTERNAL bool m0_rpc_at_is_set (const struct m0_rpc_at_buf *ab)
 
M0_INTERNAL int m0_rpc_at_recv (struct m0_rpc_at_buf *ab, const struct m0_rpc_conn *conn, uint32_t len, bool force_bulk)
 
M0_INTERNAL int m0_rpc_at_reply (struct m0_rpc_at_buf *in, struct m0_rpc_at_buf *out, struct m0_buf *repbuf, struct m0_fom *fom, int next_phase)
 
M0_INTERNAL int m0_rpc_at_reply_rc (struct m0_rpc_at_buf *out)
 
M0_INTERNAL int m0_rpc_at_rep_get (struct m0_rpc_at_buf *sent, struct m0_rpc_at_buf *rcvd, struct m0_buf *out)
 
M0_INTERNAL bool m0_rpc_at_rep_is_bulk (const struct m0_rpc_at_buf *rcvd, uint64_t *len)
 
M0_INTERNAL int m0_rpc_at_rep2inline (struct m0_rpc_at_buf *sent, struct m0_rpc_at_buf *rcvd)
 
M0_INTERNAL void m0_rpc_at_detach (struct m0_rpc_at_buf *ab)
 
M0_INTERNAL uint64_t m0_rpc_at_len (const struct m0_rpc_at_buf *ab)
 
struct m0_rpc_at_bulk_rep M0_XCA_DOMAIN (rpc)
 
 M0_BASSERT (sizeof((struct m0_rpc_at_buf *) 0) ->u==sizeof(struct m0_rpc_at_extra))
 
 M0_BASSERT (offsetof(struct m0_rpc_at_buf, u.ab_extra.abr_bulk) >=sizeof((struct m0_rpc_at_buf *) 0) ->u.ab_buf)
 

Detailed Description

RPC adaptive transmission (AT) is an interface to send/receive buffers as a part of RPC item. AT implementation transfers the contents of the buffer to the receiver either:

Two roles are clearly distinguished:

Client to server buffer transmission

Client is able to attach m0_buf buffer (exactly one) to an RPC AT buffer (m0_rpc_at_buf). After that RPC AT buffer can be sent as part of RPC item. Actual buffer transfer method depends on:

Client code to initialise AT buffer:

rc = m0_rpc_at_add(ab, user_buf, rpc_mach);
if (rc == 0)
// Send RPC item containing ab.

Note, that AT buffer finalisation should be done after reply from server is received.

Server code to load AT buffer received in RPC item:

foo_tick(fom) {
switch (fom_phase(fom)) {
...
case PHASE_X:
...
return m0_rpc_at_load(&fop->ab, fom, PHASE_Y);
case PHASE_Y:
struct m0_buf buf;
rc = m0_rpc_at_get(&fop->ab, &buf);
// Process buf.
...
}
}

Note, that initialisation of AT buffer is not required.

Buffer reception from server

Client is able to request buffer from server by sending AT buffer of special type as part of RPC request. Identification of requested buffer on server side is specific to RPC item type. Server sends requested buffer by embedding AT buffer as part of reply RPC item.

Client specifies in request the preferred way of buffer transmission: inline or inbulk. For inbulk transmission client allocates incoming net buffer of sufficient size and sends its descriptor in request. Client uses empty buffer (of type M0_RPC_AT_EMPTY) to specify that inline transmission is preferred.

Server chooses the way of buffer transmission using the following algorithm:

Todo:
Another method of buffer transmission may be needed: "best". When client specifies this method it has to provide network buffer as with in-bulk case. The server sends the reply inline if possible, uses the netbuffer otherwise. This would allow return of large records (via in-bulk), while avoiding in-bulk overhead for small records.

Client code example:

int buf_request(uint32_t len, bool force, struct m0_buf *out, bool *rep_bulk)
{
// Initialise RPC item.
...
rc = m0_rpc_at_recv(ab, rmach, len, force);
if (rc == 0) {
if (rc == 0) {
// rep_ab is a pointer to AT buffer in RPC reply.
...
rc = m0_rpc_at_rep_get(ab, rep_ab, out);
if (rc != 0)
*rep_bulk = m0_rpc_at_rep_is_bulk(rep_ab,
&out.b_nob);
}
}
// Finalise RPC item.
...
return rc;
}
rep_bulk = false;
// Assume client doesn't have any idea about buffer size.
rc = buf_request(M0_RPC_AT_UNKNOWN_LEN, false, &buf, &rep_bulk);
if (rc != 0 && rep_bulk) {
// Re-request buffer, now forcing bulk.
len = buf->b.nob;
rc = buf_request(len, true, &buf, &rep_bulk);
}

Server code example:

foo_tick(fom) {
switch (fom_phase(fom)) {
...
case PHASE_X:
...
m0_rpc_at_init(&fom->fo_rep_fop->rep_ab);
return m0_rpc_at_reply(&fom->fo_fop->ab,
&fom->fo_rep_fop->rep_ab,
buf, fom, PHASE_Y);
case PHASE_Y:
// Check status. At this point requested buffer is
// inlined at reply FOP or sent via RPC bulk to client.
rc = m0_rpc_at_reply_rc(&fom->fo_rep_fop->rep_ab);
}
}

Note, that server shouldn't finalise RPC AT buffer that is used as the reply to the client request. The memory will be automatically de-allocated when a corresponding reply FOP is finalised.

Forcing RPC bulk method on client side is required in case if maximum RPC item size or inbulk threshold are configured differently on server and client. For example, client may have higher inbulk threshold and would prefer to use inline reception method, but server will return an error because of lower inbulk threshold.

Todo:
: Perform negotiation on inbulk threshold during connection establishment?

References:

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
M0_RPC_AT_UNKNOWN_LEN 

Definition at line 223 of file at.h.

◆ m0_rpc_at_type

Enumerator
M0_RPC_AT_EMPTY 
M0_RPC_AT_INLINE 
M0_RPC_AT_BULK_SEND 
M0_RPC_AT_BULK_RECV 
M0_RPC_AT_BULK_REP 
M0_RPC_AT_TYPE_NR 

Definition at line 214 of file at.h.

Function Documentation

◆ fom_conn()

static struct m0_rpc_conn* fom_conn ( const struct m0_fom fom)
static

Definition at line 90 of file at.c.

Here is the caller graph for this function:

◆ M0_BASSERT() [1/2]

M0_BASSERT ( sizeof((struct m0_rpc_at_buf *) 0) ->  u = =sizeof(struct m0_rpc_at_extra))

◆ M0_BASSERT() [2/2]

M0_BASSERT ( offsetof(struct m0_rpc_at_buf, u.ab_extra.abr_bulk) >=sizeof((struct m0_rpc_at_buf *) 0) ->u.  ab_buf)

◆ m0_rpc_at_add()

M0_INTERNAL int m0_rpc_at_add ( struct m0_rpc_at_buf ab,
const struct m0_buf buf,
const struct m0_rpc_conn conn 
)

Called once for an AT buffer. If this returns success, then AT buffer can be serialised as part of rpc item. On success, buffer content will be deallocated in m0_rpc_at_fini(), unless m0_rpc_at_detach() is called.

Precondition
conn != NULL

Definition at line 462 of file at.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ m0_rpc_at_detach()

M0_INTERNAL void m0_rpc_at_detach ( struct m0_rpc_at_buf ab)

Detaches internal data buffer from AT buffer.

Transfers data buffer ownership to the user, so user is responsible for its deallocation. For received AT buffer internal data buffer can be obtained via m0_rpc_at_rep_get(). For sent AT buffer it's the buffer provided in m0_rpc_at_add().

Definition at line 694 of file at.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ m0_rpc_at_fini()

M0_INTERNAL void m0_rpc_at_fini ( struct m0_rpc_at_buf ab)

Finalises AT buffer.

Should be called before container RPC item finalisation, but after RPC item is sent over network.

Definition at line 441 of file at.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ m0_rpc_at_get()

M0_INTERNAL int m0_rpc_at_get ( const struct m0_rpc_at_buf ab,
struct m0_buf buf 
)

Initialises user-supplied buffer with AT buffer data.

Should be called after m0_rpc_at_load() finished loading. Function doesn't actually copy AT buffer data, but assigns 'buf' fields to point to received data. The data is accessible until 'ab' is not finalised.

Returns result of loading invoked by m0_rpc_at_load().

See also
m0_rpc_at_load()

Definition at line 399 of file at.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ m0_rpc_at_init()

M0_INTERNAL void m0_rpc_at_init ( struct m0_rpc_at_buf ab)

Initialises AT buffer.

Should be called for AT buffer, that is not received from the network, e.g. before m0_rpc_at_add(), m0_rpc_at_recv(), m0_rpc_at_reply() (for out buffer).

Todo:
M0_PRE(M0_IS0(ab));

Definition at line 433 of file at.c.

Here is the caller graph for this function:

◆ m0_rpc_at_is_set()

M0_INTERNAL bool m0_rpc_at_is_set ( const struct m0_rpc_at_buf ab)

Checks whether AT buffer has some associated data.

AT buffer is considered to be empty if:

  • Buffer is initialised, but no data is attached (has type M0_RPC_AT_EMPTY).
  • Buffer is intented for buffer reception.
  • Buffer has type M0_RPC_AT_BULK_REP, but no bytes were transmitted via bulk.

Definition at line 492 of file at.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ m0_rpc_at_len()

M0_INTERNAL uint64_t m0_rpc_at_len ( const struct m0_rpc_at_buf ab)

Returns length of data attached to buffer.

Returned value interpretation depends on buffer type:

  • M0_RPC_AT_INLINE, M0_RPC_AT_BULK_SEND: length of the attached buffer;
  • M0_RPC_AT_BULK_RECV: total size of RPC bulk buffers reserved by client;
  • M0_RPC_AT_BULK_REP: size of buffer set by service regardless of rc.

Definition at line 709 of file at.c.

Here is the caller graph for this function:

◆ m0_rpc_at_load()

M0_INTERNAL int m0_rpc_at_load ( struct m0_rpc_at_buf ab,
struct m0_fom fom,
int  next_phase 
)

Loads AT buffer contents.

Fom unconditionally moves to 'next_phase'. Once AT buffer is fully loaded, fom tick function is called.

If the buffer is transmitted inline, then there is nothing to do and M0_FSO_AGAIN is returned. Otherwise, asynchronous buffer loading through RPC bulk is started and M0_FSO_WAIT is returned.

Returns value from m0_fom_phase_outcome.

See also
m0_rpc_at_get()

Definition at line 414 of file at.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ m0_rpc_at_recv()

M0_INTERNAL int m0_rpc_at_recv ( struct m0_rpc_at_buf ab,
const struct m0_rpc_conn conn,
uint32_t  len,
bool  force_bulk 
)

Prepares AT buffer reception request.

Parameters
connRPC connection.
lenExpected length of the buffer, ignored for inline.
force_bulkForce inbulk transmission method.
Precondition
conn != NULL

Definition at line 508 of file at.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ m0_rpc_at_rep2inline()

M0_INTERNAL int m0_rpc_at_rep2inline ( struct m0_rpc_at_buf sent,
struct m0_rpc_at_buf rcvd 
)

Transforms received AT buffer to inline type.

Regardless of actual transmission method used, modify received buffer as it was received via inline transmission method. Buffer referred by a 'sent' argument can be safely finalised afterwards.

Definition at line 663 of file at.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ m0_rpc_at_rep_get()

M0_INTERNAL int m0_rpc_at_rep_get ( struct m0_rpc_at_buf sent,
struct m0_rpc_at_buf rcvd,
struct m0_buf out 
)

Initialises user-supplied buffer with AT buffer data received as reply.

Intended to be called on client side.

See also
m0_rpc_at_rep_is_bulk

Definition at line 606 of file at.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ m0_rpc_at_rep_is_bulk()

M0_INTERNAL bool m0_rpc_at_rep_is_bulk ( const struct m0_rpc_at_buf rcvd,
uint64_t *  len 
)

Checks whether inbulk was used by server to send AT buffer.

Allows client to discover actual buffer length, stored on server. Also, return value 'true' indicates that server requested inbulk method for buffer transmission.

Definition at line 651 of file at.c.

Here is the caller graph for this function:

◆ m0_rpc_at_reply()

M0_INTERNAL int m0_rpc_at_reply ( struct m0_rpc_at_buf in,
struct m0_rpc_at_buf out,
struct m0_buf repbuf,
struct m0_fom fom,
int  next_phase 
)

Adds user-supplied buffer to AT buffer embedded in server reply.

Fom unconditionally moves to 'next_phase'. Once buffer is processed (sent via inbulk or embedded in reply FOP), fom tick function is called.

Returns value from m0_fom_phase_outcome.

See also
m0_rpc_at_reply_rc()

Definition at line 528 of file at.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ m0_rpc_at_reply_rc()

M0_INTERNAL int m0_rpc_at_reply_rc ( struct m0_rpc_at_buf out)

Returns execution result of m0_rpc_at_reply().

See also
m0_rpc_at_reply()

Definition at line 583 of file at.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ M0_TL_DECLARE()

M0_TL_DECLARE ( rpcbulk  ,
M0_INTERNAL  ,
struct m0_rpc_bulk_buf   
)

◆ M0_TL_DESCR_DECLARE()

M0_TL_DESCR_DECLARE ( rpcbulk  ,
M0_EXTERN   
)

◆ M0_XCA_DOMAIN()

struct m0_rpc_at_bulk_rep M0_XCA_DOMAIN ( rpc  )

◆ rpc_at_bulk()

static struct rpc_at_bulk* rpc_at_bulk ( const struct m0_rpc_at_buf ab)
static

Definition at line 75 of file at.c.

Here is the caller graph for this function:

◆ rpc_at_bulk_crecv()

static int rpc_at_bulk_crecv ( struct m0_rpc_at_buf ab,
uint32_t  len 
)
static

Definition at line 288 of file at.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_at_bulk_csend()

static int rpc_at_bulk_csend ( struct m0_rpc_at_buf ab,
const struct m0_buf buf 
)
static

Definition at line 202 of file at.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_at_bulk_cutoff()

static m0_bcount_t rpc_at_bulk_cutoff ( const struct m0_rpc_conn conn)
static

Definition at line 80 of file at.c.

Here is the caller graph for this function:

◆ rpc_at_bulk_fini()

static void rpc_at_bulk_fini ( struct rpc_at_bulk atbulk)
static

Definition at line 183 of file at.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_at_bulk_init()

static int rpc_at_bulk_init ( struct m0_rpc_at_buf ab,
const struct m0_rpc_conn conn 
)
static

Definition at line 132 of file at.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_at_bulk_nb_alloc()

static int rpc_at_bulk_nb_alloc ( struct m0_rpc_at_buf ab,
uint64_t  size 
)
static

Definition at line 108 of file at.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_at_bulk_nb_free()

static void rpc_at_bulk_nb_free ( struct rpc_at_bulk atbulk)
static

Definition at line 127 of file at.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_at_bulk_ndom()

static struct m0_net_domain* rpc_at_bulk_ndom ( const struct rpc_at_bulk atbulk)
static

Definition at line 85 of file at.c.

Here is the caller graph for this function:

◆ rpc_at_bulk_qtype()

static enum m0_net_queue_type rpc_at_bulk_qtype ( struct m0_rpc_bulk rbulk)
static

Definition at line 165 of file at.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_at_bulk_segs_nr()

static uint64_t rpc_at_bulk_segs_nr ( const struct rpc_at_bulk atbulk,
m0_bcount_t  data_size,
m0_bcount_t seg_size 
)
static

Definition at line 95 of file at.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_at_bulk_srecv()

static int rpc_at_bulk_srecv ( struct m0_rpc_at_buf ab,
struct m0_fom fom 
)
static

Definition at line 235 of file at.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_at_bulk_srecv_rc()

static int rpc_at_bulk_srecv_rc ( const struct m0_rpc_at_buf ab,
struct m0_buf buf 
)
static

Definition at line 271 of file at.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_at_bulk_ssend()

static int rpc_at_bulk_ssend ( struct m0_rpc_at_buf in,
struct m0_rpc_at_buf out,
struct m0_buf buf,
struct m0_fom fom 
)
static

Definition at line 343 of file at.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_at_bulk_store_del()

static void rpc_at_bulk_store_del ( struct m0_rpc_bulk rbulk)
static

Definition at line 153 of file at.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_at_ssend_ast_cb()

static void rpc_at_ssend_ast_cb ( struct m0_sm_group grp,
struct m0_sm_ast ast 
)
static

Definition at line 315 of file at.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_at_ssend_complete_cb()

static bool rpc_at_ssend_complete_cb ( struct m0_clink clink)
static

Definition at line 330 of file at.c.

Here is the call graph for this function:
Here is the caller graph for this function: