diff options
Diffstat (limited to 'rpc/rpc-lib/src/rpcsvc.h')
-rw-r--r-- | rpc/rpc-lib/src/rpcsvc.h | 734 |
1 files changed, 370 insertions, 364 deletions
diff --git a/rpc/rpc-lib/src/rpcsvc.h b/rpc/rpc-lib/src/rpcsvc.h index c6efa4f536..ebb836fba3 100644 --- a/rpc/rpc-lib/src/rpcsvc.h +++ b/rpc/rpc-lib/src/rpcsvc.h @@ -33,29 +33,30 @@ #define MAX_IOVEC 16 #endif -#define RPCSVC_DEFAULT_OUTSTANDING_RPC_LIMIT 64 /* Default for protocol/server */ +#define RPCSVC_DEFAULT_OUTSTANDING_RPC_LIMIT \ + 64 /* Default for protocol/server */ #define RPCSVC_DEF_NFS_OUTSTANDING_RPC_LIMIT 16 /* Default for nfs/server */ #define RPCSVC_MAX_OUTSTANDING_RPC_LIMIT 65536 #define RPCSVC_MIN_OUTSTANDING_RPC_LIMIT 0 /* No limit i.e. Unlimited */ -#define GF_RPCSVC "rpc-service" +#define GF_RPCSVC "rpc-service" #define RPCSVC_THREAD_STACK_SIZE ((size_t)(1024 * GF_UNIT_KB)) -#define RPCSVC_FRAGHDR_SIZE 4 /* 4-byte RPC fragment header size */ -#define RPCSVC_DEFAULT_LISTEN_PORT GF_DEFAULT_BASE_PORT -#define RPCSVC_DEFAULT_MEMFACTOR 8 -#define RPCSVC_EVENTPOOL_SIZE_MULT 1024 -#define RPCSVC_POOLCOUNT_MULT 64 -#define RPCSVC_CONN_READ (128 * GF_UNIT_KB) -#define RPCSVC_PAGE_SIZE (128 * GF_UNIT_KB) -#define RPC_ROOT_UID 0 -#define RPC_ROOT_GID 0 -#define RPC_NOBODY_UID 65534 -#define RPC_NOBODY_GID 65534 +#define RPCSVC_FRAGHDR_SIZE 4 /* 4-byte RPC fragment header size */ +#define RPCSVC_DEFAULT_LISTEN_PORT GF_DEFAULT_BASE_PORT +#define RPCSVC_DEFAULT_MEMFACTOR 8 +#define RPCSVC_EVENTPOOL_SIZE_MULT 1024 +#define RPCSVC_POOLCOUNT_MULT 64 +#define RPCSVC_CONN_READ (128 * GF_UNIT_KB) +#define RPCSVC_PAGE_SIZE (128 * GF_UNIT_KB) +#define RPC_ROOT_UID 0 +#define RPC_ROOT_GID 0 +#define RPC_NOBODY_UID 65534 +#define RPC_NOBODY_GID 65534 /* RPC Record States */ -#define RPCSVC_READ_FRAGHDR 1 -#define RPCSVC_READ_FRAG 2 +#define RPCSVC_READ_FRAGHDR 1 +#define RPCSVC_READ_FRAG 2 /* The size in bytes, if crossed by a fragment will be handed over to the * vectored actor so that it can allocate its buffers the way it wants. * In our RPC layer, we assume that vectored RPC requests/records are never @@ -63,21 +64,28 @@ * whether the record should be handled in RPC layer completely or handed to * the vectored handler. */ -#define RPCSVC_VECTORED_FRAGSZ 4096 -#define RPCSVC_VECTOR_READCRED 1003 -#define RPCSVC_VECTOR_READVERFSZ 1004 -#define RPCSVC_VECTOR_READVERF 1005 -#define RPCSVC_VECTOR_IGNORE 1006 -#define RPCSVC_VECTOR_READVEC 1007 -#define RPCSVC_VECTOR_READPROCHDR 1008 - -#define rpcsvc_record_vectored_baremsg(rs) (((rs)->state == RPCSVC_READ_FRAG) && (rs)->vecstate == 0) -#define rpcsvc_record_vectored_cred(rs) ((rs)->vecstate == RPCSVC_VECTOR_READCRED) -#define rpcsvc_record_vectored_verfsz(rs) ((rs)->vecstate == RPCSVC_VECTOR_READVERFSZ) -#define rpcsvc_record_vectored_verfread(rs) ((rs)->vecstate == RPCSVC_VECTOR_READVERF) -#define rpcsvc_record_vectored_ignore(rs) ((rs)->vecstate == RPCSVC_VECTOR_IGNORE) -#define rpcsvc_record_vectored_readvec(rs) ((rs)->vecstate == RPCSVC_VECTOR_READVEC) -#define rpcsvc_record_vectored_readprochdr(rs) ((rs)->vecstate == RPCSVC_VECTOR_READPROCHDR) +#define RPCSVC_VECTORED_FRAGSZ 4096 +#define RPCSVC_VECTOR_READCRED 1003 +#define RPCSVC_VECTOR_READVERFSZ 1004 +#define RPCSVC_VECTOR_READVERF 1005 +#define RPCSVC_VECTOR_IGNORE 1006 +#define RPCSVC_VECTOR_READVEC 1007 +#define RPCSVC_VECTOR_READPROCHDR 1008 + +#define rpcsvc_record_vectored_baremsg(rs) \ + (((rs)->state == RPCSVC_READ_FRAG) && (rs)->vecstate == 0) +#define rpcsvc_record_vectored_cred(rs) \ + ((rs)->vecstate == RPCSVC_VECTOR_READCRED) +#define rpcsvc_record_vectored_verfsz(rs) \ + ((rs)->vecstate == RPCSVC_VECTOR_READVERFSZ) +#define rpcsvc_record_vectored_verfread(rs) \ + ((rs)->vecstate == RPCSVC_VECTOR_READVERF) +#define rpcsvc_record_vectored_ignore(rs) \ + ((rs)->vecstate == RPCSVC_VECTOR_IGNORE) +#define rpcsvc_record_vectored_readvec(rs) \ + ((rs)->vecstate == RPCSVC_VECTOR_READVEC) +#define rpcsvc_record_vectored_readprochdr(rs) \ + ((rs)->vecstate == RPCSVC_VECTOR_READPROCHDR) #define rpcsvc_record_vectored(rs) ((rs)->fragsize > RPCSVC_VECTORED_FRAGSZ) /* Includes bytes up to and including the credential length field. The credlen * will be followed by @credlen bytes of credential data which will have to be @@ -85,60 +93,58 @@ * verifier which will also have to be read separately including the 8 bytes of * verf flavour and verflen. */ -#define RPCSVC_BARERPC_MSGSZ 32 -#define rpcsvc_record_readfraghdr(rs) ((rs)->state == RPCSVC_READ_FRAGHDR) -#define rpcsvc_record_readfrag(rs) ((rs)->state == RPCSVC_READ_FRAG) +#define RPCSVC_BARERPC_MSGSZ 32 +#define rpcsvc_record_readfraghdr(rs) ((rs)->state == RPCSVC_READ_FRAGHDR) +#define rpcsvc_record_readfrag(rs) ((rs)->state == RPCSVC_READ_FRAG) -#define RPCSVC_LOWVERS 2 +#define RPCSVC_LOWVERS 2 #define RPCSVC_HIGHVERS 2 - #if 0 #error "defined in /usr/include/rpc/auth.h" -#define AUTH_NONE 0 /* no authentication */ -#define AUTH_NULL 0 /* backward compatibility */ -#define AUTH_SYS 1 /* unix style (uid, gids) */ -#define AUTH_UNIX AUTH_SYS -#define AUTH_SHORT 2 /* short hand unix style */ -#define AUTH_DES 3 /* des style (encrypted timestamps) */ -#define AUTH_DH AUTH_DES /* Diffie-Hellman (this is DES) */ -#define AUTH_KERB 4 /* kerberos style */ -#endif /* */ +#define AUTH_NONE 0 /* no authentication */ +#define AUTH_NULL 0 /* backward compatibility */ +#define AUTH_SYS 1 /* unix style (uid, gids) */ +#define AUTH_UNIX AUTH_SYS +#define AUTH_SHORT 2 /* short hand unix style */ +#define AUTH_DES 3 /* des style (encrypted timestamps) */ +#define AUTH_DH AUTH_DES /* Diffie-Hellman (this is DES) */ +#define AUTH_KERB 4 /* kerberos style */ +#endif /* */ typedef struct rpcsvc_program rpcsvc_program_t; struct rpcsvc_notify_wrapper { - struct list_head list; - void *data; - rpcsvc_notify_t notify; + struct list_head list; + void *data; + rpcsvc_notify_t notify; }; typedef struct rpcsvc_notify_wrapper rpcsvc_notify_wrapper_t; - typedef struct rpcsvc_request rpcsvc_request_t; typedef struct { - rpc_transport_t *trans; - rpcsvc_t *svc; - /* FIXME: remove address from this structure. Instead use get_myaddr - * interface implemented by individual transports. - */ - struct sockaddr_storage sa; - struct list_head list; + rpc_transport_t *trans; + rpcsvc_t *svc; + /* FIXME: remove address from this structure. Instead use get_myaddr + * interface implemented by individual transports. + */ + struct sockaddr_storage sa; + struct list_head list; } rpcsvc_listener_t; struct rpcsvc_config { - int max_block_size; + int max_block_size; }; typedef struct rpcsvc_auth_data { - int flavour; - int datalen; - char authdata[GF_MAX_AUTH_BYTES]; + int flavour; + int datalen; + char authdata[GF_MAX_AUTH_BYTES]; } rpcsvc_auth_data_t; -#define rpcsvc_auth_flavour(au) ((au).flavour) +#define rpcsvc_auth_flavour(au) ((au).flavour) typedef struct drc_client drc_client_t; typedef struct drc_cached_op drc_cached_op_t; @@ -148,163 +154,161 @@ typedef struct drc_cached_op drc_cached_op_t; * transmitted. * */ struct rpcsvc_request { - /* connection over which this request came. */ - rpc_transport_t *trans; - - rpcsvc_t *svc; - - rpcsvc_program_t *prog; + /* connection over which this request came. */ + rpc_transport_t *trans; - /* The identifier for the call from client. - * Needed to pair the reply with the call. - */ - uint32_t xid; + rpcsvc_t *svc; - int prognum; + rpcsvc_program_t *prog; - int progver; + /* The identifier for the call from client. + * Needed to pair the reply with the call. + */ + uint32_t xid; - int procnum; + int prognum; - int type; + int progver; - /* Uid and gid filled by the rpc-auth module during the authentication - * phase. - */ - uid_t uid; - gid_t gid; - pid_t pid; + int procnum; - gf_lkowner_t lk_owner; - uint64_t gfs_id; + int type; - /* Might want to move this to AUTH_UNIX specific state since this array - * is not available for every authentication scheme. - */ - gid_t *auxgids; - gid_t auxgidsmall[SMALL_GROUP_COUNT]; - gid_t *auxgidlarge; - int auxgidcount; + /* Uid and gid filled by the rpc-auth module during the authentication + * phase. + */ + uid_t uid; + gid_t gid; + pid_t pid; + gf_lkowner_t lk_owner; + uint64_t gfs_id; - /* The RPC message payload, contains the data required - * by the program actors. This is the buffer that will need to - * be de-xdred by the actor. - */ - struct iovec msg[MAX_IOVEC]; - int count; + /* Might want to move this to AUTH_UNIX specific state since this array + * is not available for every authentication scheme. + */ + gid_t *auxgids; + gid_t auxgidsmall[SMALL_GROUP_COUNT]; + gid_t *auxgidlarge; + int auxgidcount; - struct iobref *iobref; + /* The RPC message payload, contains the data required + * by the program actors. This is the buffer that will need to + * be de-xdred by the actor. + */ + struct iovec msg[MAX_IOVEC]; + int count; - /* Status of the RPC call, whether it was accepted or denied. */ - int rpc_status; + struct iobref *iobref; - /* In case, the call was denied, the RPC error is stored here - * till the reply is sent. - */ - int rpc_err; + /* Status of the RPC call, whether it was accepted or denied. */ + int rpc_status; - /* In case the failure happened because of an authentication problem - * , this value needs to be assigned the correct auth error number. - */ - int auth_err; + /* In case, the call was denied, the RPC error is stored here + * till the reply is sent. + */ + int rpc_err; - /* There can be cases of RPC requests where the reply needs to - * be built from multiple sources. E.g. where even the NFS reply - * can contain a payload, as in the NFSv3 read reply. Here the RPC header - * ,NFS header and the read data are brought together separately from - * different buffers, so we need to stage the buffers temporarily here - * before all of them get added to the connection's transmission list. - */ - struct list_head txlist; + /* In case the failure happened because of an authentication problem + * , this value needs to be assigned the correct auth error number. + */ + int auth_err; - /* While the reply record is being built, this variable keeps track - * of how many bytes have been added to the record. - */ - size_t payloadsize; + /* There can be cases of RPC requests where the reply needs to + * be built from multiple sources. E.g. where even the NFS reply + * can contain a payload, as in the NFSv3 read reply. Here the RPC header + * ,NFS header and the read data are brought together separately from + * different buffers, so we need to stage the buffers temporarily here + * before all of them get added to the connection's transmission list. + */ + struct list_head txlist; - /* The credentials extracted from the rpc request */ - rpcsvc_auth_data_t cred; + /* While the reply record is being built, this variable keeps track + * of how many bytes have been added to the record. + */ + size_t payloadsize; - /* The verified extracted from the rpc request. In request side - * processing this contains the verifier sent by the client, on reply - * side processing, it is filled with the verified that will be - * sent to the client. - */ - rpcsvc_auth_data_t verf; + /* The credentials extracted from the rpc request */ + rpcsvc_auth_data_t cred; - /* Execute this request's actor function in ownthread of program?*/ - gf_boolean_t ownthread; + /* The verified extracted from the rpc request. In request side + * processing this contains the verifier sent by the client, on reply + * side processing, it is filled with the verified that will be + * sent to the client. + */ + rpcsvc_auth_data_t verf; - gf_boolean_t synctask; - /* Container for a RPC program wanting to store a temp - * request-specific item. - */ - void *private; + /* Execute this request's actor function in ownthread of program?*/ + gf_boolean_t ownthread; - /* Container for transport to store request-specific item */ - void *trans_private; + gf_boolean_t synctask; + /* Container for a RPC program wanting to store a temp + * request-specific item. + */ + void *private; - /* pointer to cached reply for use in DRC */ - drc_cached_op_t *reply; + /* Container for transport to store request-specific item */ + void *trans_private; - /* request queue in rpcsvc */ - struct list_head request_list; + /* pointer to cached reply for use in DRC */ + drc_cached_op_t *reply; - /* Things passed to rpc layer from client */ + /* request queue in rpcsvc */ + struct list_head request_list; - /* @flags: Can be used for binary data passed in xdata to be - passed here instead */ - unsigned int flags; - - /* ctime: origin of time on the client side, ideally this is - the one we should consider for time */ - struct timespec ctime; + /* Things passed to rpc layer from client */ + + /* @flags: Can be used for binary data passed in xdata to be + passed here instead */ + unsigned int flags; + + /* ctime: origin of time on the client side, ideally this is + the one we should consider for time */ + struct timespec ctime; }; #define rpcsvc_request_program(req) ((rpcsvc_program_t *)((req)->prog)) #define rpcsvc_request_procnum(req) (((req)->procnum)) -#define rpcsvc_request_program_private(req) (((rpcsvc_program_t *)((req)->prog))->private) -#define rpcsvc_request_accepted(req) ((req)->rpc_status == MSG_ACCEPTED) +#define rpcsvc_request_program_private(req) \ + (((rpcsvc_program_t *)((req)->prog))->private) +#define rpcsvc_request_accepted(req) ((req)->rpc_status == MSG_ACCEPTED) #define rpcsvc_request_accepted_success(req) ((req)->rpc_err == SUCCESS) #define rpcsvc_request_prog_minauth(req) (rpcsvc_request_program(req)->min_auth) #define rpcsvc_request_cred_flavour(req) (rpcsvc_auth_flavour(req->cred)) #define rpcsvc_request_verf_flavour(req) (rpcsvc_auth_flavour(req->verf)) -#define rpcsvc_request_service(req) ((req)->svc) -#define rpcsvc_request_uid(req) ((req)->uid) -#define rpcsvc_request_gid(req) ((req)->gid) -#define rpcsvc_request_private(req) ((req)->private) -#define rpcsvc_request_xid(req) ((req)->xid) -#define rpcsvc_request_set_private(req,prv) (req)->private = (void *)(prv) -#define rpcsvc_request_iobref_ref(req) (iobref_ref ((req)->iobref)) -#define rpcsvc_request_record_ref(req) (iobuf_ref ((req)->recordiob)) -#define rpcsvc_request_record_unref(req) (iobuf_unref ((req)->recordiob)) -#define rpcsvc_request_record_iob(req) ((req)->recordiob) -#define rpcsvc_request_set_vecstate(req, state) ((req)->vecstate = state) +#define rpcsvc_request_service(req) ((req)->svc) +#define rpcsvc_request_uid(req) ((req)->uid) +#define rpcsvc_request_gid(req) ((req)->gid) +#define rpcsvc_request_private(req) ((req)->private) +#define rpcsvc_request_xid(req) ((req)->xid) +#define rpcsvc_request_set_private(req, prv) (req)->private = (void *)(prv) +#define rpcsvc_request_iobref_ref(req) (iobref_ref((req)->iobref)) +#define rpcsvc_request_record_ref(req) (iobuf_ref((req)->recordiob)) +#define rpcsvc_request_record_unref(req) (iobuf_unref((req)->recordiob)) +#define rpcsvc_request_record_iob(req) ((req)->recordiob) +#define rpcsvc_request_set_vecstate(req, state) ((req)->vecstate = state) #define rpcsvc_request_vecstate(req) ((req)->vecstate) #define rpcsvc_request_transport(req) ((req)->trans) #define rpcsvc_request_transport_ref(req) (rpc_transport_ref((req)->trans)) -#define RPC_AUTH_ROOT_SQUASH(req) \ - do { \ - int gidcount = 0; \ - if (req->svc->root_squash) { \ - if (req->uid == RPC_ROOT_UID) \ - req->uid = req->svc->anonuid; \ - if (req->gid == RPC_ROOT_GID) \ - req->gid = req->svc->anongid; \ - \ - for (gidcount = 0; gidcount < req->auxgidcount; \ - ++gidcount) { \ - if (!req->auxgids[gidcount]) \ - req->auxgids[gidcount] = \ - req->svc->anongid; \ - } \ - } \ - } while (0); - -#define RPCSVC_ACTOR_SUCCESS 0 -#define RPCSVC_ACTOR_ERROR (-1) -#define RPCSVC_ACTOR_IGNORE (-2) +#define RPC_AUTH_ROOT_SQUASH(req) \ + do { \ + int gidcount = 0; \ + if (req->svc->root_squash) { \ + if (req->uid == RPC_ROOT_UID) \ + req->uid = req->svc->anonuid; \ + if (req->gid == RPC_ROOT_GID) \ + req->gid = req->svc->anongid; \ + \ + for (gidcount = 0; gidcount < req->auxgidcount; ++gidcount) { \ + if (!req->auxgids[gidcount]) \ + req->auxgids[gidcount] = req->svc->anongid; \ + } \ + } \ + } while (0); + +#define RPCSVC_ACTOR_SUCCESS 0 +#define RPCSVC_ACTOR_ERROR (-1) +#define RPCSVC_ACTOR_IGNORE (-2) /* Functor for every type of protocol actor * must be defined like this. @@ -318,44 +322,44 @@ struct rpcsvc_request { * should return RPCSVC_ACTOR_ERROR. * */ -typedef int (*rpcsvc_actor) (rpcsvc_request_t *req); -typedef int (*rpcsvc_vector_sizer) (int state, ssize_t *readsize, - char *base_addr, char *curr_addr); +typedef int (*rpcsvc_actor)(rpcsvc_request_t *req); +typedef int (*rpcsvc_vector_sizer)(int state, ssize_t *readsize, + char *base_addr, char *curr_addr); /* Every protocol actor will also need to specify the function the RPC layer * will use to serialize or encode the message into XDR format just before * transmitting on the connection. */ -typedef void *(*rpcsvc_encode_reply) (void *msg); +typedef void *(*rpcsvc_encode_reply)(void *msg); /* Once the reply has been transmitted, the message will have to be de-allocated * , so every actor will need to provide a function that deallocates the message * it had allocated as a response. */ -typedef void (*rpcsvc_deallocate_reply) (void *msg); +typedef void (*rpcsvc_deallocate_reply)(void *msg); -#define RPCSVC_NAME_MAX 32 +#define RPCSVC_NAME_MAX 32 /* The descriptor for each procedure/actor that runs * over the RPC service. */ typedef struct rpcsvc_actor_desc { - char procname[RPCSVC_NAME_MAX]; - int procnum; - rpcsvc_actor actor; - - /* Handler for cases where the RPC requests fragments are large enough - * to benefit from being decoded into aligned memory addresses. While - * decoding the request in a non-vectored manner, due to the nature of - * the XDR scheme, RPC cannot guarantee memory aligned addresses for - * the resulting message-specific structures. Allowing a specialized - * handler for letting the RPC program read the data from the network - * directly into its aligned buffers. - */ - rpcsvc_vector_sizer vector_sizer; - - /* Can actor be ran on behalf an unprivileged requestor? */ - gf_boolean_t unprivileged; - drc_op_type_t op_type; + char procname[RPCSVC_NAME_MAX]; + int procnum; + rpcsvc_actor actor; + + /* Handler for cases where the RPC requests fragments are large enough + * to benefit from being decoded into aligned memory addresses. While + * decoding the request in a non-vectored manner, due to the nature of + * the XDR scheme, RPC cannot guarantee memory aligned addresses for + * the resulting message-specific structures. Allowing a specialized + * handler for letting the RPC program read the data from the network + * directly into its aligned buffers. + */ + rpcsvc_vector_sizer vector_sizer; + + /* Can actor be ran on behalf an unprivileged requestor? */ + gf_boolean_t unprivileged; + drc_op_type_t op_type; } rpcsvc_actor_t; /* Describes a program and its version along with the function pointers @@ -363,87 +367,86 @@ typedef struct rpcsvc_actor_desc { * Never changed ever by any thread so no need for a lock. */ struct rpcsvc_program { - char progname[RPCSVC_NAME_MAX]; - int prognum; - int progver; - /* FIXME */ - dict_t *options; /* An opaque dictionary - * populated by the program - * (probably from xl->options) - * which contain enough - * information for transport to - * initialize. As a part of - * cleanup, the members of - * options which are of interest - * to transport should be put - * into a structure for better - * readability and structure - * should replace options member - * here. - */ - uint16_t progport; /* Registered with portmap */ + char progname[RPCSVC_NAME_MAX]; + int prognum; + int progver; + /* FIXME */ + dict_t *options; /* An opaque dictionary + * populated by the program + * (probably from xl->options) + * which contain enough + * information for transport to + * initialize. As a part of + * cleanup, the members of + * options which are of interest + * to transport should be put + * into a structure for better + * readability and structure + * should replace options member + * here. + */ + uint16_t progport; /* Registered with portmap */ #if 0 int progaddrfamily; /* AF_INET or AF_INET6 */ char *proghost; /* Bind host, can be NULL */ #endif - rpcsvc_actor_t *actors; /* All procedure handlers */ - int numactors; /* Num actors in actor array */ - int proghighvers; /* Highest ver for program - supported by the system. */ - int proglowvers; /* Lowest ver */ - - /* Program specific state handed to actors */ - void *private; - - - /* This upcall is provided by the program during registration. - * It is used to notify the program about events like connection being - * destroyed etc. The rpc program may take appropriate actions, for eg., - * in the case of connection being destroyed, it should cleanup its - * state stored in the connection. - */ - rpcsvc_notify_t notify; - - /* An integer that identifies the min auth strength that is required - * by this protocol, for eg. MOUNT3 needs AUTH_UNIX at least. - * See RFC 1813, Section 5.2.1. - */ - int min_auth; - - /* Execute actor function in program's own thread? This will reduce */ - /* the workload on poller threads */ - gf_boolean_t ownthread; - gf_boolean_t alive; - - gf_boolean_t synctask; - /* list member to link to list of registered services with rpcsvc */ - struct list_head program; - struct list_head request_queue; - pthread_mutex_t queue_lock; - pthread_cond_t queue_cond; - pthread_t thread; - int threadcount; - /* eventthreadcount is just a readonly copy of the actual value - * owned by the event sub-system - * It is used to control the scaling of rpcsvc_request_handler threads - */ - int eventthreadcount; + rpcsvc_actor_t *actors; /* All procedure handlers */ + int numactors; /* Num actors in actor array */ + int proghighvers; /* Highest ver for program + supported by the system. */ + int proglowvers; /* Lowest ver */ + + /* Program specific state handed to actors */ + void *private; + + /* This upcall is provided by the program during registration. + * It is used to notify the program about events like connection being + * destroyed etc. The rpc program may take appropriate actions, for eg., + * in the case of connection being destroyed, it should cleanup its + * state stored in the connection. + */ + rpcsvc_notify_t notify; + + /* An integer that identifies the min auth strength that is required + * by this protocol, for eg. MOUNT3 needs AUTH_UNIX at least. + * See RFC 1813, Section 5.2.1. + */ + int min_auth; + + /* Execute actor function in program's own thread? This will reduce */ + /* the workload on poller threads */ + gf_boolean_t ownthread; + gf_boolean_t alive; + + gf_boolean_t synctask; + /* list member to link to list of registered services with rpcsvc */ + struct list_head program; + struct list_head request_queue; + pthread_mutex_t queue_lock; + pthread_cond_t queue_cond; + pthread_t thread; + int threadcount; + /* eventthreadcount is just a readonly copy of the actual value + * owned by the event sub-system + * It is used to control the scaling of rpcsvc_request_handler threads + */ + int eventthreadcount; }; typedef struct rpcsvc_cbk_program { - char *progname; - int prognum; - int progver; + char *progname; + int prognum; + int progver; } rpcsvc_cbk_program_t; /* All users of RPC services should use this API to register their * procedure handlers. */ extern int -rpcsvc_program_register (rpcsvc_t *svc, rpcsvc_program_t *program, - gf_boolean_t add_to_head); +rpcsvc_program_register(rpcsvc_t *svc, rpcsvc_program_t *program, + gf_boolean_t add_to_head); extern int -rpcsvc_program_unregister (rpcsvc_t *svc, rpcsvc_program_t *program); +rpcsvc_program_unregister(rpcsvc_t *svc, rpcsvc_program_t *program); /* This will create and add a listener to listener pool. Programs can * use any of the listener in this pool. A single listener can be used by @@ -454,149 +457,150 @@ rpcsvc_program_unregister (rpcsvc_t *svc, rpcsvc_program_t *program); */ /* FIXME: can multiple programs registered on same port? */ extern int32_t -rpcsvc_create_listeners (rpcsvc_t *svc, dict_t *options, char *name); +rpcsvc_create_listeners(rpcsvc_t *svc, dict_t *options, char *name); void -rpcsvc_listener_destroy (rpcsvc_listener_t *listener); +rpcsvc_listener_destroy(rpcsvc_listener_t *listener); extern int -rpcsvc_program_register_portmap (rpcsvc_program_t *newprog, uint32_t port); +rpcsvc_program_register_portmap(rpcsvc_program_t *newprog, uint32_t port); #ifdef IPV6_DEFAULT extern int -rpcsvc_program_register_rpcbind6 (rpcsvc_program_t *newprog, uint32_t port); +rpcsvc_program_register_rpcbind6(rpcsvc_program_t *newprog, uint32_t port); extern int -rpcsvc_program_unregister_rpcbind6 (rpcsvc_program_t *newprog); +rpcsvc_program_unregister_rpcbind6(rpcsvc_program_t *newprog); #endif extern int -rpcsvc_program_unregister_portmap (rpcsvc_program_t *newprog); +rpcsvc_program_unregister_portmap(rpcsvc_program_t *newprog); extern int -rpcsvc_register_portmap_enabled (rpcsvc_t *svc); +rpcsvc_register_portmap_enabled(rpcsvc_t *svc); /* Inits the global RPC service data structures. * Called in main. */ extern rpcsvc_t * -rpcsvc_init (xlator_t *xl, glusterfs_ctx_t *ctx, dict_t *options, - uint32_t poolcount); +rpcsvc_init(xlator_t *xl, glusterfs_ctx_t *ctx, dict_t *options, + uint32_t poolcount); extern int -rpcsvc_reconfigure_options (rpcsvc_t *svc, dict_t *options); +rpcsvc_reconfigure_options(rpcsvc_t *svc, dict_t *options); int -rpcsvc_register_notify (rpcsvc_t *svc, rpcsvc_notify_t notify, void *mydata); +rpcsvc_register_notify(rpcsvc_t *svc, rpcsvc_notify_t notify, void *mydata); /* unregister a notification callback @notify with data @mydata from svc. * returns the number of notification callbacks unregistered. */ int -rpcsvc_unregister_notify (rpcsvc_t *svc, rpcsvc_notify_t notify, void *mydata); +rpcsvc_unregister_notify(rpcsvc_t *svc, rpcsvc_notify_t notify, void *mydata); int -rpcsvc_transport_submit (rpc_transport_t *trans, struct iovec *rpchdr, - int rpchdrcount, struct iovec *proghdr, - int proghdrcount, struct iovec *progpayload, - int progpayloadcount, struct iobref *iobref, - void *priv); +rpcsvc_transport_submit(rpc_transport_t *trans, struct iovec *rpchdr, + int rpchdrcount, struct iovec *proghdr, + int proghdrcount, struct iovec *progpayload, + int progpayloadcount, struct iobref *iobref, + void *priv); int -rpcsvc_submit_message (rpcsvc_request_t *req, struct iovec *proghdr, - int hdrcount, struct iovec *payload, int payloadcount, - struct iobref *iobref); +rpcsvc_submit_message(rpcsvc_request_t *req, struct iovec *proghdr, + int hdrcount, struct iovec *payload, int payloadcount, + struct iobref *iobref); int -rpcsvc_submit_generic (rpcsvc_request_t *req, struct iovec *proghdr, - int hdrcount, struct iovec *payload, int payloadcount, - struct iobref *iobref); +rpcsvc_submit_generic(rpcsvc_request_t *req, struct iovec *proghdr, + int hdrcount, struct iovec *payload, int payloadcount, + struct iobref *iobref); extern int -rpcsvc_error_reply (rpcsvc_request_t *req); +rpcsvc_error_reply(rpcsvc_request_t *req); -#define RPCSVC_PEER_STRLEN 1024 -#define RPCSVC_AUTH_ACCEPT 1 -#define RPCSVC_AUTH_REJECT 2 -#define RPCSVC_AUTH_DONTCARE 3 +#define RPCSVC_PEER_STRLEN 1024 +#define RPCSVC_AUTH_ACCEPT 1 +#define RPCSVC_AUTH_REJECT 2 +#define RPCSVC_AUTH_DONTCARE 3 extern int -rpcsvc_transport_peername (rpc_transport_t *trans, char *hostname, int hostlen); +rpcsvc_transport_peername(rpc_transport_t *trans, char *hostname, int hostlen); extern int -rpcsvc_transport_peeraddr (rpc_transport_t *trans, char *addrstr, int addrlen, - struct sockaddr_storage *returnsa, socklen_t sasize); +rpcsvc_transport_peeraddr(rpc_transport_t *trans, char *addrstr, int addrlen, + struct sockaddr_storage *returnsa, socklen_t sasize); extern int -rpcsvc_auth_check (rpcsvc_t *svc, char *volname, char *ipaddr); +rpcsvc_auth_check(rpcsvc_t *svc, char *volname, char *ipaddr); extern int -rpcsvc_transport_privport_check (rpcsvc_t *svc, char *volname, uint16_t port); - -#define rpcsvc_request_seterr(req, err) ((req)->rpc_err = (int)(err)) -#define rpcsvc_request_set_autherr(req, err) ((req)->auth_err = (int)(err)) +rpcsvc_transport_privport_check(rpcsvc_t *svc, char *volname, uint16_t port); -extern int rpcsvc_submit_vectors (rpcsvc_request_t *req); +#define rpcsvc_request_seterr(req, err) ((req)->rpc_err = (int)(err)) +#define rpcsvc_request_set_autherr(req, err) ((req)->auth_err = (int)(err)) -extern int rpcsvc_request_attach_vector (rpcsvc_request_t *req, - struct iovec msgvec, struct iobuf *iob, - struct iobref *ioref, int finalvector); +extern int +rpcsvc_submit_vectors(rpcsvc_request_t *req); +extern int +rpcsvc_request_attach_vector(rpcsvc_request_t *req, struct iovec msgvec, + struct iobuf *iob, struct iobref *ioref, + int finalvector); -typedef int (*auth_init_trans) (rpc_transport_t *trans, void *priv); -typedef int (*auth_init_request) (rpcsvc_request_t *req, void *priv); -typedef int (*auth_request_authenticate) (rpcsvc_request_t *req, void *priv); +typedef int (*auth_init_trans)(rpc_transport_t *trans, void *priv); +typedef int (*auth_init_request)(rpcsvc_request_t *req, void *priv); +typedef int (*auth_request_authenticate)(rpcsvc_request_t *req, void *priv); /* This structure needs to be registered by every authentication scheme. * Our authentication schemes are stored per connection because * each connection will end up using a different authentication scheme. */ typedef struct rpcsvc_auth_ops { - auth_init_trans transport_init; - auth_init_request request_init; - auth_request_authenticate authenticate; + auth_init_trans transport_init; + auth_init_request request_init; + auth_request_authenticate authenticate; } rpcsvc_auth_ops_t; typedef struct rpcsvc_auth_flavour_desc { - char authname[RPCSVC_NAME_MAX]; - int authnum; - rpcsvc_auth_ops_t *authops; - void *authprivate; + char authname[RPCSVC_NAME_MAX]; + int authnum; + rpcsvc_auth_ops_t *authops; + void *authprivate; } rpcsvc_auth_t; -typedef void * (*rpcsvc_auth_initer_t) (rpcsvc_t *svc, dict_t *options); +typedef void *(*rpcsvc_auth_initer_t)(rpcsvc_t *svc, dict_t *options); struct rpcsvc_auth_list { - struct list_head authlist; - rpcsvc_auth_initer_t init; - /* Should be the name with which we identify the auth scheme given - * in the volfile options. - * This should be different from the authname in rpc_auth_t - * in way that makes it easier to specify this scheme in the volfile. - * This is because the technical names of the schemes can be a bit - * arcane. - */ - char name[RPCSVC_NAME_MAX]; - rpcsvc_auth_t *auth; - int enable; + struct list_head authlist; + rpcsvc_auth_initer_t init; + /* Should be the name with which we identify the auth scheme given + * in the volfile options. + * This should be different from the authname in rpc_auth_t + * in way that makes it easier to specify this scheme in the volfile. + * This is because the technical names of the schemes can be a bit + * arcane. + */ + char name[RPCSVC_NAME_MAX]; + rpcsvc_auth_t *auth; + int enable; }; extern int -rpcsvc_auth_request_init (rpcsvc_request_t *req, struct rpc_msg *callmsg); +rpcsvc_auth_request_init(rpcsvc_request_t *req, struct rpc_msg *callmsg); extern int -rpcsvc_auth_init (rpcsvc_t *svc, dict_t *options); +rpcsvc_auth_init(rpcsvc_t *svc, dict_t *options); extern int -rpcsvc_auth_reconf (rpcsvc_t *svc, dict_t *options); +rpcsvc_auth_reconf(rpcsvc_t *svc, dict_t *options); extern int -rpcsvc_auth_transport_init (rpc_transport_t *xprt); +rpcsvc_auth_transport_init(rpc_transport_t *xprt); extern int -rpcsvc_authenticate (rpcsvc_request_t *req); +rpcsvc_authenticate(rpcsvc_request_t *req); extern int -rpcsvc_auth_array (rpcsvc_t *svc, char *volname, int *autharr, int arrlen); +rpcsvc_auth_array(rpcsvc_t *svc, char *volname, int *autharr, int arrlen); /* If the request has been sent using AUTH_UNIX, this function returns the * auxiliary gids as an array, otherwise, it returns NULL. @@ -604,51 +608,53 @@ rpcsvc_auth_array (rpcsvc_t *svc, char *volname, int *autharr, int arrlen); * authentication code even further to support mode auth schemes. */ extern gid_t * -rpcsvc_auth_unix_auxgids (rpcsvc_request_t *req, int *arrlen); +rpcsvc_auth_unix_auxgids(rpcsvc_request_t *req, int *arrlen); extern char * -rpcsvc_volume_allowed (dict_t *options, char *volname); +rpcsvc_volume_allowed(dict_t *options, char *volname); -int rpcsvc_request_submit (rpcsvc_t *rpc, rpc_transport_t *trans, - rpcsvc_cbk_program_t *prog, int procnum, - void *req, glusterfs_ctx_t *ctx, - xdrproc_t xdrproc); +int +rpcsvc_request_submit(rpcsvc_t *rpc, rpc_transport_t *trans, + rpcsvc_cbk_program_t *prog, int procnum, void *req, + glusterfs_ctx_t *ctx, xdrproc_t xdrproc); -int rpcsvc_callback_submit (rpcsvc_t *rpc, rpc_transport_t *trans, - rpcsvc_cbk_program_t *prog, int procnum, - struct iovec *proghdr, int proghdrcount, - struct iobref *iobref); +int +rpcsvc_callback_submit(rpcsvc_t *rpc, rpc_transport_t *trans, + rpcsvc_cbk_program_t *prog, int procnum, + struct iovec *proghdr, int proghdrcount, + struct iobref *iobref); rpcsvc_actor_t * -rpcsvc_program_actor (rpcsvc_request_t *req); +rpcsvc_program_actor(rpcsvc_request_t *req); int -rpcsvc_transport_unix_options_build (dict_t **options, char *filepath); +rpcsvc_transport_unix_options_build(dict_t **options, char *filepath); int -rpcsvc_set_allow_insecure (rpcsvc_t *svc, dict_t *options); +rpcsvc_set_allow_insecure(rpcsvc_t *svc, dict_t *options); int -rpcsvc_set_addr_namelookup (rpcsvc_t *svc, dict_t *options); +rpcsvc_set_addr_namelookup(rpcsvc_t *svc, dict_t *options); int -rpcsvc_set_root_squash (rpcsvc_t *svc, dict_t *options); +rpcsvc_set_root_squash(rpcsvc_t *svc, dict_t *options); int -rpcsvc_set_outstanding_rpc_limit (rpcsvc_t *svc, dict_t *options, int defvalue); +rpcsvc_set_outstanding_rpc_limit(rpcsvc_t *svc, dict_t *options, int defvalue); int -rpcsvc_set_throttle_on (rpcsvc_t *svc); +rpcsvc_set_throttle_on(rpcsvc_t *svc); int -rpcsvc_set_throttle_off (rpcsvc_t *svc); +rpcsvc_set_throttle_off(rpcsvc_t *svc); gf_boolean_t -rpcsvc_get_throttle (rpcsvc_t *svc); +rpcsvc_get_throttle(rpcsvc_t *svc); int -rpcsvc_auth_array (rpcsvc_t *svc, char *volname, int *autharr, int arrlen); +rpcsvc_auth_array(rpcsvc_t *svc, char *volname, int *autharr, int arrlen); rpcsvc_vector_sizer -rpcsvc_get_program_vector_sizer (rpcsvc_t *svc, uint32_t prognum, - uint32_t progver, int procnum); +rpcsvc_get_program_vector_sizer(rpcsvc_t *svc, uint32_t prognum, + uint32_t progver, int procnum); extern int -rpcsvc_ownthread_reconf (rpcsvc_t *svc, int new_eventthreadcount); +rpcsvc_ownthread_reconf(rpcsvc_t *svc, int new_eventthreadcount); -void rpcsvc_autoscale_threads (glusterfs_ctx_t *ctx, rpcsvc_t *rpc, int incr); +void +rpcsvc_autoscale_threads(glusterfs_ctx_t *ctx, rpcsvc_t *rpc, int incr); #endif |