/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef __RPC_CLNT_H #define __RPC_CLNT_H #include "stack.h" #include "rpc-transport.h" #include "timer.h" #include "xdr-common.h" typedef enum { RPC_CLNT_CONNECT, RPC_CLNT_DISCONNECT, RPC_CLNT_MSG } rpc_clnt_event_t; #define SFRAME_GET_PROGNUM(sframe) (sframe->rpcreq->prog->prognum) #define SFRAME_GET_PROGVER(sframe) (sframe->rpcreq->prog->progver) #define SFRAME_GET_PROCNUM(sframe) (sframe->rpcreq->procnum) struct xptr_clnt; struct rpc_req; struct rpc_clnt; struct rpc_clnt_config; struct rpc_clnt_program; typedef int (*rpc_clnt_notify_t) (struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t fn, void *data); typedef int (*fop_cbk_fn_t) (struct rpc_req *req, struct iovec *iov, int count, void *myframe); typedef int (*clnt_fn_t) (call_frame_t *fr, xlator_t *xl, void *args); struct saved_frame { union { struct list_head list; struct { struct saved_frame *frame_next; struct saved_frame *frame_prev; }; }; void *capital_this; void *frame; struct timeval saved_at; struct rpc_req *rpcreq; rpc_transport_rsp_t rsp; }; struct saved_frames { int64_t count; struct saved_frame sf; struct saved_frame lk_sf; }; /* Initialized by procnum */ typedef struct rpc_clnt_procedure { char *procname; clnt_fn_t fn; } rpc_clnt_procedure_t; typedef struct rpc_clnt_program { char *progname; int prognum; int progver; rpc_clnt_procedure_t *proctable; char **procnames; int numproc; } rpc_clnt_prog_t; typedef int (*rpcclnt_cb_fn) (void *data); /* The descriptor for each procedure/actor that runs * over the RPC service. */ typedef struct rpcclnt_actor_desc { char procname[32]; int procnum; rpcclnt_cb_fn actor; } rpcclnt_cb_actor_t; /* Describes a program and its version along with the function pointers * required to handle the procedures/actors of each program/version. * Never changed ever by any thread so no need for a lock. */ typedef struct rpcclnt_cb_program { char progname[32]; int prognum; int progver; rpcclnt_cb_actor_t *actors; /* All procedure handlers */ int numactors; /* Num actors in actor array */ /* Program specific state handed to actors */ void *private; /* list member to link to list of registered services with rpc_clnt */ struct list_head program; } rpcclnt_cb_program_t; typedef struct rpc_auth_data { int flavour; int datalen; char authdata[GF_MAX_AUTH_BYTES]; } rpc_auth_data_t; struct rpc_clnt_config { int rpc_timeout; int remote_port; char * remote_host; }; #define rpc_auth_flavour(au) ((au).flavour) struct rpc_clnt_connection { pthread_mutex_t lock; rpc_transport_t *trans; struct rpc_clnt_config config; gf_timer_t *reconnect; gf_timer_t *timer; gf_timer_t *ping_timer; struct rpc_clnt *rpc_clnt; char connected; struct saved_frames *saved_frames; int32_t frame_timeout; struct timeval last_sent; struct timeval last_received; int32_t ping_started; }; typedef struct rpc_clnt_connection rpc_clnt_connection_t; struct rpc_req { rpc_clnt_connection_t *conn; uint32_t xid; struct iovec req[2]; int reqcnt; struct iobref *req_iobref; struct iovec rsp[2]; int rspcnt; struct iobref *rsp_iobref; int rpc_status; rpc_auth_data_t verf; rpc_clnt_prog_t *prog; int procnum; fop_cbk_fn_t cbkfn; void *conn_private; }; typedef struct rpc_clnt { pthread_mutex_t lock; rpc_clnt_notify_t notifyfn; rpc_clnt_connection_t conn; void *mydata; uint64_t xid; /* list of cb programs registered with rpc-clnt */ struct list_head programs; /* Memory pool for rpc_req_t */ struct mem_pool *reqpool; struct mem_pool *saved_frames_pool; glusterfs_ctx_t *ctx; int refcount; int auth_null; char disabled; } rpc_clnt_t; struct rpc_clnt *rpc_clnt_new (dict_t *options, glusterfs_ctx_t *ctx, char *name, uint32_t reqpool_size); int rpc_clnt_start (struct rpc_clnt *rpc); int rpc_clnt_register_notify (struct rpc_clnt *rpc, rpc_clnt_notify_t fn, void *mydata); /* Some preconditions related to vectors holding responses. * @rsphdr: should contain pointer to buffer which can hold response header * and length of the program header. In case of procedures whose * respnose size is not bounded (eg., glusterfs lookup), the length * should be equal to size of buffer. * @rsp_payload: should contain pointer and length of the bu * * 1. Both @rsp_hdr and @rsp_payload are optional. * 2. The user of rpc_clnt_submit, if wants response hdr and payload in its own * buffers, then it has to populate @rsphdr and @rsp_payload. * 3. when @rsp_payload is not NULL, @rsphdr should * also be filled with pointer to buffer to hold header and length * of the header. */ int rpc_clnt_submit (struct rpc_clnt *rpc, rpc_clnt_prog_t *prog, int procnum, fop_cbk_fn_t cbkfn, struct iovec *proghdr, int proghdrcount, struct iovec *progpayload, int progpayloadcount, struct iobref *iobref, void *frame, struct iovec *rsphdr, int rsphdr_count, struct iovec *rsp_payload, int rsp_payload_count, struct iobref *rsp_iobref); struct rpc_clnt * rpc_clnt_ref (struct rpc_clnt *rpc); struct rpc_clnt * rpc_clnt_unref (struct rpc_clnt *rpc); int rpc_clnt_connection_cleanup (rpc_clnt_connection_t *conn); void rpc_clnt_set_connected (rpc_clnt_connection_t *conn); void rpc_clnt_unset_connected (rpc_clnt_connection_t *conn); void rpc_clnt_reconnect (void *trans_ptr); void rpc_clnt_reconfig (struct rpc_clnt *rpc, struct rpc_clnt_config *config); /* All users of RPC services should use this API to register their * procedure handlers. */ int rpcclnt_cbk_program_register (struct rpc_clnt *svc, rpcclnt_cb_program_t *program); int rpc_clnt_transport_unix_options_build (dict_t **options, char *filepath, int frame_timeout); void rpc_clnt_disable (struct rpc_clnt *rpc); #endif /* !_RPC_CLNT_H */