Bug Summary

File:rpc/rpc-lib/src/rpcsvc.c
Location:line 556, column 9
Description:Value stored to 'ret' is never read

Annotated Source Code

1/*
2 Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
3 This file is part of GlusterFS.
4
5 This file is licensed to you under your choice of the GNU Lesser
6 General Public License, version 3 or any later version (LGPLv3 or
7 later), or the GNU General Public License, version 2 (GPLv2), in all
8 cases as published by the Free Software Foundation.
9*/
10
11#ifndef _CONFIG_H
12#define _CONFIG_H
13#include "config.h"
14#endif
15
16#include "rpcsvc.h"
17#include "rpc-transport.h"
18#include "dict.h"
19#include "logging.h"
20#include "byte-order.h"
21#include "common-utils.h"
22#include "compat-errno.h"
23#include "list.h"
24#include "xdr-rpc.h"
25#include "iobuf.h"
26#include "globals.h"
27#include "xdr-common.h"
28#include "xdr-generic.h"
29#include "rpc-common-xdr.h"
30#include "syncop.h"
31
32#include <errno(*__errno_location ()).h>
33#include <pthread.h>
34#include <stdlib.h>
35#include <rpc/rpc.h>
36#include <rpc/pmap_clnt.h>
37#include <arpa/inet.h>
38#include <rpc/xdr.h>
39#include <fnmatch.h>
40#include <stdarg.h>
41#include <stdio.h>
42
43#include "xdr-rpcclnt.h"
44
45#define ACL_PROGRAM100227 100227
46
47struct rpcsvc_program gluster_dump_prog;
48
49#define rpcsvc_alloc_request(svc, request)do { request = (rpcsvc_request_t *) mem_get ((svc)->rxpool
); memset (request, 0, sizeof (rpcsvc_request_t)); } while (0
)
\
50 do { \
51 request = (rpcsvc_request_t *) mem_get ((svc)->rxpool); \
52 memset (request, 0, sizeof (rpcsvc_request_t)); \
53 } while (0)
54
55rpcsvc_listener_t *
56rpcsvc_get_listener (rpcsvc_t *svc, uint16_t port, rpc_transport_t *trans);
57
58int
59rpcsvc_notify (rpc_transport_t *trans, void *mydata,
60 rpc_transport_event_t event, void *data, ...);
61
62rpcsvc_notify_wrapper_t *
63rpcsvc_notify_wrapper_alloc (void)
64{
65 rpcsvc_notify_wrapper_t *wrapper = NULL((void*)0);
66
67 wrapper = GF_CALLOC (1, sizeof (*wrapper), gf_common_mt_rpcsvc_wrapper_t)__gf_calloc (1, sizeof (*wrapper), gf_common_mt_rpcsvc_wrapper_t
)
;
68 if (!wrapper) {
69 goto out;
70 }
71
72 INIT_LIST_HEAD (&wrapper->list)do { (&wrapper->list)->next = (&wrapper->list
)->prev = &wrapper->list; } while (0)
;
73out:
74 return wrapper;
75}
76
77
78void
79rpcsvc_listener_destroy (rpcsvc_listener_t *listener)
80{
81 rpcsvc_t *svc = NULL((void*)0);
82
83 if (!listener) {
84 goto out;
85 }
86
87 svc = listener->svc;
88 if (!svc) {
89 goto listener_free;
90 }
91
92 pthread_mutex_lock (&svc->rpclock);
93 {
94 list_del_init (&listener->list);
95 }
96 pthread_mutex_unlock (&svc->rpclock);
97
98listener_free:
99 GF_FREE (listener)__gf_free (listener);
100out:
101 return;
102}
103
104rpcsvc_vector_sizer
105rpcsvc_get_program_vector_sizer (rpcsvc_t *svc, uint32_t prognum,
106 uint32_t progver, uint32_t procnum)
107{
108 rpcsvc_program_t *program = NULL((void*)0);
109 char found = 0;
110
111 if (!svc)
112 return NULL((void*)0);
113
114 pthread_mutex_lock (&svc->rpclock);
115 {
116 list_for_each_entry (program, &svc->programs, program)for (program = ((typeof(*program) *)((char *)((&svc->programs
)->next)-(unsigned long)(&((typeof(*program) *)0)->
program))); &program->program != (&svc->programs
); program = ((typeof(*program) *)((char *)(program->program
.next)-(unsigned long)(&((typeof(*program) *)0)->program
))))
{
117 if ((program->prognum == prognum)
118 && (program->progver == progver)) {
119 found = 1;
120 break;
121 }
122 }
123 }
124 pthread_mutex_unlock (&svc->rpclock);
125
126 if (found)
127 return program->actors[procnum].vector_sizer;
128 else
129 return NULL((void*)0);
130}
131
132/* This needs to change to returning errors, since
133 * we need to return RPC specific error messages when some
134 * of the pointers below are NULL.
135 */
136rpcsvc_actor_t *
137rpcsvc_program_actor (rpcsvc_request_t *req)
138{
139 rpcsvc_program_t *program = NULL((void*)0);
140 int err = SYSTEM_ERR;
141 rpcsvc_actor_t *actor = NULL((void*)0);
142 rpcsvc_t *svc = NULL((void*)0);
143 char found = 0;
144
145 if (!req)
146 goto err;
147
148 svc = req->svc;
149 pthread_mutex_lock (&svc->rpclock);
150 {
151 list_for_each_entry (program, &svc->programs, program)for (program = ((typeof(*program) *)((char *)((&svc->programs
)->next)-(unsigned long)(&((typeof(*program) *)0)->
program))); &program->program != (&svc->programs
); program = ((typeof(*program) *)((char *)(program->program
.next)-(unsigned long)(&((typeof(*program) *)0)->program
))))
{
152 if (program->prognum == req->prognum) {
153 err = PROG_MISMATCH;
154 }
155
156 if ((program->prognum == req->prognum)
157 && (program->progver == req->progver)) {
158 found = 1;
159 break;
160 }
161 }
162 }
163 pthread_mutex_unlock (&svc->rpclock);
164
165 if (!found) {
166 if (err != PROG_MISMATCH) {
167 /* log in DEBUG when nfs clients try to see if
168 * ACL requests are accepted by nfs server
169 */
170 gf_log (GF_RPCSVC, (req->prognum == ACL_PROGRAM) ?do { do { if (0) printf ("RPC program not available (req %u %u)"
, req->prognum, req->progver); } while (0); _gf_log ("rpc-service"
, "rpcsvc.c", __FUNCTION__, 173, (req->prognum == 100227) ?
GF_LOG_DEBUG : GF_LOG_WARNING, "RPC program not available (req %u %u)"
, req->prognum, req->progver); } while (0)
171 GF_LOG_DEBUG : GF_LOG_WARNING,do { do { if (0) printf ("RPC program not available (req %u %u)"
, req->prognum, req->progver); } while (0); _gf_log ("rpc-service"
, "rpcsvc.c", __FUNCTION__, 173, (req->prognum == 100227) ?
GF_LOG_DEBUG : GF_LOG_WARNING, "RPC program not available (req %u %u)"
, req->prognum, req->progver); } while (0)
172 "RPC program not available (req %u %u)",do { do { if (0) printf ("RPC program not available (req %u %u)"
, req->prognum, req->progver); } while (0); _gf_log ("rpc-service"
, "rpcsvc.c", __FUNCTION__, 173, (req->prognum == 100227) ?
GF_LOG_DEBUG : GF_LOG_WARNING, "RPC program not available (req %u %u)"
, req->prognum, req->progver); } while (0)
173 req->prognum, req->progver)do { do { if (0) printf ("RPC program not available (req %u %u)"
, req->prognum, req->progver); } while (0); _gf_log ("rpc-service"
, "rpcsvc.c", __FUNCTION__, 173, (req->prognum == 100227) ?
GF_LOG_DEBUG : GF_LOG_WARNING, "RPC program not available (req %u %u)"
, req->prognum, req->progver); } while (0)
;
174 err = PROG_UNAVAIL;
175 goto err;
176 }
177
178 gf_log (GF_RPCSVC, GF_LOG_WARNING,do { do { if (0) printf ("RPC program version not available (req %u %u)"
, req->prognum, req->progver); } while (0); _gf_log ("rpc-service"
, "rpcsvc.c", __FUNCTION__, 180, GF_LOG_WARNING, "RPC program version not available (req %u %u)"
, req->prognum, req->progver); } while (0)
179 "RPC program version not available (req %u %u)",do { do { if (0) printf ("RPC program version not available (req %u %u)"
, req->prognum, req->progver); } while (0); _gf_log ("rpc-service"
, "rpcsvc.c", __FUNCTION__, 180, GF_LOG_WARNING, "RPC program version not available (req %u %u)"
, req->prognum, req->progver); } while (0)
180 req->prognum, req->progver)do { do { if (0) printf ("RPC program version not available (req %u %u)"
, req->prognum, req->progver); } while (0); _gf_log ("rpc-service"
, "rpcsvc.c", __FUNCTION__, 180, GF_LOG_WARNING, "RPC program version not available (req %u %u)"
, req->prognum, req->progver); } while (0)
;
181 goto err;
182 }
183 req->prog = program;
184 if (!program->actors) {
185 gf_log (GF_RPCSVC, GF_LOG_WARNING,do { do { if (0) printf ("RPC Actor not found for program %s %d"
, program->progname, program->prognum); } while (0); _gf_log
("rpc-service", "rpcsvc.c", __FUNCTION__, 187, GF_LOG_WARNING
, "RPC Actor not found for program %s %d", program->progname
, program->prognum); } while (0)
186 "RPC Actor not found for program %s %d",do { do { if (0) printf ("RPC Actor not found for program %s %d"
, program->progname, program->prognum); } while (0); _gf_log
("rpc-service", "rpcsvc.c", __FUNCTION__, 187, GF_LOG_WARNING
, "RPC Actor not found for program %s %d", program->progname
, program->prognum); } while (0)
187 program->progname, program->prognum)do { do { if (0) printf ("RPC Actor not found for program %s %d"
, program->progname, program->prognum); } while (0); _gf_log
("rpc-service", "rpcsvc.c", __FUNCTION__, 187, GF_LOG_WARNING
, "RPC Actor not found for program %s %d", program->progname
, program->prognum); } while (0)
;
188 err = SYSTEM_ERR;
189 goto err;
190 }
191
192 if ((req->procnum < 0) || (req->procnum >= program->numactors)) {
193 gf_log (GF_RPCSVC, GF_LOG_ERROR, "RPC Program procedure not"do { do { if (0) printf ("RPC Program procedure not" " available for procedure %d in %s"
, req->procnum, program->progname); } while (0); _gf_log
("rpc-service", "rpcsvc.c", __FUNCTION__, 195, GF_LOG_ERROR,
"RPC Program procedure not" " available for procedure %d in %s"
, req->procnum, program->progname); } while (0)
194 " available for procedure %d in %s", req->procnum,do { do { if (0) printf ("RPC Program procedure not" " available for procedure %d in %s"
, req->procnum, program->progname); } while (0); _gf_log
("rpc-service", "rpcsvc.c", __FUNCTION__, 195, GF_LOG_ERROR,
"RPC Program procedure not" " available for procedure %d in %s"
, req->procnum, program->progname); } while (0)
195 program->progname)do { do { if (0) printf ("RPC Program procedure not" " available for procedure %d in %s"
, req->procnum, program->progname); } while (0); _gf_log
("rpc-service", "rpcsvc.c", __FUNCTION__, 195, GF_LOG_ERROR,
"RPC Program procedure not" " available for procedure %d in %s"
, req->procnum, program->progname); } while (0)
;
196 err = PROC_UNAVAIL;
197 goto err;
198 }
199
200 actor = &program->actors[req->procnum];
201 if (!actor->actor) {
202 gf_log (GF_RPCSVC, GF_LOG_ERROR, "RPC Program procedure not"do { do { if (0) printf ("RPC Program procedure not" " available for procedure %d in %s"
, req->procnum, program->progname); } while (0); _gf_log
("rpc-service", "rpcsvc.c", __FUNCTION__, 204, GF_LOG_ERROR,
"RPC Program procedure not" " available for procedure %d in %s"
, req->procnum, program->progname); } while (0)
203 " available for procedure %d in %s", req->procnum,do { do { if (0) printf ("RPC Program procedure not" " available for procedure %d in %s"
, req->procnum, program->progname); } while (0); _gf_log
("rpc-service", "rpcsvc.c", __FUNCTION__, 204, GF_LOG_ERROR,
"RPC Program procedure not" " available for procedure %d in %s"
, req->procnum, program->progname); } while (0)
204 program->progname)do { do { if (0) printf ("RPC Program procedure not" " available for procedure %d in %s"
, req->procnum, program->progname); } while (0); _gf_log
("rpc-service", "rpcsvc.c", __FUNCTION__, 204, GF_LOG_ERROR,
"RPC Program procedure not" " available for procedure %d in %s"
, req->procnum, program->progname); } while (0)
;
205 err = PROC_UNAVAIL;
206 actor = NULL((void*)0);
207 goto err;
208 }
209
210 req->synctask = program->synctask;
211
212 err = SUCCESS;
213 gf_log (GF_RPCSVC, GF_LOG_TRACE, "Actor found: %s - %s",do { do { if (0) printf ("Actor found: %s - %s", program->
progname, actor->procname); } while (0); _gf_log ("rpc-service"
, "rpcsvc.c", __FUNCTION__, 214, GF_LOG_TRACE, "Actor found: %s - %s"
, program->progname, actor->procname); } while (0)
214 program->progname, actor->procname)do { do { if (0) printf ("Actor found: %s - %s", program->
progname, actor->procname); } while (0); _gf_log ("rpc-service"
, "rpcsvc.c", __FUNCTION__, 214, GF_LOG_TRACE, "Actor found: %s - %s"
, program->progname, actor->procname); } while (0)
;
215err:
216 if (req)
217 req->rpc_err = err;
218
219 return actor;
220}
221
222
223/* this procedure can only pass 4 arguments to registered notifyfn. To send more
224 * arguments call wrapper->notify directly.
225 */
226static inline void
227rpcsvc_program_notify (rpcsvc_listener_t *listener, rpcsvc_event_t event,
228 void *data)
229{
230 rpcsvc_notify_wrapper_t *wrapper = NULL((void*)0);
231
232 if (!listener) {
233 goto out;
234 }
235
236 list_for_each_entry (wrapper, &listener->svc->notify, list)for (wrapper = ((typeof(*wrapper) *)((char *)((&listener->
svc->notify)->next)-(unsigned long)(&((typeof(*wrapper
) *)0)->list))); &wrapper->list != (&listener->
svc->notify); wrapper = ((typeof(*wrapper) *)((char *)(wrapper
->list.next)-(unsigned long)(&((typeof(*wrapper) *)0)->
list))))
{
237 if (wrapper->notify) {
238 wrapper->notify (listener->svc,
239 wrapper->data,
240 event, data);
241 }
242 }
243
244out:
245 return;
246}
247
248
249static inline int
250rpcsvc_accept (rpcsvc_t *svc, rpc_transport_t *listen_trans,
251 rpc_transport_t *new_trans)
252{
253 rpcsvc_listener_t *listener = NULL((void*)0);
254 int32_t ret = -1;
255
256 listener = rpcsvc_get_listener (svc, -1, listen_trans);
257 if (listener == NULL((void*)0)) {
258 goto out;
259 }
260
261 rpcsvc_program_notify (listener, RPCSVC_EVENT_ACCEPT, new_trans);
262 ret = 0;
263out:
264 return ret;
265}
266
267
268void
269rpcsvc_request_destroy (rpcsvc_request_t *req)
270{
271 if (!req) {
272 goto out;
273 }
274
275 if (req->iobref) {
276 iobref_unref (req->iobref);
277 }
278
279 if (req->hdr_iobuf)
280 iobuf_unref (req->hdr_iobuf);
281
282 rpc_transport_unref (req->trans);
283
284 mem_put (req);
285
286out:
287 return;
288}
289
290
291rpcsvc_request_t *
292rpcsvc_request_init (rpcsvc_t *svc, rpc_transport_t *trans,
293 struct rpc_msg *callmsg,
294 struct iovec progmsg, rpc_transport_pollin_t *msg,
295 rpcsvc_request_t *req)
296{
297 int i = 0;
298
299 if ((!trans) || (!callmsg)|| (!req) || (!msg))
300 return NULL((void*)0);
301
302 /* We start a RPC request as always denied. */
303 req->rpc_status = MSG_DENIED;
304 req->xid = rpc_call_xid (callmsg)((callmsg)->rm_xid);
305 req->prognum = rpc_call_program (callmsg)((callmsg)->ru.RM_cmb.cb_prog);
306 req->progver = rpc_call_progver (callmsg)((callmsg)->ru.RM_cmb.cb_vers);
307 req->procnum = rpc_call_progproc (callmsg)((callmsg)->ru.RM_cmb.cb_proc);
308 req->trans = rpc_transport_ref (trans);
309 req->count = msg->count;
310 req->msg[0] = progmsg;
311 req->iobref = iobref_ref (msg->iobref);
312 if (msg->vectored) {
313 /* msg->vector[2] is defined in structure. prevent a
314 out of bound access */
315 for (i = 1; i < min (msg->count, 2)((msg->count)<(2)?(msg->count):(2)); i++) {
316 req->msg[i] = msg->vector[i];
317 }
318 }
319
320 req->svc = svc;
321 req->trans_private = msg->private;
322
323 INIT_LIST_HEAD (&req->txlist)do { (&req->txlist)->next = (&req->txlist)->
prev = &req->txlist; } while (0)
;
324 req->payloadsize = 0;
325
326 /* By this time, the data bytes for the auth scheme would have already
327 * been copied into the required sections of the req structure,
328 * we just need to fill in the meta-data about it now.
329 */
330 req->cred.flavour = rpc_call_cred_flavour (callmsg)((((&(callmsg)->ru.RM_cmb.cb_cred))->oa_flavor));
331 req->cred.datalen = rpc_call_cred_len (callmsg)((((&(callmsg)->ru.RM_cmb.cb_cred))->oa_length));
332 req->verf.flavour = rpc_call_verf_flavour (callmsg)((((&(callmsg)->ru.RM_cmb.cb_verf))->oa_flavor));
333 req->verf.datalen = rpc_call_verf_len (callmsg)((((&(callmsg)->ru.RM_cmb.cb_verf))->oa_length));
334
335 /* AUTH */
336 rpcsvc_auth_request_init (req);
337 return req;
338}
339
340
341rpcsvc_request_t *
342rpcsvc_request_create (rpcsvc_t *svc, rpc_transport_t *trans,
343 rpc_transport_pollin_t *msg)
344{
345 char *msgbuf = NULL((void*)0);
346 struct rpc_msg rpcmsg;
347 struct iovec progmsg; /* RPC Program payload */
348 rpcsvc_request_t *req = NULL((void*)0);
349 size_t msglen = 0;
350 int ret = -1;
351
352 if (!svc || !trans)
353 return NULL((void*)0);
354
355 /* We need to allocate the request before actually calling
356 * rpcsvc_request_init on the request so that we, can fill the auth
357 * data directly into the request structure from the message iobuf.
358 * This avoids a need to keep a temp buffer into which the auth data
359 * would've been copied otherwise.
360 */
361 rpcsvc_alloc_request (svc, req)do { req = (rpcsvc_request_t *) mem_get ((svc)->rxpool); memset
(req, 0, sizeof (rpcsvc_request_t)); } while (0)
;
362 if (!req) {
363 goto err;
364 }
365
366 msgbuf = msg->vector[0].iov_base;
367 msglen = msg->vector[0].iov_len;
368
369 ret = xdr_to_rpc_call (msgbuf, msglen, &rpcmsg, &progmsg,
370 req->cred.authdata,req->verf.authdata);
371
372 if (ret == -1) {
373 gf_log (GF_RPCSVC, GF_LOG_WARNING, "RPC call decoding failed")do { do { if (0) printf ("RPC call decoding failed"); } while
(0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__, 373, GF_LOG_WARNING
, "RPC call decoding failed"); } while (0)
;
374 rpcsvc_request_seterr (req, GARBAGE_ARGS)(req)->rpc_err = GARBAGE_ARGS;
375 req->trans = rpc_transport_ref (trans);
376 req->svc = svc;
377 goto err;
378 }
379
380 ret = -1;
381 rpcsvc_request_init (svc, trans, &rpcmsg, progmsg, msg, req);
382
383 gf_log (GF_RPCSVC, GF_LOG_TRACE, "received rpc-message (XID: 0x%lx, "do { do { if (0) printf ("received rpc-message (XID: 0x%lx, "
"Ver: %ld, Program: %ld, ProgVers: %ld, Proc: %ld) from" " rpc-transport (%s)"
, ((&rpcmsg)->rm_xid), ((&rpcmsg)->ru.RM_cmb.cb_rpcvers
), ((&rpcmsg)->ru.RM_cmb.cb_prog), ((&rpcmsg)->
ru.RM_cmb.cb_vers), ((&rpcmsg)->ru.RM_cmb.cb_proc), trans
->name); } while (0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__
, 388, GF_LOG_TRACE, "received rpc-message (XID: 0x%lx, " "Ver: %ld, Program: %ld, ProgVers: %ld, Proc: %ld) from"
" rpc-transport (%s)", ((&rpcmsg)->rm_xid), ((&rpcmsg
)->ru.RM_cmb.cb_rpcvers), ((&rpcmsg)->ru.RM_cmb.cb_prog
), ((&rpcmsg)->ru.RM_cmb.cb_vers), ((&rpcmsg)->
ru.RM_cmb.cb_proc), trans->name); } while (0)
384 "Ver: %ld, Program: %ld, ProgVers: %ld, Proc: %ld) from"do { do { if (0) printf ("received rpc-message (XID: 0x%lx, "
"Ver: %ld, Program: %ld, ProgVers: %ld, Proc: %ld) from" " rpc-transport (%s)"
, ((&rpcmsg)->rm_xid), ((&rpcmsg)->ru.RM_cmb.cb_rpcvers
), ((&rpcmsg)->ru.RM_cmb.cb_prog), ((&rpcmsg)->
ru.RM_cmb.cb_vers), ((&rpcmsg)->ru.RM_cmb.cb_proc), trans
->name); } while (0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__
, 388, GF_LOG_TRACE, "received rpc-message (XID: 0x%lx, " "Ver: %ld, Program: %ld, ProgVers: %ld, Proc: %ld) from"
" rpc-transport (%s)", ((&rpcmsg)->rm_xid), ((&rpcmsg
)->ru.RM_cmb.cb_rpcvers), ((&rpcmsg)->ru.RM_cmb.cb_prog
), ((&rpcmsg)->ru.RM_cmb.cb_vers), ((&rpcmsg)->
ru.RM_cmb.cb_proc), trans->name); } while (0)
385 " rpc-transport (%s)", rpc_call_xid (&rpcmsg),do { do { if (0) printf ("received rpc-message (XID: 0x%lx, "
"Ver: %ld, Program: %ld, ProgVers: %ld, Proc: %ld) from" " rpc-transport (%s)"
, ((&rpcmsg)->rm_xid), ((&rpcmsg)->ru.RM_cmb.cb_rpcvers
), ((&rpcmsg)->ru.RM_cmb.cb_prog), ((&rpcmsg)->
ru.RM_cmb.cb_vers), ((&rpcmsg)->ru.RM_cmb.cb_proc), trans
->name); } while (0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__
, 388, GF_LOG_TRACE, "received rpc-message (XID: 0x%lx, " "Ver: %ld, Program: %ld, ProgVers: %ld, Proc: %ld) from"
" rpc-transport (%s)", ((&rpcmsg)->rm_xid), ((&rpcmsg
)->ru.RM_cmb.cb_rpcvers), ((&rpcmsg)->ru.RM_cmb.cb_prog
), ((&rpcmsg)->ru.RM_cmb.cb_vers), ((&rpcmsg)->
ru.RM_cmb.cb_proc), trans->name); } while (0)
386 rpc_call_rpcvers (&rpcmsg), rpc_call_program (&rpcmsg),do { do { if (0) printf ("received rpc-message (XID: 0x%lx, "
"Ver: %ld, Program: %ld, ProgVers: %ld, Proc: %ld) from" " rpc-transport (%s)"
, ((&rpcmsg)->rm_xid), ((&rpcmsg)->ru.RM_cmb.cb_rpcvers
), ((&rpcmsg)->ru.RM_cmb.cb_prog), ((&rpcmsg)->
ru.RM_cmb.cb_vers), ((&rpcmsg)->ru.RM_cmb.cb_proc), trans
->name); } while (0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__
, 388, GF_LOG_TRACE, "received rpc-message (XID: 0x%lx, " "Ver: %ld, Program: %ld, ProgVers: %ld, Proc: %ld) from"
" rpc-transport (%s)", ((&rpcmsg)->rm_xid), ((&rpcmsg
)->ru.RM_cmb.cb_rpcvers), ((&rpcmsg)->ru.RM_cmb.cb_prog
), ((&rpcmsg)->ru.RM_cmb.cb_vers), ((&rpcmsg)->
ru.RM_cmb.cb_proc), trans->name); } while (0)
387 rpc_call_progver (&rpcmsg), rpc_call_progproc (&rpcmsg),do { do { if (0) printf ("received rpc-message (XID: 0x%lx, "
"Ver: %ld, Program: %ld, ProgVers: %ld, Proc: %ld) from" " rpc-transport (%s)"
, ((&rpcmsg)->rm_xid), ((&rpcmsg)->ru.RM_cmb.cb_rpcvers
), ((&rpcmsg)->ru.RM_cmb.cb_prog), ((&rpcmsg)->
ru.RM_cmb.cb_vers), ((&rpcmsg)->ru.RM_cmb.cb_proc), trans
->name); } while (0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__
, 388, GF_LOG_TRACE, "received rpc-message (XID: 0x%lx, " "Ver: %ld, Program: %ld, ProgVers: %ld, Proc: %ld) from"
" rpc-transport (%s)", ((&rpcmsg)->rm_xid), ((&rpcmsg
)->ru.RM_cmb.cb_rpcvers), ((&rpcmsg)->ru.RM_cmb.cb_prog
), ((&rpcmsg)->ru.RM_cmb.cb_vers), ((&rpcmsg)->
ru.RM_cmb.cb_proc), trans->name); } while (0)
388 trans->name)do { do { if (0) printf ("received rpc-message (XID: 0x%lx, "
"Ver: %ld, Program: %ld, ProgVers: %ld, Proc: %ld) from" " rpc-transport (%s)"
, ((&rpcmsg)->rm_xid), ((&rpcmsg)->ru.RM_cmb.cb_rpcvers
), ((&rpcmsg)->ru.RM_cmb.cb_prog), ((&rpcmsg)->
ru.RM_cmb.cb_vers), ((&rpcmsg)->ru.RM_cmb.cb_proc), trans
->name); } while (0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__
, 388, GF_LOG_TRACE, "received rpc-message (XID: 0x%lx, " "Ver: %ld, Program: %ld, ProgVers: %ld, Proc: %ld) from"
" rpc-transport (%s)", ((&rpcmsg)->rm_xid), ((&rpcmsg
)->ru.RM_cmb.cb_rpcvers), ((&rpcmsg)->ru.RM_cmb.cb_prog
), ((&rpcmsg)->ru.RM_cmb.cb_vers), ((&rpcmsg)->
ru.RM_cmb.cb_proc), trans->name); } while (0)
;
389
390 if (rpc_call_rpcvers (&rpcmsg)((&rpcmsg)->ru.RM_cmb.cb_rpcvers) != 2) {
391 /* LOG- TODO: print rpc version, also print the peerinfo
392 from transport */
393 gf_log (GF_RPCSVC, GF_LOG_ERROR, "RPC version not supported "do { do { if (0) printf ("RPC version not supported " "(XID: 0x%lx, Ver: %ld, Prog: %ld, ProgVers: %ld, "
"Proc: %ld) from trans (%s)", ((&rpcmsg)->rm_xid), ((
&rpcmsg)->ru.RM_cmb.cb_rpcvers), ((&rpcmsg)->ru
.RM_cmb.cb_prog), ((&rpcmsg)->ru.RM_cmb.cb_vers), ((&
rpcmsg)->ru.RM_cmb.cb_proc), trans->name); } while (0);
_gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__, 398, GF_LOG_ERROR
, "RPC version not supported " "(XID: 0x%lx, Ver: %ld, Prog: %ld, ProgVers: %ld, "
"Proc: %ld) from trans (%s)", ((&rpcmsg)->rm_xid), ((
&rpcmsg)->ru.RM_cmb.cb_rpcvers), ((&rpcmsg)->ru
.RM_cmb.cb_prog), ((&rpcmsg)->ru.RM_cmb.cb_vers), ((&
rpcmsg)->ru.RM_cmb.cb_proc), trans->name); } while (0)
394 "(XID: 0x%lx, Ver: %ld, Prog: %ld, ProgVers: %ld, "do { do { if (0) printf ("RPC version not supported " "(XID: 0x%lx, Ver: %ld, Prog: %ld, ProgVers: %ld, "
"Proc: %ld) from trans (%s)", ((&rpcmsg)->rm_xid), ((
&rpcmsg)->ru.RM_cmb.cb_rpcvers), ((&rpcmsg)->ru
.RM_cmb.cb_prog), ((&rpcmsg)->ru.RM_cmb.cb_vers), ((&
rpcmsg)->ru.RM_cmb.cb_proc), trans->name); } while (0);
_gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__, 398, GF_LOG_ERROR
, "RPC version not supported " "(XID: 0x%lx, Ver: %ld, Prog: %ld, ProgVers: %ld, "
"Proc: %ld) from trans (%s)", ((&rpcmsg)->rm_xid), ((
&rpcmsg)->ru.RM_cmb.cb_rpcvers), ((&rpcmsg)->ru
.RM_cmb.cb_prog), ((&rpcmsg)->ru.RM_cmb.cb_vers), ((&
rpcmsg)->ru.RM_cmb.cb_proc), trans->name); } while (0)
395 "Proc: %ld) from trans (%s)", rpc_call_xid (&rpcmsg),do { do { if (0) printf ("RPC version not supported " "(XID: 0x%lx, Ver: %ld, Prog: %ld, ProgVers: %ld, "
"Proc: %ld) from trans (%s)", ((&rpcmsg)->rm_xid), ((
&rpcmsg)->ru.RM_cmb.cb_rpcvers), ((&rpcmsg)->ru
.RM_cmb.cb_prog), ((&rpcmsg)->ru.RM_cmb.cb_vers), ((&
rpcmsg)->ru.RM_cmb.cb_proc), trans->name); } while (0);
_gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__, 398, GF_LOG_ERROR
, "RPC version not supported " "(XID: 0x%lx, Ver: %ld, Prog: %ld, ProgVers: %ld, "
"Proc: %ld) from trans (%s)", ((&rpcmsg)->rm_xid), ((
&rpcmsg)->ru.RM_cmb.cb_rpcvers), ((&rpcmsg)->ru
.RM_cmb.cb_prog), ((&rpcmsg)->ru.RM_cmb.cb_vers), ((&
rpcmsg)->ru.RM_cmb.cb_proc), trans->name); } while (0)
396 rpc_call_rpcvers (&rpcmsg), rpc_call_program (&rpcmsg),do { do { if (0) printf ("RPC version not supported " "(XID: 0x%lx, Ver: %ld, Prog: %ld, ProgVers: %ld, "
"Proc: %ld) from trans (%s)", ((&rpcmsg)->rm_xid), ((
&rpcmsg)->ru.RM_cmb.cb_rpcvers), ((&rpcmsg)->ru
.RM_cmb.cb_prog), ((&rpcmsg)->ru.RM_cmb.cb_vers), ((&
rpcmsg)->ru.RM_cmb.cb_proc), trans->name); } while (0);
_gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__, 398, GF_LOG_ERROR
, "RPC version not supported " "(XID: 0x%lx, Ver: %ld, Prog: %ld, ProgVers: %ld, "
"Proc: %ld) from trans (%s)", ((&rpcmsg)->rm_xid), ((
&rpcmsg)->ru.RM_cmb.cb_rpcvers), ((&rpcmsg)->ru
.RM_cmb.cb_prog), ((&rpcmsg)->ru.RM_cmb.cb_vers), ((&
rpcmsg)->ru.RM_cmb.cb_proc), trans->name); } while (0)
397 rpc_call_progver (&rpcmsg), rpc_call_progproc (&rpcmsg),do { do { if (0) printf ("RPC version not supported " "(XID: 0x%lx, Ver: %ld, Prog: %ld, ProgVers: %ld, "
"Proc: %ld) from trans (%s)", ((&rpcmsg)->rm_xid), ((
&rpcmsg)->ru.RM_cmb.cb_rpcvers), ((&rpcmsg)->ru
.RM_cmb.cb_prog), ((&rpcmsg)->ru.RM_cmb.cb_vers), ((&
rpcmsg)->ru.RM_cmb.cb_proc), trans->name); } while (0);
_gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__, 398, GF_LOG_ERROR
, "RPC version not supported " "(XID: 0x%lx, Ver: %ld, Prog: %ld, ProgVers: %ld, "
"Proc: %ld) from trans (%s)", ((&rpcmsg)->rm_xid), ((
&rpcmsg)->ru.RM_cmb.cb_rpcvers), ((&rpcmsg)->ru
.RM_cmb.cb_prog), ((&rpcmsg)->ru.RM_cmb.cb_vers), ((&
rpcmsg)->ru.RM_cmb.cb_proc), trans->name); } while (0)
398 trans->name)do { do { if (0) printf ("RPC version not supported " "(XID: 0x%lx, Ver: %ld, Prog: %ld, ProgVers: %ld, "
"Proc: %ld) from trans (%s)", ((&rpcmsg)->rm_xid), ((
&rpcmsg)->ru.RM_cmb.cb_rpcvers), ((&rpcmsg)->ru
.RM_cmb.cb_prog), ((&rpcmsg)->ru.RM_cmb.cb_vers), ((&
rpcmsg)->ru.RM_cmb.cb_proc), trans->name); } while (0);
_gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__, 398, GF_LOG_ERROR
, "RPC version not supported " "(XID: 0x%lx, Ver: %ld, Prog: %ld, ProgVers: %ld, "
"Proc: %ld) from trans (%s)", ((&rpcmsg)->rm_xid), ((
&rpcmsg)->ru.RM_cmb.cb_rpcvers), ((&rpcmsg)->ru
.RM_cmb.cb_prog), ((&rpcmsg)->ru.RM_cmb.cb_vers), ((&
rpcmsg)->ru.RM_cmb.cb_proc), trans->name); } while (0)
;
399 rpcsvc_request_seterr (req, RPC_MISMATCH)(req)->rpc_err = RPC_MISMATCH;
400 goto err;
401 }
402
403 ret = rpcsvc_authenticate (req);
404 if (ret == RPCSVC_AUTH_REJECT2) {
405 /* No need to set auth_err, that is the responsibility of
406 * the authentication handler since only that know what exact
407 * error happened.
408 */
409 rpcsvc_request_seterr (req, AUTH_ERROR)(req)->rpc_err = AUTH_ERROR;
410 gf_log (GF_RPCSVC, GF_LOG_ERROR, "auth failed on request. "do { do { if (0) printf ("auth failed on request. " "(XID: 0x%lx, Ver: %ld, Prog: %ld, ProgVers: %ld, "
"Proc: %ld) from trans (%s)", ((&rpcmsg)->rm_xid), ((
&rpcmsg)->ru.RM_cmb.cb_rpcvers), ((&rpcmsg)->ru
.RM_cmb.cb_prog), ((&rpcmsg)->ru.RM_cmb.cb_vers), ((&
rpcmsg)->ru.RM_cmb.cb_proc), trans->name); } while (0);
_gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__, 415, GF_LOG_ERROR
, "auth failed on request. " "(XID: 0x%lx, Ver: %ld, Prog: %ld, ProgVers: %ld, "
"Proc: %ld) from trans (%s)", ((&rpcmsg)->rm_xid), ((
&rpcmsg)->ru.RM_cmb.cb_rpcvers), ((&rpcmsg)->ru
.RM_cmb.cb_prog), ((&rpcmsg)->ru.RM_cmb.cb_vers), ((&
rpcmsg)->ru.RM_cmb.cb_proc), trans->name); } while (0)
411 "(XID: 0x%lx, Ver: %ld, Prog: %ld, ProgVers: %ld, "do { do { if (0) printf ("auth failed on request. " "(XID: 0x%lx, Ver: %ld, Prog: %ld, ProgVers: %ld, "
"Proc: %ld) from trans (%s)", ((&rpcmsg)->rm_xid), ((
&rpcmsg)->ru.RM_cmb.cb_rpcvers), ((&rpcmsg)->ru
.RM_cmb.cb_prog), ((&rpcmsg)->ru.RM_cmb.cb_vers), ((&
rpcmsg)->ru.RM_cmb.cb_proc), trans->name); } while (0);
_gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__, 415, GF_LOG_ERROR
, "auth failed on request. " "(XID: 0x%lx, Ver: %ld, Prog: %ld, ProgVers: %ld, "
"Proc: %ld) from trans (%s)", ((&rpcmsg)->rm_xid), ((
&rpcmsg)->ru.RM_cmb.cb_rpcvers), ((&rpcmsg)->ru
.RM_cmb.cb_prog), ((&rpcmsg)->ru.RM_cmb.cb_vers), ((&
rpcmsg)->ru.RM_cmb.cb_proc), trans->name); } while (0)
412 "Proc: %ld) from trans (%s)", rpc_call_xid (&rpcmsg),do { do { if (0) printf ("auth failed on request. " "(XID: 0x%lx, Ver: %ld, Prog: %ld, ProgVers: %ld, "
"Proc: %ld) from trans (%s)", ((&rpcmsg)->rm_xid), ((
&rpcmsg)->ru.RM_cmb.cb_rpcvers), ((&rpcmsg)->ru
.RM_cmb.cb_prog), ((&rpcmsg)->ru.RM_cmb.cb_vers), ((&
rpcmsg)->ru.RM_cmb.cb_proc), trans->name); } while (0);
_gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__, 415, GF_LOG_ERROR
, "auth failed on request. " "(XID: 0x%lx, Ver: %ld, Prog: %ld, ProgVers: %ld, "
"Proc: %ld) from trans (%s)", ((&rpcmsg)->rm_xid), ((
&rpcmsg)->ru.RM_cmb.cb_rpcvers), ((&rpcmsg)->ru
.RM_cmb.cb_prog), ((&rpcmsg)->ru.RM_cmb.cb_vers), ((&
rpcmsg)->ru.RM_cmb.cb_proc), trans->name); } while (0)
413 rpc_call_rpcvers (&rpcmsg), rpc_call_program (&rpcmsg),do { do { if (0) printf ("auth failed on request. " "(XID: 0x%lx, Ver: %ld, Prog: %ld, ProgVers: %ld, "
"Proc: %ld) from trans (%s)", ((&rpcmsg)->rm_xid), ((
&rpcmsg)->ru.RM_cmb.cb_rpcvers), ((&rpcmsg)->ru
.RM_cmb.cb_prog), ((&rpcmsg)->ru.RM_cmb.cb_vers), ((&
rpcmsg)->ru.RM_cmb.cb_proc), trans->name); } while (0);
_gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__, 415, GF_LOG_ERROR
, "auth failed on request. " "(XID: 0x%lx, Ver: %ld, Prog: %ld, ProgVers: %ld, "
"Proc: %ld) from trans (%s)", ((&rpcmsg)->rm_xid), ((
&rpcmsg)->ru.RM_cmb.cb_rpcvers), ((&rpcmsg)->ru
.RM_cmb.cb_prog), ((&rpcmsg)->ru.RM_cmb.cb_vers), ((&
rpcmsg)->ru.RM_cmb.cb_proc), trans->name); } while (0)
414 rpc_call_progver (&rpcmsg), rpc_call_progproc (&rpcmsg),do { do { if (0) printf ("auth failed on request. " "(XID: 0x%lx, Ver: %ld, Prog: %ld, ProgVers: %ld, "
"Proc: %ld) from trans (%s)", ((&rpcmsg)->rm_xid), ((
&rpcmsg)->ru.RM_cmb.cb_rpcvers), ((&rpcmsg)->ru
.RM_cmb.cb_prog), ((&rpcmsg)->ru.RM_cmb.cb_vers), ((&
rpcmsg)->ru.RM_cmb.cb_proc), trans->name); } while (0);
_gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__, 415, GF_LOG_ERROR
, "auth failed on request. " "(XID: 0x%lx, Ver: %ld, Prog: %ld, ProgVers: %ld, "
"Proc: %ld) from trans (%s)", ((&rpcmsg)->rm_xid), ((
&rpcmsg)->ru.RM_cmb.cb_rpcvers), ((&rpcmsg)->ru
.RM_cmb.cb_prog), ((&rpcmsg)->ru.RM_cmb.cb_vers), ((&
rpcmsg)->ru.RM_cmb.cb_proc), trans->name); } while (0)
415 trans->name)do { do { if (0) printf ("auth failed on request. " "(XID: 0x%lx, Ver: %ld, Prog: %ld, ProgVers: %ld, "
"Proc: %ld) from trans (%s)", ((&rpcmsg)->rm_xid), ((
&rpcmsg)->ru.RM_cmb.cb_rpcvers), ((&rpcmsg)->ru
.RM_cmb.cb_prog), ((&rpcmsg)->ru.RM_cmb.cb_vers), ((&
rpcmsg)->ru.RM_cmb.cb_proc), trans->name); } while (0);
_gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__, 415, GF_LOG_ERROR
, "auth failed on request. " "(XID: 0x%lx, Ver: %ld, Prog: %ld, ProgVers: %ld, "
"Proc: %ld) from trans (%s)", ((&rpcmsg)->rm_xid), ((
&rpcmsg)->ru.RM_cmb.cb_rpcvers), ((&rpcmsg)->ru
.RM_cmb.cb_prog), ((&rpcmsg)->ru.RM_cmb.cb_vers), ((&
rpcmsg)->ru.RM_cmb.cb_proc), trans->name); } while (0)
;
416 ret = -1;
417 goto err;
418 }
419
420
421 /* If the error is not RPC_MISMATCH, we consider the call as accepted
422 * since we are not handling authentication failures for now.
423 */
424 req->rpc_status = MSG_ACCEPTED;
425 ret = 0;
426err:
427 if (ret == -1) {
428 ret = rpcsvc_error_reply (req);
429 if (ret)
430 gf_log ("rpcsvc", GF_LOG_WARNING,do { do { if (0) printf ("failed to queue error reply"); } while
(0); _gf_log ("rpcsvc", "rpcsvc.c", __FUNCTION__, 431, GF_LOG_WARNING
, "failed to queue error reply"); } while (0)
431 "failed to queue error reply")do { do { if (0) printf ("failed to queue error reply"); } while
(0); _gf_log ("rpcsvc", "rpcsvc.c", __FUNCTION__, 431, GF_LOG_WARNING
, "failed to queue error reply"); } while (0)
;
432 req = NULL((void*)0);
433 }
434
435 return req;
436}
437
438
439int
440rpcsvc_check_and_reply_error (int ret, call_frame_t *frame, void *opaque)
441{
442 rpcsvc_request_t *req = NULL((void*)0);
443
444 req = opaque;
445
446 if (ret)
447 gf_log ("rpcsvc", GF_LOG_ERROR,do { do { if (0) printf ("rpc actor failed to complete successfully"
); } while (0); _gf_log ("rpcsvc", "rpcsvc.c", __FUNCTION__, 448
, GF_LOG_ERROR, "rpc actor failed to complete successfully");
} while (0)
448 "rpc actor failed to complete successfully")do { do { if (0) printf ("rpc actor failed to complete successfully"
); } while (0); _gf_log ("rpcsvc", "rpcsvc.c", __FUNCTION__, 448
, GF_LOG_ERROR, "rpc actor failed to complete successfully");
} while (0)
;
449
450 if (ret == RPCSVC_ACTOR_ERROR(-1)) {
451 ret = rpcsvc_error_reply (req);
452 if (ret)
453 gf_log ("rpcsvc", GF_LOG_WARNING,do { do { if (0) printf ("failed to queue error reply"); } while
(0); _gf_log ("rpcsvc", "rpcsvc.c", __FUNCTION__, 454, GF_LOG_WARNING
, "failed to queue error reply"); } while (0)
454 "failed to queue error reply")do { do { if (0) printf ("failed to queue error reply"); } while
(0); _gf_log ("rpcsvc", "rpcsvc.c", __FUNCTION__, 454, GF_LOG_WARNING
, "failed to queue error reply"); } while (0)
;
455 }
456
457 return 0;
458}
459
460int
461rpcsvc_handle_rpc_call (rpcsvc_t *svc, rpc_transport_t *trans,
462 rpc_transport_pollin_t *msg)
463{
464 rpcsvc_actor_t *actor = NULL((void*)0);
465 rpcsvc_actor actor_fn = NULL((void*)0);
466 rpcsvc_request_t *req = NULL((void*)0);
467 int ret = -1;
468 uint16_t port = 0;
469 gf_boolean_t is_unix = _gf_false;
470 gf_boolean_t unprivileged = _gf_false;
471
472 if (!trans || !svc)
473 return -1;
474
475 switch (trans->peerinfo.sockaddr.ss_family) {
476 case AF_INET2:
477 port = ((struct sockaddr_in *)&trans->peerinfo.sockaddr)->sin_port;
478 break;
479
480 case AF_INET610:
481 port = ((struct sockaddr_in6 *)&trans->peerinfo.sockaddr)->sin6_port;
482 break;
483 case AF_UNIX1:
484 is_unix = _gf_true;
485 break;
486 default:
487 gf_log (GF_RPCSVC, GF_LOG_ERROR,do { do { if (0) printf ("invalid address family (%d)", trans
->peerinfo.sockaddr.ss_family); } while (0); _gf_log ("rpc-service"
, "rpcsvc.c", __FUNCTION__, 489, GF_LOG_ERROR, "invalid address family (%d)"
, trans->peerinfo.sockaddr.ss_family); } while (0)
488 "invalid address family (%d)",do { do { if (0) printf ("invalid address family (%d)", trans
->peerinfo.sockaddr.ss_family); } while (0); _gf_log ("rpc-service"
, "rpcsvc.c", __FUNCTION__, 489, GF_LOG_ERROR, "invalid address family (%d)"
, trans->peerinfo.sockaddr.ss_family); } while (0)
489 trans->peerinfo.sockaddr.ss_family)do { do { if (0) printf ("invalid address family (%d)", trans
->peerinfo.sockaddr.ss_family); } while (0); _gf_log ("rpc-service"
, "rpcsvc.c", __FUNCTION__, 489, GF_LOG_ERROR, "invalid address family (%d)"
, trans->peerinfo.sockaddr.ss_family); } while (0)
;
490 return -1;
491 }
492
493
494
495 if (is_unix == _gf_false) {
496 port = ntohs (port);
497
498 gf_log ("rpcsvc", GF_LOG_TRACE, "Client port: %d", (int)port)do { do { if (0) printf ("Client port: %d", (int)port); } while
(0); _gf_log ("rpcsvc", "rpcsvc.c", __FUNCTION__, 498, GF_LOG_TRACE
, "Client port: %d", (int)port); } while (0)
;
499
500 if (port > 1024)
501 unprivileged = _gf_true;
502 }
503
504 req = rpcsvc_request_create (svc, trans, msg);
505 if (!req)
506 goto err;
507
508 if (!rpcsvc_request_accepted (req)((req)->rpc_status == MSG_ACCEPTED))
509 goto err_reply;
510
511 actor = rpcsvc_program_actor (req);
512 if (!actor)
513 goto err_reply;
514
515 if (0 == svc->allow_insecure && unprivileged && !actor->unprivileged) {
516 /* Non-privileged user, fail request */
517 gf_log ("glusterd", GF_LOG_ERROR,do { do { if (0) printf ("Request received from non-" "privileged port. Failing request"
); } while (0); _gf_log ("glusterd", "rpcsvc.c", __FUNCTION__
, 519, GF_LOG_ERROR, "Request received from non-" "privileged port. Failing request"
); } while (0)
518 "Request received from non-"do { do { if (0) printf ("Request received from non-" "privileged port. Failing request"
); } while (0); _gf_log ("glusterd", "rpcsvc.c", __FUNCTION__
, 519, GF_LOG_ERROR, "Request received from non-" "privileged port. Failing request"
); } while (0)
519 "privileged port. Failing request")do { do { if (0) printf ("Request received from non-" "privileged port. Failing request"
); } while (0); _gf_log ("glusterd", "rpcsvc.c", __FUNCTION__
, 519, GF_LOG_ERROR, "Request received from non-" "privileged port. Failing request"
); } while (0)
;
520 rpcsvc_request_destroy (req);
521 return -1;
522 }
523
524 if (req->rpc_err == SUCCESS) {
525 /* Before going to xlator code, set the THIS properly */
526 THIS(*__glusterfs_this_location()) = svc->mydata;
527
528 actor_fn = actor->actor;
529
530 if (!actor_fn) {
531 rpcsvc_request_seterr (req, PROC_UNAVAIL)(req)->rpc_err = PROC_UNAVAIL;
532 /* LOG TODO: print more info about procnum,
533 prognum etc, also print transport info */
534 gf_log (GF_RPCSVC, GF_LOG_ERROR,do { do { if (0) printf ("No vectored handler present"); } while
(0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__, 535, GF_LOG_ERROR
, "No vectored handler present"); } while (0)
535 "No vectored handler present")do { do { if (0) printf ("No vectored handler present"); } while
(0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__, 535, GF_LOG_ERROR
, "No vectored handler present"); } while (0)
;
536 ret = RPCSVC_ACTOR_ERROR(-1);
537 goto err_reply;
538 }
539
540 if (req->synctask) {
541 if (msg->hdr_iobuf)
542 req->hdr_iobuf = iobuf_ref (msg->hdr_iobuf);
543
544 ret = synctask_new (THIS(*__glusterfs_this_location())->ctx->env,
545 (synctask_fn_t) actor_fn,
546 rpcsvc_check_and_reply_error, NULL((void*)0),
547 req);
548 } else {
549 ret = actor_fn (req);
550 req->hdr_iobuf = NULL((void*)0);
551 }
552 }
553
554err_reply:
555
556 ret = rpcsvc_check_and_reply_error (ret, NULL((void*)0), req);
Value stored to 'ret' is never read
557 /* No need to propagate error beyond this function since the reply
558 * has now been queued. */
559 ret = 0;
560
561err:
562 return ret;
563}
564
565
566int
567rpcsvc_handle_disconnect (rpcsvc_t *svc, rpc_transport_t *trans)
568{
569 rpcsvc_event_t event;
570 rpcsvc_notify_wrapper_t *wrappers = NULL((void*)0), *wrapper;
571 int32_t ret = -1, i = 0, wrapper_count = 0;
572 rpcsvc_listener_t *listener = NULL((void*)0);
573
574 event = (trans->listener == NULL((void*)0)) ? RPCSVC_EVENT_LISTENER_DEAD
575 : RPCSVC_EVENT_DISCONNECT;
576
577 pthread_mutex_lock (&svc->rpclock);
578 {
579 if (!svc->notify_count)
580 goto unlock;
581
582 wrappers = GF_CALLOC (svc->notify_count, sizeof (*wrapper),__gf_calloc (svc->notify_count, sizeof (*wrapper), gf_common_mt_rpcsvc_wrapper_t
)
583 gf_common_mt_rpcsvc_wrapper_t)__gf_calloc (svc->notify_count, sizeof (*wrapper), gf_common_mt_rpcsvc_wrapper_t
)
;
584 if (!wrappers) {
585 goto unlock;
586 }
587
588 list_for_each_entry (wrapper, &svc->notify, list)for (wrapper = ((typeof(*wrapper) *)((char *)((&svc->notify
)->next)-(unsigned long)(&((typeof(*wrapper) *)0)->
list))); &wrapper->list != (&svc->notify); wrapper
= ((typeof(*wrapper) *)((char *)(wrapper->list.next)-(unsigned
long)(&((typeof(*wrapper) *)0)->list))))
{
589 if (wrapper->notify) {
590 wrappers[i++] = *wrapper;
591 }
592 }
593
594 wrapper_count = i;
595 }
596unlock:
597 pthread_mutex_unlock (&svc->rpclock);
598
599 if (wrappers) {
600 for (i = 0; i < wrapper_count; i++) {
601 wrappers[i].notify (svc, wrappers[i].data,
602 event, trans);
603 }
604
605 GF_FREE (wrappers)__gf_free (wrappers);
606 }
607
608 if (event == RPCSVC_EVENT_LISTENER_DEAD) {
609 listener = rpcsvc_get_listener (svc, -1, trans->listener);
610 rpcsvc_listener_destroy (listener);
611 }
612
613 return ret;
614}
615
616
617int
618rpcsvc_notify (rpc_transport_t *trans, void *mydata,
619 rpc_transport_event_t event, void *data, ...)
620{
621 int ret = -1;
622 rpc_transport_pollin_t *msg = NULL((void*)0);
623 rpc_transport_t *new_trans = NULL((void*)0);
624 rpcsvc_t *svc = NULL((void*)0);
625 rpcsvc_listener_t *listener = NULL((void*)0);
626
627 svc = mydata;
628 if (svc == NULL((void*)0)) {
629 goto out;
630 }
631
632 switch (event) {
633 case RPC_TRANSPORT_ACCEPT:
634 new_trans = data;
635 ret = rpcsvc_accept (svc, trans, new_trans);
636 break;
637
638 case RPC_TRANSPORT_DISCONNECT:
639 ret = rpcsvc_handle_disconnect (svc, trans);
640 break;
641
642 case RPC_TRANSPORT_MSG_RECEIVED:
643 msg = data;
644 ret = rpcsvc_handle_rpc_call (svc, trans, msg);
645 break;
646
647 case RPC_TRANSPORT_MSG_SENT:
648 ret = 0;
649 break;
650
651 case RPC_TRANSPORT_CONNECT:
652 /* do nothing, no need for rpcsvc to handle this, client should
653 * handle this event
654 */
655 /* print info about transport too : LOG TODO */
656 gf_log ("rpcsvc", GF_LOG_CRITICAL,do { do { if (0) printf ("got CONNECT event, which should have not come"
); } while (0); _gf_log ("rpcsvc", "rpcsvc.c", __FUNCTION__, 657
, GF_LOG_CRITICAL, "got CONNECT event, which should have not come"
); } while (0)
657 "got CONNECT event, which should have not come")do { do { if (0) printf ("got CONNECT event, which should have not come"
); } while (0); _gf_log ("rpcsvc", "rpcsvc.c", __FUNCTION__, 657
, GF_LOG_CRITICAL, "got CONNECT event, which should have not come"
); } while (0)
;
658 ret = 0;
659 break;
660
661 case RPC_TRANSPORT_CLEANUP:
662 listener = rpcsvc_get_listener (svc, -1, trans->listener);
663 if (listener == NULL((void*)0)) {
664 goto out;
665 }
666
667 rpcsvc_program_notify (listener, RPCSVC_EVENT_TRANSPORT_DESTROY,
668 trans);
669 ret = 0;
670 break;
671
672 case RPC_TRANSPORT_MAP_XID_REQUEST:
673 /* FIXME: think about this later */
674 gf_log ("rpcsvc", GF_LOG_CRITICAL,do { do { if (0) printf ("got MAP_XID event, which should have not come"
); } while (0); _gf_log ("rpcsvc", "rpcsvc.c", __FUNCTION__, 675
, GF_LOG_CRITICAL, "got MAP_XID event, which should have not come"
); } while (0)
675 "got MAP_XID event, which should have not come")do { do { if (0) printf ("got MAP_XID event, which should have not come"
); } while (0); _gf_log ("rpcsvc", "rpcsvc.c", __FUNCTION__, 675
, GF_LOG_CRITICAL, "got MAP_XID event, which should have not come"
); } while (0)
;
676 ret = 0;
677 break;
678 }
679
680out:
681 return ret;
682}
683
684
685/* Given the RPC reply structure and the payload handed by the RPC program,
686 * encode the RPC record header into the buffer pointed by recordstart.
687 */
688struct iovec
689rpcsvc_record_build_header (char *recordstart, size_t rlen,
690 struct rpc_msg reply, size_t payload)
691{
692 struct iovec replyhdr;
693 struct iovec txrecord = {0, 0};
694 size_t fraglen = 0;
695 int ret = -1;
696
697 /* After leaving aside the 4 bytes for the fragment header, lets
698 * encode the RPC reply structure into the buffer given to us.
699 */
700 ret = rpc_reply_to_xdr (&reply, recordstart, rlen, &replyhdr);
701 if (ret == -1) {
702 gf_log (GF_RPCSVC, GF_LOG_WARNING, "Failed to create RPC reply")do { do { if (0) printf ("Failed to create RPC reply"); } while
(0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__, 702, GF_LOG_WARNING
, "Failed to create RPC reply"); } while (0)
;
703 goto err;
704 }
705
706 fraglen = payload + replyhdr.iov_len;
707 gf_log (GF_RPCSVC, GF_LOG_TRACE, "Reply fraglen %zu, payload: %zu, "do { do { if (0) printf ("Reply fraglen %zu, payload: %zu, " "rpc hdr: %zu"
, fraglen, payload, replyhdr.iov_len); } while (0); _gf_log (
"rpc-service", "rpcsvc.c", __FUNCTION__, 708, GF_LOG_TRACE, "Reply fraglen %zu, payload: %zu, "
"rpc hdr: %zu", fraglen, payload, replyhdr.iov_len); } while
(0)
708 "rpc hdr: %zu", fraglen, payload, replyhdr.iov_len)do { do { if (0) printf ("Reply fraglen %zu, payload: %zu, " "rpc hdr: %zu"
, fraglen, payload, replyhdr.iov_len); } while (0); _gf_log (
"rpc-service", "rpcsvc.c", __FUNCTION__, 708, GF_LOG_TRACE, "Reply fraglen %zu, payload: %zu, "
"rpc hdr: %zu", fraglen, payload, replyhdr.iov_len); } while
(0)
;
709
710 txrecord.iov_base = recordstart;
711
712 /* Remember, this is only the vec for the RPC header and does not
713 * include the payload above. We needed the payload only to calculate
714 * the size of the full fragment. This size is sent in the fragment
715 * header.
716 */
717 txrecord.iov_len = replyhdr.iov_len;
718err:
719 return txrecord;
720}
721
722static inline int
723rpcsvc_get_callid (rpcsvc_t *rpc)
724{
725 return GF_UNIVERSAL_ANSWER42;
726}
727
728int
729rpcsvc_fill_callback (int prognum, int progver, int procnum, int payload,
730 uint64_t xid, struct rpc_msg *request)
731{
732 int ret = -1;
733
734 if (!request) {
735 goto out;
736 }
737
738 memset (request, 0, sizeof (*request));
739
740 request->rm_xid = xid;
741 request->rm_direction = CALL;
742
743 request->rm_callru.RM_cmb.cb_rpcvers = 2;
744 request->rm_callru.RM_cmb.cb_prog = prognum;
745 request->rm_callru.RM_cmb.cb_vers = progver;
746 request->rm_callru.RM_cmb.cb_proc = procnum;
747
748 request->rm_callru.RM_cmb.cb_cred.oa_flavor = AUTH_NONE0;
749 request->rm_callru.RM_cmb.cb_cred.oa_base = NULL((void*)0);
750 request->rm_callru.RM_cmb.cb_cred.oa_length = 0;
751
752 request->rm_callru.RM_cmb.cb_verf.oa_flavor = AUTH_NONE0;
753 request->rm_callru.RM_cmb.cb_verf.oa_base = NULL((void*)0);
754 request->rm_callru.RM_cmb.cb_verf.oa_length = 0;
755
756 ret = 0;
757out:
758 return ret;
759}
760
761
762struct iovec
763rpcsvc_callback_build_header (char *recordstart, size_t rlen,
764 struct rpc_msg *request, size_t payload)
765{
766 struct iovec requesthdr = {0, };
767 struct iovec txrecord = {0, 0};
768 int ret = -1;
769 size_t fraglen = 0;
770
771 ret = rpc_request_to_xdr (request, recordstart, rlen, &requesthdr);
772 if (ret == -1) {
773 gf_log ("rpcsvc", GF_LOG_WARNING,do { do { if (0) printf ("Failed to create RPC request"); } while
(0); _gf_log ("rpcsvc", "rpcsvc.c", __FUNCTION__, 774, GF_LOG_WARNING
, "Failed to create RPC request"); } while (0)
774 "Failed to create RPC request")do { do { if (0) printf ("Failed to create RPC request"); } while
(0); _gf_log ("rpcsvc", "rpcsvc.c", __FUNCTION__, 774, GF_LOG_WARNING
, "Failed to create RPC request"); } while (0)
;
775 goto out;
776 }
777
778 fraglen = payload + requesthdr.iov_len;
779 gf_log ("rpcsvc", GF_LOG_TRACE, "Request fraglen %zu, payload: %zu, "do { do { if (0) printf ("Request fraglen %zu, payload: %zu, "
"rpc hdr: %zu", fraglen, payload, requesthdr.iov_len); } while
(0); _gf_log ("rpcsvc", "rpcsvc.c", __FUNCTION__, 780, GF_LOG_TRACE
, "Request fraglen %zu, payload: %zu, " "rpc hdr: %zu", fraglen
, payload, requesthdr.iov_len); } while (0)
780 "rpc hdr: %zu", fraglen, payload, requesthdr.iov_len)do { do { if (0) printf ("Request fraglen %zu, payload: %zu, "
"rpc hdr: %zu", fraglen, payload, requesthdr.iov_len); } while
(0); _gf_log ("rpcsvc", "rpcsvc.c", __FUNCTION__, 780, GF_LOG_TRACE
, "Request fraglen %zu, payload: %zu, " "rpc hdr: %zu", fraglen
, payload, requesthdr.iov_len); } while (0)
;
781
782 txrecord.iov_base = recordstart;
783
784 /* Remember, this is only the vec for the RPC header and does not
785 * include the payload above. We needed the payload only to calculate
786 * the size of the full fragment. This size is sent in the fragment
787 * header.
788 */
789 txrecord.iov_len = requesthdr.iov_len;
790
791out:
792 return txrecord;
793}
794
795struct iobuf *
796rpcsvc_callback_build_record (rpcsvc_t *rpc, int prognum, int progver,
797 int procnum, size_t payload, uint64_t xid,
798 struct iovec *recbuf)
799{
800 struct rpc_msg request = {0, };
801 struct iobuf *request_iob = NULL((void*)0);
802 char *record = NULL((void*)0);
803 struct iovec recordhdr = {0, };
804 size_t pagesize = 0;
805 size_t xdr_size = 0;
806 int ret = -1;
807
808 if ((!rpc) || (!recbuf)) {
809 goto out;
810 }
811
812 /* Fill the rpc structure and XDR it into the buffer got above. */
813 ret = rpcsvc_fill_callback (prognum, progver, procnum, payload, xid,
814 &request);
815 if (ret == -1) {
816 gf_log ("rpcsvc", GF_LOG_WARNING, "cannot build a rpc-request "do { do { if (0) printf ("cannot build a rpc-request " "xid (%"
"ll" "u"")", xid); } while (0); _gf_log ("rpcsvc", "rpcsvc.c"
, __FUNCTION__, 817, GF_LOG_WARNING, "cannot build a rpc-request "
"xid (%""ll" "u"")", xid); } while (0)
817 "xid (%"PRIu64")", xid)do { do { if (0) printf ("cannot build a rpc-request " "xid (%"
"ll" "u"")", xid); } while (0); _gf_log ("rpcsvc", "rpcsvc.c"
, __FUNCTION__, 817, GF_LOG_WARNING, "cannot build a rpc-request "
"xid (%""ll" "u"")", xid); } while (0)
;
818 goto out;
819 }
820
821 /* First, try to get a pointer into the buffer which the RPC
822 * layer can use.
823 */
824 xdr_size = xdr_sizeof ((xdrproc_t)xdr_callmsg, &request);
825
826 request_iob = iobuf_get2 (rpc->ctx->iobuf_pool, (xdr_size + payload));
827 if (!request_iob) {
828 goto out;
829 }
830
831 pagesize = iobuf_pagesize (request_iob)(request_iob->iobuf_arena->page_size);
832
833 record = iobuf_ptr (request_iob)((request_iob)->ptr); /* Now we have it. */
834
835 recordhdr = rpcsvc_callback_build_header (record, pagesize, &request,
836 payload);
837
838 if (!recordhdr.iov_base) {
839 gf_log ("rpc-clnt", GF_LOG_ERROR, "Failed to build record "do { do { if (0) printf ("Failed to build record " " header")
; } while (0); _gf_log ("rpc-clnt", "rpcsvc.c", __FUNCTION__,
840, GF_LOG_ERROR, "Failed to build record " " header"); } while
(0)
840 " header")do { do { if (0) printf ("Failed to build record " " header")
; } while (0); _gf_log ("rpc-clnt", "rpcsvc.c", __FUNCTION__,
840, GF_LOG_ERROR, "Failed to build record " " header"); } while
(0)
;
841 iobuf_unref (request_iob);
842 request_iob = NULL((void*)0);
843 recbuf->iov_base = NULL((void*)0);
844 goto out;
845 }
846
847 recbuf->iov_base = recordhdr.iov_base;
848 recbuf->iov_len = recordhdr.iov_len;
849
850out:
851 return request_iob;
852}
853
854int
855rpcsvc_callback_submit (rpcsvc_t *rpc, rpc_transport_t *trans,
856 rpcsvc_cbk_program_t *prog, int procnum,
857 struct iovec *proghdr, int proghdrcount)
858{
859 struct iobuf *request_iob = NULL((void*)0);
860 struct iovec rpchdr = {0,};
861 rpc_transport_req_t req;
862 int ret = -1;
863 int proglen = 0;
864 uint64_t callid = 0;
865
866 if (!rpc) {
867 goto out;
868 }
869
870 memset (&req, 0, sizeof (req));
871
872 callid = rpcsvc_get_callid (rpc);
873
874 if (proghdr) {
875 proglen += iov_length (proghdr, proghdrcount);
876 }
877
878 request_iob = rpcsvc_callback_build_record (rpc, prog->prognum,
879 prog->progver, procnum,
880 proglen, callid,
881 &rpchdr);
882 if (!request_iob) {
883 gf_log ("rpcsvc", GF_LOG_WARNING,do { do { if (0) printf ("cannot build rpc-record"); } while (
0); _gf_log ("rpcsvc", "rpcsvc.c", __FUNCTION__, 884, GF_LOG_WARNING
, "cannot build rpc-record"); } while (0)
884 "cannot build rpc-record")do { do { if (0) printf ("cannot build rpc-record"); } while (
0); _gf_log ("rpcsvc", "rpcsvc.c", __FUNCTION__, 884, GF_LOG_WARNING
, "cannot build rpc-record"); } while (0)
;
885 goto out;
886 }
887
888 req.msg.rpchdr = &rpchdr;
889 req.msg.rpchdrcount = 1;
890 req.msg.proghdr = proghdr;
891 req.msg.proghdrcount = proghdrcount;
892
893 ret = rpc_transport_submit_request (trans, &req);
894 if (ret == -1) {
895 gf_log ("rpcsvc", GF_LOG_WARNING,do { do { if (0) printf ("transmission of rpc-request failed"
); } while (0); _gf_log ("rpcsvc", "rpcsvc.c", __FUNCTION__, 896
, GF_LOG_WARNING, "transmission of rpc-request failed"); } while
(0)
896 "transmission of rpc-request failed")do { do { if (0) printf ("transmission of rpc-request failed"
); } while (0); _gf_log ("rpcsvc", "rpcsvc.c", __FUNCTION__, 896
, GF_LOG_WARNING, "transmission of rpc-request failed"); } while
(0)
;
897 goto out;
898 }
899
900 ret = 0;
901
902out:
903 iobuf_unref (request_iob);
904
905 return ret;
906}
907
908static inline int
909rpcsvc_transport_submit (rpc_transport_t *trans, struct iovec *hdrvec,
910 int hdrcount, struct iovec *proghdr, int proghdrcount,
911 struct iovec *progpayload, int progpayloadcount,
912 struct iobref *iobref, void *priv)
913{
914 int ret = -1;
915 rpc_transport_reply_t reply = {{0, }};
916
917 if ((!trans) || (!hdrvec) || (!hdrvec->iov_base)) {
918 goto out;
919 }
920
921 reply.msg.rpchdr = hdrvec;
922 reply.msg.rpchdrcount = hdrcount;
923 reply.msg.proghdr = proghdr;
924 reply.msg.proghdrcount = proghdrcount;
925 reply.msg.progpayload = progpayload;
926 reply.msg.progpayloadcount = progpayloadcount;
927 reply.msg.iobref = iobref;
928 reply.private = priv;
929
930 ret = rpc_transport_submit_reply (trans, &reply);
931
932out:
933 return ret;
934}
935
936
937int
938rpcsvc_fill_reply (rpcsvc_request_t *req, struct rpc_msg *reply)
939{
940 int ret = -1;
941 rpcsvc_program_t *prog = NULL((void*)0);
942 if ((!req) || (!reply))
943 goto out;
944
945 ret = 0;
946 rpc_fill_empty_reply (reply, req->xid);
947 if (req->rpc_status == MSG_DENIED) {
948 rpc_fill_denied_reply (reply, req->rpc_err, req->auth_err);
949 goto out;
950 }
951
952 prog = rpcsvc_request_program (req)((rpcsvc_program_t *)((req)->prog));
953
954 if (req->rpc_status == MSG_ACCEPTED)
955 rpc_fill_accepted_reply (reply, req->rpc_err,
956 (prog) ? prog->proglowvers : 0,
957 (prog) ? prog->proghighvers: 0,
958 req->verf.flavour, req->verf.datalen,
959 req->verf.authdata);
960 else
961 gf_log (GF_RPCSVC, GF_LOG_ERROR, "Invalid rpc_status value")do { do { if (0) printf ("Invalid rpc_status value"); } while
(0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__, 961, GF_LOG_ERROR
, "Invalid rpc_status value"); } while (0)
;
962
963out:
964 return ret;
965}
966
967
968/* Given a request and the reply payload, build a reply and encodes the reply
969 * into a record header. This record header is encoded into the vector pointed
970 * to be recbuf.
971 * msgvec is the buffer that points to the payload of the RPC program.
972 * This buffer can be NULL, if an RPC error reply is being constructed.
973 * The only reason it is needed here is that in case the buffer is provided,
974 * we should account for the length of that buffer in the RPC fragment header.
975 */
976struct iobuf *
977rpcsvc_record_build_record (rpcsvc_request_t *req, size_t payload,
978 size_t hdrlen, struct iovec *recbuf)
979{
980 struct rpc_msg reply;
981 struct iobuf *replyiob = NULL((void*)0);
982 char *record = NULL((void*)0);
983 struct iovec recordhdr = {0, };
984 size_t pagesize = 0;
985 size_t xdr_size = 0;
986 rpcsvc_t *svc = NULL((void*)0);
987 int ret = -1;
988
989 if ((!req) || (!req->trans) || (!req->svc) || (!recbuf))
990 return NULL((void*)0);
991
992 svc = req->svc;
993
994 /* Fill the rpc structure and XDR it into the buffer got above. */
995 ret = rpcsvc_fill_reply (req, &reply);
996 if (ret)
997 goto err_exit;
998
999 xdr_size = xdr_sizeof ((xdrproc_t)xdr_replymsg, &reply);
1000
1001 /* Payload would include 'readv' size etc too, where as
1002 that comes as another payload iobuf */
1003 replyiob = iobuf_get2 (svc->ctx->iobuf_pool, (xdr_size + hdrlen));
1004 if (!replyiob) {
1005 goto err_exit;
1006 }
1007
1008 pagesize = iobuf_pagesize (replyiob)(replyiob->iobuf_arena->page_size);
1009
1010 record = iobuf_ptr (replyiob)((replyiob)->ptr); /* Now we have it. */
1011
1012 recordhdr = rpcsvc_record_build_header (record, pagesize, reply,
1013 payload);
1014 if (!recordhdr.iov_base) {
1015 gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to build record "do { do { if (0) printf ("Failed to build record " " header")
; } while (0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__
, 1016, GF_LOG_ERROR, "Failed to build record " " header"); }
while (0)
1016 " header")do { do { if (0) printf ("Failed to build record " " header")
; } while (0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__
, 1016, GF_LOG_ERROR, "Failed to build record " " header"); }
while (0)
;
1017 iobuf_unref (replyiob);
1018 replyiob = NULL((void*)0);
1019 recbuf->iov_base = NULL((void*)0);
1020 goto err_exit;
1021 }
1022
1023 recbuf->iov_base = recordhdr.iov_base;
1024 recbuf->iov_len = recordhdr.iov_len;
1025err_exit:
1026 return replyiob;
1027}
1028
1029
1030/*
1031 * The function to submit a program message to the RPC service.
1032 * This message is added to the transmission queue of the
1033 * conn.
1034 *
1035 * Program callers are not expected to use the msgvec->iov_base
1036 * address for anything else.
1037 * Nor are they expected to free it once this function returns.
1038 * Once the transmission of the buffer is completed by the RPC service,
1039 * the memory area as referenced through @msg will be unrefed.
1040 * If a higher layer does not want anything to do with this iobuf
1041 * after this function returns, it should call unref on it. For keeping
1042 * it around till the transmission is actually complete, rpcsvc also refs it.
1043 * *
1044 * If this function returns an error by returning -1, the
1045 * higher layer programs should assume that a disconnection happened
1046 * and should know that the conn memory area as well as the req structure
1047 * has been freed internally.
1048 *
1049 * For now, this function assumes that a submit is always called
1050 * to send a new record. Later, if there is a situation where different
1051 * buffers for the same record come from different sources, then we'll
1052 * need to change this code to account for multiple submit calls adding
1053 * the buffers into a single record.
1054 */
1055
1056int
1057rpcsvc_submit_generic (rpcsvc_request_t *req, struct iovec *proghdr,
1058 int hdrcount, struct iovec *payload, int payloadcount,
1059 struct iobref *iobref)
1060{
1061 int ret = -1, i = 0;
1062 struct iobuf *replyiob = NULL((void*)0);
1063 struct iovec recordhdr = {0, };
1064 rpc_transport_t *trans = NULL((void*)0);
1065 size_t msglen = 0;
1066 size_t hdrlen = 0;
1067 char new_iobref = 0;
1068
1069 if ((!req) || (!req->trans))
1070 return -1;
1071
1072 trans = req->trans;
1073
1074 for (i = 0; i < hdrcount; i++) {
1075 msglen += proghdr[i].iov_len;
1076 }
1077
1078 for (i = 0; i < payloadcount; i++) {
1079 msglen += payload[i].iov_len;
1080 }
1081
1082 gf_log (GF_RPCSVC, GF_LOG_TRACE, "Tx message: %zu", msglen)do { do { if (0) printf ("Tx message: %zu", msglen); } while (
0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__, 1082, GF_LOG_TRACE
, "Tx message: %zu", msglen); } while (0)
;
1083
1084 /* Build the buffer containing the encoded RPC reply. */
1085 replyiob = rpcsvc_record_build_record (req, msglen, hdrlen, &recordhdr);
1086 if (!replyiob) {
1087 gf_log (GF_RPCSVC, GF_LOG_ERROR,"Reply record creation failed")do { do { if (0) printf ("Reply record creation failed"); } while
(0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__, 1087,
GF_LOG_ERROR,"Reply record creation failed"); } while (0)
;
1088 goto disconnect_exit;
1089 }
1090
1091 if (!iobref) {
1092 iobref = iobref_new ();
1093 if (!iobref) {
1094 goto disconnect_exit;
1095 }
1096
1097 new_iobref = 1;
1098 }
1099
1100 iobref_add (iobref, replyiob);
1101
1102 ret = rpcsvc_transport_submit (trans, &recordhdr, 1, proghdr, hdrcount,
1103 payload, payloadcount, iobref,
1104 req->trans_private);
1105
1106 if (ret == -1) {
1107 gf_log (GF_RPCSVC, GF_LOG_ERROR, "failed to submit message "do { do { if (0) printf ("failed to submit message " "(XID: 0x%ux, Program: %s, ProgVers: %d, Proc: %d) to "
"rpc-transport (%s)", req->xid, req->prog ? req->prog
->progname : "(not matched)", req->prog ? req->prog->
progver : 0, req->procnum, trans->name); } while (0); _gf_log
("rpc-service", "rpcsvc.c", __FUNCTION__, 1112, GF_LOG_ERROR
, "failed to submit message " "(XID: 0x%ux, Program: %s, ProgVers: %d, Proc: %d) to "
"rpc-transport (%s)", req->xid, req->prog ? req->prog
->progname : "(not matched)", req->prog ? req->prog->
progver : 0, req->procnum, trans->name); } while (0)
1108 "(XID: 0x%ux, Program: %s, ProgVers: %d, Proc: %d) to "do { do { if (0) printf ("failed to submit message " "(XID: 0x%ux, Program: %s, ProgVers: %d, Proc: %d) to "
"rpc-transport (%s)", req->xid, req->prog ? req->prog
->progname : "(not matched)", req->prog ? req->prog->
progver : 0, req->procnum, trans->name); } while (0); _gf_log
("rpc-service", "rpcsvc.c", __FUNCTION__, 1112, GF_LOG_ERROR
, "failed to submit message " "(XID: 0x%ux, Program: %s, ProgVers: %d, Proc: %d) to "
"rpc-transport (%s)", req->xid, req->prog ? req->prog
->progname : "(not matched)", req->prog ? req->prog->
progver : 0, req->procnum, trans->name); } while (0)
1109 "rpc-transport (%s)", req->xid,do { do { if (0) printf ("failed to submit message " "(XID: 0x%ux, Program: %s, ProgVers: %d, Proc: %d) to "
"rpc-transport (%s)", req->xid, req->prog ? req->prog
->progname : "(not matched)", req->prog ? req->prog->
progver : 0, req->procnum, trans->name); } while (0); _gf_log
("rpc-service", "rpcsvc.c", __FUNCTION__, 1112, GF_LOG_ERROR
, "failed to submit message " "(XID: 0x%ux, Program: %s, ProgVers: %d, Proc: %d) to "
"rpc-transport (%s)", req->xid, req->prog ? req->prog
->progname : "(not matched)", req->prog ? req->prog->
progver : 0, req->procnum, trans->name); } while (0)
1110 req->prog ? req->prog->progname : "(not matched)",do { do { if (0) printf ("failed to submit message " "(XID: 0x%ux, Program: %s, ProgVers: %d, Proc: %d) to "
"rpc-transport (%s)", req->xid, req->prog ? req->prog
->progname : "(not matched)", req->prog ? req->prog->
progver : 0, req->procnum, trans->name); } while (0); _gf_log
("rpc-service", "rpcsvc.c", __FUNCTION__, 1112, GF_LOG_ERROR
, "failed to submit message " "(XID: 0x%ux, Program: %s, ProgVers: %d, Proc: %d) to "
"rpc-transport (%s)", req->xid, req->prog ? req->prog
->progname : "(not matched)", req->prog ? req->prog->
progver : 0, req->procnum, trans->name); } while (0)
1111 req->prog ? req->prog->progver : 0,do { do { if (0) printf ("failed to submit message " "(XID: 0x%ux, Program: %s, ProgVers: %d, Proc: %d) to "
"rpc-transport (%s)", req->xid, req->prog ? req->prog
->progname : "(not matched)", req->prog ? req->prog->
progver : 0, req->procnum, trans->name); } while (0); _gf_log
("rpc-service", "rpcsvc.c", __FUNCTION__, 1112, GF_LOG_ERROR
, "failed to submit message " "(XID: 0x%ux, Program: %s, ProgVers: %d, Proc: %d) to "
"rpc-transport (%s)", req->xid, req->prog ? req->prog
->progname : "(not matched)", req->prog ? req->prog->
progver : 0, req->procnum, trans->name); } while (0)
1112 req->procnum, trans->name)do { do { if (0) printf ("failed to submit message " "(XID: 0x%ux, Program: %s, ProgVers: %d, Proc: %d) to "
"rpc-transport (%s)", req->xid, req->prog ? req->prog
->progname : "(not matched)", req->prog ? req->prog->
progver : 0, req->procnum, trans->name); } while (0); _gf_log
("rpc-service", "rpcsvc.c", __FUNCTION__, 1112, GF_LOG_ERROR
, "failed to submit message " "(XID: 0x%ux, Program: %s, ProgVers: %d, Proc: %d) to "
"rpc-transport (%s)", req->xid, req->prog ? req->prog
->progname : "(not matched)", req->prog ? req->prog->
progver : 0, req->procnum, trans->name); } while (0)
;
1113 } else {
1114 gf_log (GF_RPCSVC, GF_LOG_TRACE,do { do { if (0) printf ("submitted reply for rpc-message (XID: 0x%ux, "
"Program: %s, ProgVers: %d, Proc: %d) to rpc-transport " "(%s)"
, req->xid, req->prog ? req->prog->progname: "-",
req->prog ? req->prog->progver : 0, req->procnum
, trans->name); } while (0); _gf_log ("rpc-service", "rpcsvc.c"
, __FUNCTION__, 1119, GF_LOG_TRACE, "submitted reply for rpc-message (XID: 0x%ux, "
"Program: %s, ProgVers: %d, Proc: %d) to rpc-transport " "(%s)"
, req->xid, req->prog ? req->prog->progname: "-",
req->prog ? req->prog->progver : 0, req->procnum
, trans->name); } while (0)
1115 "submitted reply for rpc-message (XID: 0x%ux, "do { do { if (0) printf ("submitted reply for rpc-message (XID: 0x%ux, "
"Program: %s, ProgVers: %d, Proc: %d) to rpc-transport " "(%s)"
, req->xid, req->prog ? req->prog->progname: "-",
req->prog ? req->prog->progver : 0, req->procnum
, trans->name); } while (0); _gf_log ("rpc-service", "rpcsvc.c"
, __FUNCTION__, 1119, GF_LOG_TRACE, "submitted reply for rpc-message (XID: 0x%ux, "
"Program: %s, ProgVers: %d, Proc: %d) to rpc-transport " "(%s)"
, req->xid, req->prog ? req->prog->progname: "-",
req->prog ? req->prog->progver : 0, req->procnum
, trans->name); } while (0)
1116 "Program: %s, ProgVers: %d, Proc: %d) to rpc-transport "do { do { if (0) printf ("submitted reply for rpc-message (XID: 0x%ux, "
"Program: %s, ProgVers: %d, Proc: %d) to rpc-transport " "(%s)"
, req->xid, req->prog ? req->prog->progname: "-",
req->prog ? req->prog->progver : 0, req->procnum
, trans->name); } while (0); _gf_log ("rpc-service", "rpcsvc.c"
, __FUNCTION__, 1119, GF_LOG_TRACE, "submitted reply for rpc-message (XID: 0x%ux, "
"Program: %s, ProgVers: %d, Proc: %d) to rpc-transport " "(%s)"
, req->xid, req->prog ? req->prog->progname: "-",
req->prog ? req->prog->progver : 0, req->procnum
, trans->name); } while (0)
1117 "(%s)", req->xid, req->prog ? req->prog->progname: "-",do { do { if (0) printf ("submitted reply for rpc-message (XID: 0x%ux, "
"Program: %s, ProgVers: %d, Proc: %d) to rpc-transport " "(%s)"
, req->xid, req->prog ? req->prog->progname: "-",
req->prog ? req->prog->progver : 0, req->procnum
, trans->name); } while (0); _gf_log ("rpc-service", "rpcsvc.c"
, __FUNCTION__, 1119, GF_LOG_TRACE, "submitted reply for rpc-message (XID: 0x%ux, "
"Program: %s, ProgVers: %d, Proc: %d) to rpc-transport " "(%s)"
, req->xid, req->prog ? req->prog->progname: "-",
req->prog ? req->prog->progver : 0, req->procnum
, trans->name); } while (0)
1118 req->prog ? req->prog->progver : 0,do { do { if (0) printf ("submitted reply for rpc-message (XID: 0x%ux, "
"Program: %s, ProgVers: %d, Proc: %d) to rpc-transport " "(%s)"
, req->xid, req->prog ? req->prog->progname: "-",
req->prog ? req->prog->progver : 0, req->procnum
, trans->name); } while (0); _gf_log ("rpc-service", "rpcsvc.c"
, __FUNCTION__, 1119, GF_LOG_TRACE, "submitted reply for rpc-message (XID: 0x%ux, "
"Program: %s, ProgVers: %d, Proc: %d) to rpc-transport " "(%s)"
, req->xid, req->prog ? req->prog->progname: "-",
req->prog ? req->prog->progver : 0, req->procnum
, trans->name); } while (0)
1119 req->procnum, trans->name)do { do { if (0) printf ("submitted reply for rpc-message (XID: 0x%ux, "
"Program: %s, ProgVers: %d, Proc: %d) to rpc-transport " "(%s)"
, req->xid, req->prog ? req->prog->progname: "-",
req->prog ? req->prog->progver : 0, req->procnum
, trans->name); } while (0); _gf_log ("rpc-service", "rpcsvc.c"
, __FUNCTION__, 1119, GF_LOG_TRACE, "submitted reply for rpc-message (XID: 0x%ux, "
"Program: %s, ProgVers: %d, Proc: %d) to rpc-transport " "(%s)"
, req->xid, req->prog ? req->prog->progname: "-",
req->prog ? req->prog->progver : 0, req->procnum
, trans->name); } while (0)
;
1120 }
1121
1122disconnect_exit:
1123 if (replyiob) {
1124 iobuf_unref (replyiob);
1125 }
1126
1127 if (new_iobref) {
1128 iobref_unref (iobref);
1129 }
1130
1131 rpcsvc_request_destroy (req);
1132
1133 return ret;
1134}
1135
1136
1137int
1138rpcsvc_error_reply (rpcsvc_request_t *req)
1139{
1140 struct iovec dummyvec = {0, };
1141
1142 if (!req)
1143 return -1;
1144
1145 gf_log_callingfn ("", GF_LOG_DEBUG, "sending a RPC error reply")do { do { if (0) printf ("sending a RPC error reply"); } while
(0); _gf_log_callingfn ("", "rpcsvc.c", __FUNCTION__, 1145, GF_LOG_DEBUG
, "sending a RPC error reply"); } while (0)
;
1146
1147 /* At this point the req should already have been filled with the
1148 * appropriate RPC error numbers.
1149 */
1150 return rpcsvc_submit_generic (req, &dummyvec, 0, NULL((void*)0), 0, NULL((void*)0));
1151}
1152
1153
1154/* Register the program with the local portmapper service. */
1155inline int
1156rpcsvc_program_register_portmap (rpcsvc_program_t *newprog, uint32_t port)
1157{
1158 int ret = 0;
1159
1160 if (!newprog) {
1161 goto out;
1162 }
1163
1164 if (!(pmap_set (newprog->prognum, newprog->progver, IPPROTO_TCPIPPROTO_TCP,
1165 port))) {
1166 gf_log (GF_RPCSVC, GF_LOG_ERROR, "Could not register with"do { do { if (0) printf ("Could not register with" " portmap"
); } while (0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__
, 1167, GF_LOG_ERROR, "Could not register with" " portmap"); }
while (0)
1167 " portmap")do { do { if (0) printf ("Could not register with" " portmap"
); } while (0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__
, 1167, GF_LOG_ERROR, "Could not register with" " portmap"); }
while (0)
;
1168 goto out;
1169 }
1170
1171 ret = 0;
1172out:
1173 return ret;
1174}
1175
1176
1177static inline int
1178rpcsvc_program_unregister_portmap (rpcsvc_program_t *prog)
1179{
1180 int ret = 0;
1181
1182 if (!prog)
1183 goto out;
1184
1185 if (!(pmap_unset(prog->prognum, prog->progver))) {
1186 gf_log (GF_RPCSVC, GF_LOG_ERROR, "Could not unregister with"do { do { if (0) printf ("Could not unregister with" " portmap"
); } while (0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__
, 1187, GF_LOG_ERROR, "Could not unregister with" " portmap")
; } while (0)
1187 " portmap")do { do { if (0) printf ("Could not unregister with" " portmap"
); } while (0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__
, 1187, GF_LOG_ERROR, "Could not unregister with" " portmap")
; } while (0)
;
1188 goto out;
1189 }
1190
1191 ret = 0;
1192out:
1193 return ret;
1194}
1195
1196int
1197rpcsvc_register_portmap_enabled (rpcsvc_t *svc)
1198{
1199 return svc->register_portmap;
1200}
1201
1202int32_t
1203rpcsvc_get_listener_port (rpcsvc_listener_t *listener)
1204{
1205 int32_t listener_port = -1;
1206
1207 if ((listener == NULL((void*)0)) || (listener->trans == NULL((void*)0))) {
1208 goto out;
1209 }
1210
1211 switch (listener->trans->myinfo.sockaddr.ss_family) {
1212 case AF_INET2:
1213 listener_port = ((struct sockaddr_in *)&listener->trans->myinfo.sockaddr)->sin_port;
1214 break;
1215
1216 case AF_INET610:
1217 listener_port = ((struct sockaddr_in6 *)&listener->trans->myinfo.sockaddr)->sin6_port;
1218 break;
1219
1220 default:
1221 gf_log (GF_RPCSVC, GF_LOG_DEBUG,do { do { if (0) printf ("invalid address family (%d)", listener
->trans->myinfo.sockaddr.ss_family); } while (0); _gf_log
("rpc-service", "rpcsvc.c", __FUNCTION__, 1223, GF_LOG_DEBUG
, "invalid address family (%d)", listener->trans->myinfo
.sockaddr.ss_family); } while (0)
1222 "invalid address family (%d)",do { do { if (0) printf ("invalid address family (%d)", listener
->trans->myinfo.sockaddr.ss_family); } while (0); _gf_log
("rpc-service", "rpcsvc.c", __FUNCTION__, 1223, GF_LOG_DEBUG
, "invalid address family (%d)", listener->trans->myinfo
.sockaddr.ss_family); } while (0)
1223 listener->trans->myinfo.sockaddr.ss_family)do { do { if (0) printf ("invalid address family (%d)", listener
->trans->myinfo.sockaddr.ss_family); } while (0); _gf_log
("rpc-service", "rpcsvc.c", __FUNCTION__, 1223, GF_LOG_DEBUG
, "invalid address family (%d)", listener->trans->myinfo
.sockaddr.ss_family); } while (0)
;
1224 goto out;
1225 }
1226
1227 listener_port = ntohs (listener_port);
1228
1229out:
1230 return listener_port;
1231}
1232
1233
1234rpcsvc_listener_t *
1235rpcsvc_get_listener (rpcsvc_t *svc, uint16_t port, rpc_transport_t *trans)
1236{
1237 rpcsvc_listener_t *listener = NULL((void*)0);
1238 char found = 0;
1239 uint32_t listener_port = 0;
1240
1241 if (!svc) {
1242 goto out;
1243 }
1244
1245 pthread_mutex_lock (&svc->rpclock);
1246 {
1247 list_for_each_entry (listener, &svc->listeners, list)for (listener = ((typeof(*listener) *)((char *)((&svc->
listeners)->next)-(unsigned long)(&((typeof(*listener)
*)0)->list))); &listener->list != (&svc->listeners
); listener = ((typeof(*listener) *)((char *)(listener->list
.next)-(unsigned long)(&((typeof(*listener) *)0)->list
))))
{
1248 if (trans != NULL((void*)0)) {
1249 if (listener->trans == trans) {
1250 found = 1;
1251 break;
1252 }
1253
1254 continue;
1255 }
1256
1257 listener_port = rpcsvc_get_listener_port (listener);
1258 if (listener_port == -1) {
1259 gf_log (GF_RPCSVC, GF_LOG_ERROR,do { do { if (0) printf ("invalid port for listener %s", listener
->trans->name); } while (0); _gf_log ("rpc-service", "rpcsvc.c"
, __FUNCTION__, 1261, GF_LOG_ERROR, "invalid port for listener %s"
, listener->trans->name); } while (0)
1260 "invalid port for listener %s",do { do { if (0) printf ("invalid port for listener %s", listener
->trans->name); } while (0); _gf_log ("rpc-service", "rpcsvc.c"
, __FUNCTION__, 1261, GF_LOG_ERROR, "invalid port for listener %s"
, listener->trans->name); } while (0)
1261 listener->trans->name)do { do { if (0) printf ("invalid port for listener %s", listener
->trans->name); } while (0); _gf_log ("rpc-service", "rpcsvc.c"
, __FUNCTION__, 1261, GF_LOG_ERROR, "invalid port for listener %s"
, listener->trans->name); } while (0)
;
1262 continue;
1263 }
1264
1265 if (listener_port == port) {
1266 found = 1;
1267 break;
1268 }
1269 }
1270 }
1271 pthread_mutex_unlock (&svc->rpclock);
1272
1273 if (!found) {
1274 listener = NULL((void*)0);
1275 }
1276
1277out:
1278 return listener;
1279}
1280
1281
1282/* The only difference between the generic submit and this one is that the
1283 * generic submit is also used for submitting RPC error replies in where there
1284 * are no payloads so the msgvec and msgbuf can be NULL.
1285 * Since RPC programs should be using this function along with their payloads
1286 * we must perform NULL checks before calling the generic submit.
1287 */
1288int
1289rpcsvc_submit_message (rpcsvc_request_t *req, struct iovec *proghdr,
1290 int hdrcount, struct iovec *payload, int payloadcount,
1291 struct iobref *iobref)
1292{
1293 if ((!req) || (!req->trans) || (!proghdr) || (!proghdr->iov_base))
1294 return -1;
1295
1296 return rpcsvc_submit_generic (req, proghdr, hdrcount, payload,
1297 payloadcount, iobref);
1298}
1299
1300
1301int
1302rpcsvc_program_unregister (rpcsvc_t *svc, rpcsvc_program_t *program)
1303{
1304 int ret = -1;
1305 rpcsvc_program_t *prog = NULL((void*)0);
1306 if (!svc || !program) {
1307 goto out;
1308 }
1309
1310 ret = rpcsvc_program_unregister_portmap (program);
1311 if (ret == -1) {
1312 gf_log (GF_RPCSVC, GF_LOG_ERROR, "portmap unregistration of"do { do { if (0) printf ("portmap unregistration of" " program failed"
); } while (0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__
, 1313, GF_LOG_ERROR, "portmap unregistration of" " program failed"
); } while (0)
1313 " program failed")do { do { if (0) printf ("portmap unregistration of" " program failed"
); } while (0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__
, 1313, GF_LOG_ERROR, "portmap unregistration of" " program failed"
); } while (0)
;
1314 goto out;
1315 }
1316
1317 pthread_mutex_lock (&svc->rpclock);
1318 {
1319 list_for_each_entry (prog, &svc->programs, program)for (prog = ((typeof(*prog) *)((char *)((&svc->programs
)->next)-(unsigned long)(&((typeof(*prog) *)0)->program
))); &prog->program != (&svc->programs); prog =
((typeof(*prog) *)((char *)(prog->program.next)-(unsigned
long)(&((typeof(*prog) *)0)->program))))
{
1320 if ((prog->prognum == program->prognum)
1321 && (prog->progver == program->progver)) {
1322 break;
1323 }
1324 }
1325 }
1326 pthread_mutex_unlock (&svc->rpclock);
1327
1328 if (prog == NULL((void*)0)) {
1329 ret = -1;
1330 goto out;
1331 }
1332
1333 gf_log (GF_RPCSVC, GF_LOG_DEBUG, "Program unregistered: %s, Num: %d,"do { do { if (0) printf ("Program unregistered: %s, Num: %d,"
" Ver: %d, Port: %d", prog->progname, prog->prognum, prog
->progver, prog->progport); } while (0); _gf_log ("rpc-service"
, "rpcsvc.c", __FUNCTION__, 1335, GF_LOG_DEBUG, "Program unregistered: %s, Num: %d,"
" Ver: %d, Port: %d", prog->progname, prog->prognum, prog
->progver, prog->progport); } while (0)
1334 " Ver: %d, Port: %d", prog->progname, prog->prognum,do { do { if (0) printf ("Program unregistered: %s, Num: %d,"
" Ver: %d, Port: %d", prog->progname, prog->prognum, prog
->progver, prog->progport); } while (0); _gf_log ("rpc-service"
, "rpcsvc.c", __FUNCTION__, 1335, GF_LOG_DEBUG, "Program unregistered: %s, Num: %d,"
" Ver: %d, Port: %d", prog->progname, prog->prognum, prog
->progver, prog->progport); } while (0)
1335 prog->progver, prog->progport)do { do { if (0) printf ("Program unregistered: %s, Num: %d,"
" Ver: %d, Port: %d", prog->progname, prog->prognum, prog
->progver, prog->progport); } while (0); _gf_log ("rpc-service"
, "rpcsvc.c", __FUNCTION__, 1335, GF_LOG_DEBUG, "Program unregistered: %s, Num: %d,"
" Ver: %d, Port: %d", prog->progname, prog->prognum, prog
->progver, prog->progport); } while (0)
;
1336
1337 pthread_mutex_lock (&svc->rpclock);
1338 {
1339 list_del_init (&prog->program);
1340 }
1341 pthread_mutex_unlock (&svc->rpclock);
1342
1343 ret = 0;
1344out:
1345 if (ret == -1) {
1346 gf_log (GF_RPCSVC, GF_LOG_ERROR, "Program unregistration failed"do { do { if (0) printf ("Program unregistration failed" ": %s, Num: %d, Ver: %d, Port: %d"
, program->progname, program->prognum, program->progver
, program->progport); } while (0); _gf_log ("rpc-service",
"rpcsvc.c", __FUNCTION__, 1348, GF_LOG_ERROR, "Program unregistration failed"
": %s, Num: %d, Ver: %d, Port: %d", program->progname, program
->prognum, program->progver, program->progport); } while
(0)
1347 ": %s, Num: %d, Ver: %d, Port: %d", program->progname,do { do { if (0) printf ("Program unregistration failed" ": %s, Num: %d, Ver: %d, Port: %d"
, program->progname, program->prognum, program->progver
, program->progport); } while (0); _gf_log ("rpc-service",
"rpcsvc.c", __FUNCTION__, 1348, GF_LOG_ERROR, "Program unregistration failed"
": %s, Num: %d, Ver: %d, Port: %d", program->progname, program
->prognum, program->progver, program->progport); } while
(0)
1348 program->prognum, program->progver, program->progport)do { do { if (0) printf ("Program unregistration failed" ": %s, Num: %d, Ver: %d, Port: %d"
, program->progname, program->prognum, program->progver
, program->progport); } while (0); _gf_log ("rpc-service",
"rpcsvc.c", __FUNCTION__, 1348, GF_LOG_ERROR, "Program unregistration failed"
": %s, Num: %d, Ver: %d, Port: %d", program->progname, program
->prognum, program->progver, program->progport); } while
(0)
;
1349 }
1350
1351 return ret;
1352}
1353
1354
1355inline int
1356rpcsvc_transport_peername (rpc_transport_t *trans, char *hostname, int hostlen)
1357{
1358 if (!trans) {
1359 return -1;
1360 }
1361
1362 return rpc_transport_get_peername (trans, hostname, hostlen);
1363}
1364
1365
1366inline int
1367rpcsvc_transport_peeraddr (rpc_transport_t *trans, char *addrstr, int addrlen,
1368 struct sockaddr_storage *sa, socklen_t sasize)
1369{
1370 if (!trans) {
1371 return -1;
1372 }
1373
1374 return rpc_transport_get_peeraddr(trans, addrstr, addrlen, sa,
1375 sasize);
1376}
1377
1378
1379rpc_transport_t *
1380rpcsvc_transport_create (rpcsvc_t *svc, dict_t *options, char *name)
1381{
1382 int ret = -1;
1383 rpc_transport_t *trans = NULL((void*)0);
1384
1385 trans = rpc_transport_load (svc->ctx, options, name);
1386 if (!trans) {
1387 gf_log (GF_RPCSVC, GF_LOG_WARNING, "cannot create listener, "do { do { if (0) printf ("cannot create listener, " "initing the transport failed"
); } while (0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__
, 1388, GF_LOG_WARNING, "cannot create listener, " "initing the transport failed"
); } while (0)
1388 "initing the transport failed")do { do { if (0) printf ("cannot create listener, " "initing the transport failed"
); } while (0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__
, 1388, GF_LOG_WARNING, "cannot create listener, " "initing the transport failed"
); } while (0)
;
1389 goto out;
1390 }
1391
1392 ret = rpc_transport_listen (trans);
1393 if (ret == -1) {
1394 gf_log (GF_RPCSVC, GF_LOG_WARNING,do { do { if (0) printf ("listening on transport failed"); } while
(0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__, 1395,
GF_LOG_WARNING, "listening on transport failed"); } while (0
)
1395 "listening on transport failed")do { do { if (0) printf ("listening on transport failed"); } while
(0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__, 1395,
GF_LOG_WARNING, "listening on transport failed"); } while (0
)
;
1396 goto out;
1397 }
1398
1399 ret = rpc_transport_register_notify (trans, rpcsvc_notify, svc);
1400 if (ret == -1) {
1401 gf_log (GF_RPCSVC, GF_LOG_WARNING, "registering notify failed")do { do { if (0) printf ("registering notify failed"); } while
(0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__, 1401,
GF_LOG_WARNING, "registering notify failed"); } while (0)
;
1402 goto out;
1403 }
1404
1405 ret = 0;
1406out:
1407 if ((ret == -1) && (trans)) {
1408 rpc_transport_disconnect (trans);
1409 trans = NULL((void*)0);
1410 }
1411
1412 return trans;
1413}
1414
1415rpcsvc_listener_t *
1416rpcsvc_listener_alloc (rpcsvc_t *svc, rpc_transport_t *trans)
1417{
1418 rpcsvc_listener_t *listener = NULL((void*)0);
1419
1420 listener = GF_CALLOC (1, sizeof (*listener),__gf_calloc (1, sizeof (*listener), gf_common_mt_rpcsvc_listener_t
)
1421 gf_common_mt_rpcsvc_listener_t)__gf_calloc (1, sizeof (*listener), gf_common_mt_rpcsvc_listener_t
)
;
1422 if (!listener) {
1423 goto out;
1424 }
1425
1426 listener->trans = trans;
1427 listener->svc = svc;
1428
1429 INIT_LIST_HEAD (&listener->list)do { (&listener->list)->next = (&listener->list
)->prev = &listener->list; } while (0)
;
1430
1431 pthread_mutex_lock (&svc->rpclock);
1432 {
1433 list_add_tail (&listener->list, &svc->listeners);
1434 }
1435 pthread_mutex_unlock (&svc->rpclock);
1436out:
1437 return listener;
1438}
1439
1440
1441int32_t
1442rpcsvc_create_listener (rpcsvc_t *svc, dict_t *options, char *name)
1443{
1444 rpc_transport_t *trans = NULL((void*)0);
1445 rpcsvc_listener_t *listener = NULL((void*)0);
1446 int32_t ret = -1;
1447
1448 if (!svc || !options) {
1449 goto out;
1450 }
1451
1452 trans = rpcsvc_transport_create (svc, options, name);
1453 if (!trans) {
1454 /* LOG TODO */
1455 goto out;
1456 }
1457
1458 listener = rpcsvc_listener_alloc (svc, trans);
1459 if (listener == NULL((void*)0)) {
1460 goto out;
1461 }
1462
1463 ret = 0;
1464out:
1465 if (!listener && trans) {
1466 rpc_transport_disconnect (trans);
1467 }
1468
1469 return ret;
1470}
1471
1472
1473int32_t
1474rpcsvc_create_listeners (rpcsvc_t *svc, dict_t *options, char *name)
1475{
1476 int32_t ret = -1, count = 0;
1477 data_t *data = NULL((void*)0);
1478 char *str = NULL((void*)0), *ptr = NULL((void*)0), *transport_name = NULL((void*)0);
1479 char *transport_type = NULL((void*)0), *saveptr = NULL((void*)0), *tmp = NULL((void*)0);
1480
1481 if ((svc == NULL((void*)0)) || (options == NULL((void*)0)) || (name == NULL((void*)0))) {
1482 goto out;
1483 }
1484
1485 data = dict_get (options, "transport-type");
1486 if (data == NULL((void*)0)) {
1487 gf_log (GF_RPCSVC, GF_LOG_ERROR,do { do { if (0) printf ("option transport-type not set"); } while
(0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__, 1488,
GF_LOG_ERROR, "option transport-type not set"); } while (0)
1488 "option transport-type not set")do { do { if (0) printf ("option transport-type not set"); } while
(0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__, 1488,
GF_LOG_ERROR, "option transport-type not set"); } while (0)
;
1489 goto out;
1490 }
1491
1492 transport_type = data_to_str (data);
1493 if (transport_type == NULL((void*)0)) {
1494 gf_log (GF_RPCSVC, GF_LOG_ERROR,do { do { if (0) printf ("option transport-type not set"); } while
(0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__, 1495,
GF_LOG_ERROR, "option transport-type not set"); } while (0)
1495 "option transport-type not set")do { do { if (0) printf ("option transport-type not set"); } while
(0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__, 1495,
GF_LOG_ERROR, "option transport-type not set"); } while (0)
;
1496 goto out;
1497 }
1498
1499 /* duplicate transport_type, since following dict_set will free it */
1500 transport_type = gf_strdup (transport_type);
1501 if (transport_type == NULL((void*)0)) {
1502 goto out;
1503 }
1504
1505 str = gf_strdup (transport_type);
1506 if (str == NULL((void*)0)) {
1507 goto out;
1508 }
1509
1510 ptr = strtok_r (str, ",", &saveptr);
1511
1512 while (ptr != NULL((void*)0)) {
1513 tmp = gf_strdup (ptr);
1514 if (tmp == NULL((void*)0)) {
1515 goto out;
1516 }
1517
1518 ret = gf_asprintf (&transport_name, "%s.%s", tmp, name);
1519 if (ret == -1) {
1520 goto out;
1521 }
1522
1523 ret = dict_set_dynstr (options, "transport-type", tmp);
1524 if (ret == -1) {
1525 goto out;
1526 }
1527
1528 tmp = NULL((void*)0);
1529 ptr = strtok_r (NULL((void*)0), ",", &saveptr);
1530
1531 ret = rpcsvc_create_listener (svc, options, transport_name);
1532 if (ret != 0) {
1533 goto out;
1534 }
1535
1536 GF_FREE (transport_name)__gf_free (transport_name);
1537 transport_name = NULL((void*)0);
1538 count++;
1539 }
1540
1541 ret = dict_set_dynstr (options, "transport-type", transport_type);
1542 if (ret == -1) {
1543 goto out;
1544 }
1545
1546 transport_type = NULL((void*)0);
1547
1548out:
1549 GF_FREE (str)__gf_free (str);
1550
1551 GF_FREE (transport_type)__gf_free (transport_type);
1552
1553 GF_FREE (tmp)__gf_free (tmp);
1554
1555 GF_FREE (transport_name)__gf_free (transport_name);
1556
1557 return count;
1558}
1559
1560
1561int
1562rpcsvc_unregister_notify (rpcsvc_t *svc, rpcsvc_notify_t notify, void *mydata)
1563{
1564 rpcsvc_notify_wrapper_t *wrapper = NULL((void*)0), *tmp = NULL((void*)0);
1565 int ret = 0;
1566
1567 if (!svc || !notify) {
1568 goto out;
1569 }
1570
1571 pthread_mutex_lock (&svc->rpclock);
1572 {
1573 list_for_each_entry_safe (wrapper, tmp, &svc->notify, list)for (wrapper = ((typeof(*wrapper) *)((char *)((&svc->notify
)->next)-(unsigned long)(&((typeof(*wrapper) *)0)->
list))), tmp = ((typeof(*wrapper) *)((char *)(wrapper->list
.next)-(unsigned long)(&((typeof(*wrapper) *)0)->list)
)); &wrapper->list != (&svc->notify); wrapper =
tmp, tmp = ((typeof(*tmp) *)((char *)(tmp->list.next)-(unsigned
long)(&((typeof(*tmp) *)0)->list))))
{
1574 if ((wrapper->notify == notify)
1575 && (mydata == wrapper->data)) {
1576 list_del_init (&wrapper->list);
1577 GF_FREE (wrapper)__gf_free (wrapper);
1578 ret++;
1579 }
1580 }
1581 }
1582 pthread_mutex_unlock (&svc->rpclock);
1583
1584out:
1585 return ret;
1586}
1587
1588int
1589rpcsvc_register_notify (rpcsvc_t *svc, rpcsvc_notify_t notify, void *mydata)
1590{
1591 rpcsvc_notify_wrapper_t *wrapper = NULL((void*)0);
1592 int ret = -1;
1593
1594 wrapper = rpcsvc_notify_wrapper_alloc ();
1595 if (!wrapper) {
1596 goto out;
1597 }
1598 svc->mydata = mydata; /* this_xlator */
1599 wrapper->data = mydata;
1600 wrapper->notify = notify;
1601
1602 pthread_mutex_lock (&svc->rpclock);
1603 {
1604 list_add_tail (&wrapper->list, &svc->notify);
1605 svc->notify_count++;
1606 }
1607 pthread_mutex_unlock (&svc->rpclock);
1608
1609 ret = 0;
1610out:
1611 return ret;
1612}
1613
1614
1615inline int
1616rpcsvc_program_register (rpcsvc_t *svc, rpcsvc_program_t *program)
1617{
1618 int ret = -1;
1619 rpcsvc_program_t *newprog = NULL((void*)0);
1620 char already_registered = 0;
1621
1622 if (!svc) {
1623 goto out;
1624 }
1625
1626 if (program->actors == NULL((void*)0)) {
1627 goto out;
1628 }
1629
1630 pthread_mutex_lock (&svc->rpclock);
1631 {
1632 list_for_each_entry (newprog, &svc->programs, program)for (newprog = ((typeof(*newprog) *)((char *)((&svc->programs
)->next)-(unsigned long)(&((typeof(*newprog) *)0)->
program))); &newprog->program != (&svc->programs
); newprog = ((typeof(*newprog) *)((char *)(newprog->program
.next)-(unsigned long)(&((typeof(*newprog) *)0)->program
))))
{
1633 if ((newprog->prognum == program->prognum)
1634 && (newprog->progver == program->progver)) {
1635 already_registered = 1;
1636 break;
1637 }
1638 }
1639 }
1640 pthread_mutex_unlock (&svc->rpclock);
1641
1642 if (already_registered) {
1643 ret = 0;
1644 goto out;
1645 }
1646
1647 newprog = GF_CALLOC (1, sizeof(*newprog),gf_common_mt_rpcsvc_program_t)__gf_calloc (1, sizeof(*newprog), gf_common_mt_rpcsvc_program_t
)
;
1648 if (newprog == NULL((void*)0)) {
1649 goto out;
1650 }
1651
1652 memcpy (newprog, program, sizeof (*program));
1653
1654 INIT_LIST_HEAD (&newprog->program)do { (&newprog->program)->next = (&newprog->
program)->prev = &newprog->program; } while (0)
;
1655
1656 pthread_mutex_lock (&svc->rpclock);
1657 {
1658 list_add_tail (&newprog->program, &svc->programs);
1659 }
1660 pthread_mutex_unlock (&svc->rpclock);
1661
1662 ret = 0;
1663 gf_log (GF_RPCSVC, GF_LOG_DEBUG, "New program registered: %s, Num: %d,"do { do { if (0) printf ("New program registered: %s, Num: %d,"
" Ver: %d, Port: %d", newprog->progname, newprog->prognum
, newprog->progver, newprog->progport); } while (0); _gf_log
("rpc-service", "rpcsvc.c", __FUNCTION__, 1665, GF_LOG_DEBUG
, "New program registered: %s, Num: %d," " Ver: %d, Port: %d"
, newprog->progname, newprog->prognum, newprog->progver
, newprog->progport); } while (0)
1664 " Ver: %d, Port: %d", newprog->progname, newprog->prognum,do { do { if (0) printf ("New program registered: %s, Num: %d,"
" Ver: %d, Port: %d", newprog->progname, newprog->prognum
, newprog->progver, newprog->progport); } while (0); _gf_log
("rpc-service", "rpcsvc.c", __FUNCTION__, 1665, GF_LOG_DEBUG
, "New program registered: %s, Num: %d," " Ver: %d, Port: %d"
, newprog->progname, newprog->prognum, newprog->progver
, newprog->progport); } while (0)
1665 newprog->progver, newprog->progport)do { do { if (0) printf ("New program registered: %s, Num: %d,"
" Ver: %d, Port: %d", newprog->progname, newprog->prognum
, newprog->progver, newprog->progport); } while (0); _gf_log
("rpc-service", "rpcsvc.c", __FUNCTION__, 1665, GF_LOG_DEBUG
, "New program registered: %s, Num: %d," " Ver: %d, Port: %d"
, newprog->progname, newprog->prognum, newprog->progver
, newprog->progport); } while (0)
;
1666
1667out:
1668 if (ret == -1) {
1669 gf_log (GF_RPCSVC, GF_LOG_ERROR, "Program registration failed:"do { do { if (0) printf ("Program registration failed:" " %s, Num: %d, Ver: %d, Port: %d"
, program->progname, program->prognum, program->progver
, program->progport); } while (0); _gf_log ("rpc-service",
"rpcsvc.c", __FUNCTION__, 1671, GF_LOG_ERROR, "Program registration failed:"
" %s, Num: %d, Ver: %d, Port: %d", program->progname, program
->prognum, program->progver, program->progport); } while
(0)
1670 " %s, Num: %d, Ver: %d, Port: %d", program->progname,do { do { if (0) printf ("Program registration failed:" " %s, Num: %d, Ver: %d, Port: %d"
, program->progname, program->prognum, program->progver
, program->progport); } while (0); _gf_log ("rpc-service",
"rpcsvc.c", __FUNCTION__, 1671, GF_LOG_ERROR, "Program registration failed:"
" %s, Num: %d, Ver: %d, Port: %d", program->progname, program
->prognum, program->progver, program->progport); } while
(0)
1671 program->prognum, program->progver, program->progport)do { do { if (0) printf ("Program registration failed:" " %s, Num: %d, Ver: %d, Port: %d"
, program->progname, program->prognum, program->progver
, program->progport); } while (0); _gf_log ("rpc-service",
"rpcsvc.c", __FUNCTION__, 1671, GF_LOG_ERROR, "Program registration failed:"
" %s, Num: %d, Ver: %d, Port: %d", program->progname, program
->prognum, program->progver, program->progport); } while
(0)
;
1672 }
1673
1674 return ret;
1675}
1676
1677static void
1678free_prog_details (gf_dump_rsp *rsp)
1679{
1680 gf_prog_detail *prev = NULL((void*)0);
1681 gf_prog_detail *trav = NULL((void*)0);
1682
1683 trav = rsp->prog;
1684 while (trav) {
1685 prev = trav;
1686 trav = trav->next;
1687 GF_FREE (prev)__gf_free (prev);
1688 }
1689}
1690
1691static int
1692build_prog_details (rpcsvc_request_t *req, gf_dump_rsp *rsp)
1693{
1694 int ret = -1;
1695 rpcsvc_program_t *program = NULL((void*)0);
1696 gf_prog_detail *prog = NULL((void*)0);
1697 gf_prog_detail *prev = NULL((void*)0);
1698
1699 if (!req || !req->trans || !req->svc)
1700 goto out;
1701
1702 list_for_each_entry (program, &req->svc->programs, program)for (program = ((typeof(*program) *)((char *)((&req->svc
->programs)->next)-(unsigned long)(&((typeof(*program
) *)0)->program))); &program->program != (&req->
svc->programs); program = ((typeof(*program) *)((char *)(program
->program.next)-(unsigned long)(&((typeof(*program) *)
0)->program))))
{
1703 prog = GF_CALLOC (1, sizeof (*prog), 0)__gf_calloc (1, sizeof (*prog), 0);
1704 if (!prog)
1705 goto out;
1706 prog->progname = program->progname;
1707 prog->prognum = program->prognum;
1708 prog->progver = program->progver;
1709 if (!rsp->prog)
1710 rsp->prog = prog;
1711 if (prev)
1712 prev->next = prog;
1713 prev = prog;
1714 }
1715 if (prev)
1716 ret = 0;
1717out:
1718 return ret;
1719}
1720
1721static int
1722rpcsvc_dump (rpcsvc_request_t *req)
1723{
1724 char rsp_buf[8 * 1024] = {0,};
1725 gf_dump_rsp rsp = {0,};
1726 struct iovec iov = {0,};
1727 int op_errno = EINVAL22;
1728 int ret = -1;
1729 uint32_t dump_rsp_len = 0;
1730
1731 if (!req)
1732 goto sendrsp;
1733
1734 ret = build_prog_details (req, &rsp);
1735 if (ret < 0) {
1736 op_errno = -ret;
1737 goto sendrsp;
1738 }
1739
1740 op_errno = 0;
1741
1742sendrsp:
1743 rsp.op_errno = gf_errno_to_error (op_errno);
1744 rsp.op_ret = ret;
1745
1746 dump_rsp_len = xdr_sizeof ((xdrproc_t) xdr_gf_dump_rsp,
1747 &rsp);
1748
1749 iov.iov_base = rsp_buf;
1750 iov.iov_len = dump_rsp_len;
1751
1752 ret = xdr_serialize_generic (iov, &rsp, (xdrproc_t)xdr_gf_dump_rsp);
1753 if (ret < 0) {
1754 ret = RPCSVC_ACTOR_ERROR(-1);
1755 } else {
1756 rpcsvc_submit_generic (req, &iov, 1, NULL((void*)0), 0, NULL((void*)0));
1757 ret = 0;
1758 }
1759
1760 free_prog_details (&rsp);
1761
1762 return ret;
1763}
1764
1765int
1766rpcsvc_init_options (rpcsvc_t *svc, dict_t *options)
1767{
1768 char *optstr = NULL((void*)0);
1769 int ret = -1;
1770
1771 if ((!svc) || (!options))
1772 return -1;
1773
1774 svc->memfactor = RPCSVC_DEFAULT_MEMFACTOR8;
1775
1776 svc->register_portmap = _gf_true;
1777 if (dict_get (options, "rpc.register-with-portmap")) {
1778 ret = dict_get_str (options, "rpc.register-with-portmap",
1779 &optstr);
1780 if (ret < 0) {
1781 gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to parse "do { do { if (0) printf ("Failed to parse " "dict"); } while (
0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__, 1782, GF_LOG_ERROR
, "Failed to parse " "dict"); } while (0)
1782 "dict")do { do { if (0) printf ("Failed to parse " "dict"); } while (
0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__, 1782, GF_LOG_ERROR
, "Failed to parse " "dict"); } while (0)
;
1783 goto out;
1784 }
1785
1786 ret = gf_string2boolean (optstr, &svc->register_portmap);
1787 if (ret < 0) {
1788 gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to parse bool "do { do { if (0) printf ("Failed to parse bool " "string"); }
while (0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__,
1789, GF_LOG_ERROR, "Failed to parse bool " "string"); } while
(0)
1789 "string")do { do { if (0) printf ("Failed to parse bool " "string"); }
while (0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__,
1789, GF_LOG_ERROR, "Failed to parse bool " "string"); } while
(0)
;
1790 goto out;
1791 }
1792 }
1793
1794 if (!svc->register_portmap)
1795 gf_log (GF_RPCSVC, GF_LOG_DEBUG, "Portmap registration "do { do { if (0) printf ("Portmap registration " "disabled");
} while (0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__
, 1796, GF_LOG_DEBUG, "Portmap registration " "disabled"); } while
(0)
1796 "disabled")do { do { if (0) printf ("Portmap registration " "disabled");
} while (0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__
, 1796, GF_LOG_DEBUG, "Portmap registration " "disabled"); } while
(0)
;
1797
1798 ret = 0;
1799out:
1800 return ret;
1801}
1802
1803int
1804rpcsvc_transport_unix_options_build (dict_t **options, char *filepath)
1805{
1806 dict_t *dict = NULL((void*)0);
1807 char *fpath = NULL((void*)0);
1808 int ret = -1;
1809
1810 GF_ASSERT (filepath)do { if (!(filepath)) { do { do { if (0) printf ("Assertion failed: "
"filepath"); } while (0); _gf_log_callingfn ("", "rpcsvc.c",
__FUNCTION__, 1810, GF_LOG_ERROR, "Assertion failed: " "filepath"
); } while (0); } } while (0)
;
1811 GF_ASSERT (options)do { if (!(options)) { do { do { if (0) printf ("Assertion failed: "
"options"); } while (0); _gf_log_callingfn ("", "rpcsvc.c", __FUNCTION__
, 1811, GF_LOG_ERROR, "Assertion failed: " "options"); } while
(0); } } while (0)
;
1812
1813 dict = dict_new ();
1814 if (!dict)
1815 goto out;
1816
1817 fpath = gf_strdup (filepath);
1818 if (!fpath) {
1819 ret = -1;
1820 goto out;
1821 }
1822
1823 ret = dict_set_dynstr (dict, "transport.socket.listen-path", fpath);
1824 if (ret)
1825 goto out;
1826
1827 ret = dict_set_str (dict, "transport.address-family", "unix");
1828 if (ret)
1829 goto out;
1830
1831 ret = dict_set_str (dict, "transport.socket.nodelay", "off");
1832 if (ret)
1833 goto out;
1834
1835 ret = dict_set_str (dict, "transport-type", "socket");
1836 if (ret)
1837 goto out;
1838
1839 *options = dict;
1840out:
1841 if (ret) {
1842 GF_FREE (fpath)__gf_free (fpath);
1843 if (dict)
1844 dict_unref (dict);
1845 }
1846 return ret;
1847}
1848
1849/* The global RPC service initializer.
1850 */
1851rpcsvc_t *
1852rpcsvc_init (xlator_t *xl, glusterfs_ctx_t *ctx, dict_t *options,
1853 uint32_t poolcount)
1854{
1855 rpcsvc_t *svc = NULL((void*)0);
1856 int ret = -1;
1857
1858 if ((!ctx) || (!options))
1859 return NULL((void*)0);
1860
1861 svc = GF_CALLOC (1, sizeof (*svc), gf_common_mt_rpcsvc_t)__gf_calloc (1, sizeof (*svc), gf_common_mt_rpcsvc_t);
1862 if (!svc)
1863 return NULL((void*)0);
1864
1865 pthread_mutex_init (&svc->rpclock, NULL((void*)0));
1866 INIT_LIST_HEAD (&svc->authschemes)do { (&svc->authschemes)->next = (&svc->authschemes
)->prev = &svc->authschemes; } while (0)
;
1867 INIT_LIST_HEAD (&svc->notify)do { (&svc->notify)->next = (&svc->notify)->
prev = &svc->notify; } while (0)
;
1868 INIT_LIST_HEAD (&svc->listeners)do { (&svc->listeners)->next = (&svc->listeners
)->prev = &svc->listeners; } while (0)
;
1869 INIT_LIST_HEAD (&svc->programs)do { (&svc->programs)->next = (&svc->programs
)->prev = &svc->programs; } while (0)
;
1870
1871 ret = rpcsvc_init_options (svc, options);
1872 if (ret == -1) {
1873 gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to init options")do { do { if (0) printf ("Failed to init options"); } while (
0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__, 1873, GF_LOG_ERROR
, "Failed to init options"); } while (0)
;
1874 goto free_svc;
1875 }
1876
1877 if (!poolcount)
1878 poolcount = RPCSVC_POOLCOUNT_MULT64 * svc->memfactor;
1879
1880 gf_log (GF_RPCSVC, GF_LOG_TRACE, "rx pool: %d", poolcount)do { do { if (0) printf ("rx pool: %d", poolcount); } while (
0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__, 1880, GF_LOG_TRACE
, "rx pool: %d", poolcount); } while (0)
;
1881 svc->rxpool = mem_pool_new (rpcsvc_request_t, poolcount)mem_pool_new_fn (sizeof(rpcsvc_request_t), poolcount, "rpcsvc_request_t"
)
;
1882 /* TODO: leak */
1883 if (!svc->rxpool) {
1884 gf_log (GF_RPCSVC, GF_LOG_ERROR, "mem pool allocation failed")do { do { if (0) printf ("mem pool allocation failed"); } while
(0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__, 1884,
GF_LOG_ERROR, "mem pool allocation failed"); } while (0)
;
1885 goto free_svc;
1886 }
1887
1888 ret = rpcsvc_auth_init (svc, options);
1889 if (ret == -1) {
1890 gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to init "do { do { if (0) printf ("Failed to init " "authentication");
} while (0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__
, 1891, GF_LOG_ERROR, "Failed to init " "authentication"); } while
(0)
1891 "authentication")do { do { if (0) printf ("Failed to init " "authentication");
} while (0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__
, 1891, GF_LOG_ERROR, "Failed to init " "authentication"); } while
(0)
;
1892 goto free_svc;
1893 }
1894
1895 ret = -1;
1896 svc->options = options;
1897 svc->ctx = ctx;
1898 svc->mydata = xl;
1899 gf_log (GF_RPCSVC, GF_LOG_DEBUG, "RPC service inited.")do { do { if (0) printf ("RPC service inited."); } while (0);
_gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__, 1899, GF_LOG_DEBUG
, "RPC service inited."); } while (0)
;
1900
1901 gluster_dump_prog.options = options;
1902
1903 ret = rpcsvc_program_register (svc, &gluster_dump_prog);
1904 if (ret) {
1905 gf_log (GF_RPCSVC, GF_LOG_ERROR,do { do { if (0) printf ("failed to register DUMP program"); }
while (0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__,
1906, GF_LOG_ERROR, "failed to register DUMP program"); } while
(0)
1906 "failed to register DUMP program")do { do { if (0) printf ("failed to register DUMP program"); }
while (0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__,
1906, GF_LOG_ERROR, "failed to register DUMP program"); } while
(0)
;
1907 goto free_svc;
1908 }
1909 ret = 0;
1910free_svc:
1911 if (ret == -1) {
1912 GF_FREE (svc)__gf_free (svc);
1913 svc = NULL((void*)0);
1914 }
1915
1916 return svc;
1917}
1918
1919
1920int
1921rpcsvc_transport_peer_check_search (dict_t *options, char *pattern,
1922 char *ip, char *hostname)
1923{
1924 int ret = -1;
1925 char *addrtok = NULL((void*)0);
1926 char *addrstr = NULL((void*)0);
1927 char *dup_addrstr = NULL((void*)0);
1928 char *svptr = NULL((void*)0);
1929
1930 if ((!options) || (!ip))
1931 return -1;
1932
1933 ret = dict_get_str (options, pattern, &addrstr);
1934 if (ret < 0) {
1935 ret = -1;
1936 goto err;
1937 }
1938
1939 if (!addrstr) {
1940 ret = -1;
1941 goto err;
1942 }
1943
1944 dup_addrstr = gf_strdup (addrstr);
1945 addrtok = strtok_r (dup_addrstr, ",", &svptr);
1946 while (addrtok) {
1947
1948 /* CASEFOLD not present on Solaris */
1949#ifdef FNM_CASEFOLD(1 << 4)
1950 ret = fnmatch (addrtok, ip, FNM_CASEFOLD(1 << 4));
1951#else
1952 ret = fnmatch (addrtok, ip, 0);
1953#endif
1954 if (ret == 0)
1955 goto err;
1956
1957 /* compare hostnames if applicable */
1958 if (hostname) {
1959#ifdef FNM_CASEFOLD(1 << 4)
1960 ret = fnmatch (addrtok, hostname, FNM_CASEFOLD(1 << 4));
1961#else
1962 ret = fnmatch (addrtok, hostname, 0);
1963#endif
1964 if (ret == 0)
1965 goto err;
1966 }
1967
1968 addrtok = strtok_r (NULL((void*)0), ",", &svptr);
1969 }
1970
1971 ret = -1;
1972err:
1973 GF_FREE (dup_addrstr)__gf_free (dup_addrstr);
1974
1975 return ret;
1976}
1977
1978
1979int
1980rpcsvc_transport_peer_check_allow (dict_t *options, char *volname,
1981 char *ip, char *hostname)
1982{
1983 int ret = RPCSVC_AUTH_DONTCARE3;
1984 char *srchstr = NULL((void*)0);
1985
1986 if ((!options) || (!ip) || (!volname))
1987 return ret;
1988
1989 ret = gf_asprintf (&srchstr, "rpc-auth.addr.%s.allow", volname);
1990 if (ret == -1) {
1991 gf_log (GF_RPCSVC, GF_LOG_ERROR, "asprintf failed")do { do { if (0) printf ("asprintf failed"); } while (0); _gf_log
("rpc-service", "rpcsvc.c", __FUNCTION__, 1991, GF_LOG_ERROR
, "asprintf failed"); } while (0)
;
1992 ret = RPCSVC_AUTH_DONTCARE3;
1993 goto out;
1994 }
1995
1996 ret = rpcsvc_transport_peer_check_search (options, srchstr,
1997 ip, hostname);
1998 GF_FREE (srchstr)__gf_free (srchstr);
1999
2000 if (ret == 0)
2001 ret = RPCSVC_AUTH_ACCEPT1;
2002 else
2003 ret = RPCSVC_AUTH_REJECT2;
2004out:
2005 return ret;
2006}
2007
2008int
2009rpcsvc_transport_peer_check_reject (dict_t *options, char *volname,
2010 char *ip, char *hostname)
2011{
2012 int ret = RPCSVC_AUTH_DONTCARE3;
2013 char *srchstr = NULL((void*)0);
2014
2015 if ((!options) || (!ip) || (!volname))
2016 return ret;
2017
2018 ret = gf_asprintf (&srchstr, "rpc-auth.addr.%s.reject",
2019 volname);
2020 if (ret == -1) {
2021 gf_log (GF_RPCSVC, GF_LOG_ERROR, "asprintf failed")do { do { if (0) printf ("asprintf failed"); } while (0); _gf_log
("rpc-service", "rpcsvc.c", __FUNCTION__, 2021, GF_LOG_ERROR
, "asprintf failed"); } while (0)
;
2022 ret = RPCSVC_AUTH_REJECT2;
2023 goto out;
2024 }
2025
2026 ret = rpcsvc_transport_peer_check_search (options, srchstr,
2027 ip, hostname);
2028 GF_FREE (srchstr)__gf_free (srchstr);
2029
2030 if (ret == 0)
2031 ret = RPCSVC_AUTH_REJECT2;
2032 else
2033 ret = RPCSVC_AUTH_DONTCARE3;
2034out:
2035 return ret;
2036}
2037
2038
2039/* Combines rpc auth's allow and reject options.
2040 * Order of checks is important.
2041 * First, REJECT if either rejects.
2042 * If neither rejects, ACCEPT if either accepts.
2043 * If neither accepts, DONTCARE
2044 */
2045int
2046rpcsvc_combine_allow_reject_volume_check (int allow, int reject)
2047{
2048 if (allow == RPCSVC_AUTH_REJECT2 ||
2049 reject == RPCSVC_AUTH_REJECT2)
2050 return RPCSVC_AUTH_REJECT2;
2051
2052 if (allow == RPCSVC_AUTH_ACCEPT1 ||
2053 reject == RPCSVC_AUTH_ACCEPT1)
2054 return RPCSVC_AUTH_ACCEPT1;
2055
2056 return RPCSVC_AUTH_DONTCARE3;
2057}
2058
2059int
2060rpcsvc_auth_check (dict_t *options, char *volname,
2061 rpc_transport_t *trans)
2062{
2063 int ret = RPCSVC_AUTH_REJECT2;
2064 int accept = RPCSVC_AUTH_REJECT2;
2065 int reject = RPCSVC_AUTH_REJECT2;
2066 char *hostname = NULL((void*)0);
2067 char *ip = NULL((void*)0);
2068 char client_ip[RPCSVC_PEER_STRLEN1024] = {0};
2069
2070 if (!options || !volname || !trans)
2071 return ret;
2072
2073 ret = rpcsvc_transport_peername (trans, client_ip, RPCSVC_PEER_STRLEN1024);
2074 if (ret != 0) {
2075 gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to get remote addr: "do { do { if (0) printf ("Failed to get remote addr: " "%s", gai_strerror
(ret)); } while (0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__
, 2076, GF_LOG_ERROR, "Failed to get remote addr: " "%s", gai_strerror
(ret)); } while (0)
2076 "%s", gai_strerror (ret))do { do { if (0) printf ("Failed to get remote addr: " "%s", gai_strerror
(ret)); } while (0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__
, 2076, GF_LOG_ERROR, "Failed to get remote addr: " "%s", gai_strerror
(ret)); } while (0)
;
2077 return RPCSVC_AUTH_REJECT2;
2078 }
2079
2080 get_host_name (client_ip, &ip);
2081
2082 /* addr-namelookup disabled by default */
2083 ret = dict_get_str_boolean (options, "rpc-auth.addr.namelookup", 0);
2084 if (ret == _gf_true)
2085 gf_get_hostname_from_ip (ip, &hostname);
2086
2087 accept = rpcsvc_transport_peer_check_allow (options, volname,
2088 ip, hostname);
2089
2090 reject = rpcsvc_transport_peer_check_reject (options, volname,
2091 ip, hostname);
2092
2093 return rpcsvc_combine_allow_reject_volume_check (accept, reject);
2094}
2095
2096int
2097rpcsvc_transport_privport_check (rpcsvc_t *svc, char *volname,
2098 rpc_transport_t *trans)
2099{
2100 union gf_sock_union sock_union;
2101 int ret = RPCSVC_AUTH_REJECT2;
2102 socklen_t sinsize = sizeof (&sock_union.sin);
2103 char *srchstr = NULL((void*)0);
2104 char *valstr = NULL((void*)0);
2105 uint16_t port = 0;
2106 gf_boolean_t insecure = _gf_false;
2107
2108 memset (&sock_union, 0, sizeof (sock_union));
2109
2110 if ((!svc) || (!volname) || (!trans))
2111 return ret;
2112
2113 ret = rpcsvc_transport_peeraddr (trans, NULL((void*)0), 0, &sock_union.storage,
2114 sinsize);
2115 if (ret != 0) {
2116 gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to get peer addr: %s",do { do { if (0) printf ("Failed to get peer addr: %s", gai_strerror
(ret)); } while (0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__
, 2117, GF_LOG_ERROR, "Failed to get peer addr: %s", gai_strerror
(ret)); } while (0)
2117 gai_strerror (ret))do { do { if (0) printf ("Failed to get peer addr: %s", gai_strerror
(ret)); } while (0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__
, 2117, GF_LOG_ERROR, "Failed to get peer addr: %s", gai_strerror
(ret)); } while (0)
;
2118 ret = RPCSVC_AUTH_REJECT2;
2119 goto err;
2120 }
2121
2122 port = ntohs (sock_union.sin.sin_port);
2123 gf_log (GF_RPCSVC, GF_LOG_TRACE, "Client port: %d", (int)port)do { do { if (0) printf ("Client port: %d", (int)port); } while
(0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__, 2123,
GF_LOG_TRACE, "Client port: %d", (int)port); } while (0)
;
2124 /* If the port is already a privileged one, dont bother with checking
2125 * options.
2126 */
2127 if (port <= 1024) {
2128 ret = RPCSVC_AUTH_ACCEPT1;
2129 goto err;
2130 }
2131
2132 /* Disabled by default */
2133 ret = gf_asprintf (&srchstr, "rpc-auth.ports.%s.insecure", volname);
2134 if (ret == -1) {
2135 gf_log (GF_RPCSVC, GF_LOG_ERROR, "asprintf failed")do { do { if (0) printf ("asprintf failed"); } while (0); _gf_log
("rpc-service", "rpcsvc.c", __FUNCTION__, 2135, GF_LOG_ERROR
, "asprintf failed"); } while (0)
;
2136 ret = RPCSVC_AUTH_REJECT2;
2137 goto err;
2138 }
2139
2140 ret = dict_get_str (svc->options, srchstr, &valstr);
2141 if (ret) {
2142 gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to"do { do { if (0) printf ("Failed to" " read rpc-auth.ports.insecure value"
); } while (0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__
, 2143, GF_LOG_ERROR, "Failed to" " read rpc-auth.ports.insecure value"
); } while (0)
2143 " read rpc-auth.ports.insecure value")do { do { if (0) printf ("Failed to" " read rpc-auth.ports.insecure value"
); } while (0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__
, 2143, GF_LOG_ERROR, "Failed to" " read rpc-auth.ports.insecure value"
); } while (0)
;
2144 goto err;
2145 }
2146
2147 ret = gf_string2boolean (valstr, &insecure);
2148 if (ret) {
2149 gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to"do { do { if (0) printf ("Failed to" " convert rpc-auth.ports.insecure value"
); } while (0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__
, 2150, GF_LOG_ERROR, "Failed to" " convert rpc-auth.ports.insecure value"
); } while (0)
2150 " convert rpc-auth.ports.insecure value")do { do { if (0) printf ("Failed to" " convert rpc-auth.ports.insecure value"
); } while (0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__
, 2150, GF_LOG_ERROR, "Failed to" " convert rpc-auth.ports.insecure value"
); } while (0)
;
2151 goto err;
2152 }
2153
2154 ret = insecure ? RPCSVC_AUTH_ACCEPT1 : RPCSVC_AUTH_REJECT2;
2155
2156 if (ret == RPCSVC_AUTH_ACCEPT1)
2157 gf_log (GF_RPCSVC, GF_LOG_DEBUG, "Unprivileged port allowed")do { do { if (0) printf ("Unprivileged port allowed"); } while
(0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__, 2157,
GF_LOG_DEBUG, "Unprivileged port allowed"); } while (0)
;
2158 else
2159 gf_log (GF_RPCSVC, GF_LOG_DEBUG, "Unprivileged port not"do { do { if (0) printf ("Unprivileged port not" " allowed");
} while (0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__
, 2160, GF_LOG_DEBUG, "Unprivileged port not" " allowed"); } while
(0)
2160 " allowed")do { do { if (0) printf ("Unprivileged port not" " allowed");
} while (0); _gf_log ("rpc-service", "rpcsvc.c", __FUNCTION__
, 2160, GF_LOG_DEBUG, "Unprivileged port not" " allowed"); } while
(0)
;
2161
2162err:
2163 if (srchstr)
2164 GF_FREE (srchstr)__gf_free (srchstr);
2165
2166 return ret;
2167}
2168
2169
2170char *
2171rpcsvc_volume_allowed (dict_t *options, char *volname)
2172{
2173 char globalrule[] = "rpc-auth.addr.allow";
2174 char *srchstr = NULL((void*)0);
2175 char *addrstr = NULL((void*)0);
2176 int ret = -1;
2177
2178 if ((!options) || (!volname))
2179 return NULL((void*)0);
2180
2181 ret = gf_asprintf (&srchstr, "rpc-auth.addr.%s.allow", volname);
2182 if (ret == -1) {
2183 gf_log (GF_RPCSVC, GF_LOG_ERROR, "asprintf failed")do { do { if (0) printf ("asprintf failed"); } while (0); _gf_log
("rpc-service", "rpcsvc.c", __FUNCTION__, 2183, GF_LOG_ERROR
, "asprintf failed"); } while (0)
;
2184 goto out;
2185 }
2186
2187 if (!dict_get (options, srchstr))
2188 ret = dict_get_str (options, globalrule, &addrstr);
2189 else
2190 ret = dict_get_str (options, srchstr, &addrstr);
2191
2192out:
2193 GF_FREE (srchstr)__gf_free (srchstr);
2194
2195 return addrstr;
2196}
2197
2198
2199rpcsvc_actor_t gluster_dump_actors[] = {
2200 [GF_DUMP_NULL] = {"NULL", GF_DUMP_NULL, NULL((void*)0), NULL((void*)0), 0},
2201 [GF_DUMP_DUMP] = {"DUMP", GF_DUMP_DUMP, rpcsvc_dump, NULL((void*)0), 0},
2202 [GF_DUMP_MAXVALUE] = {"MAXVALUE", GF_DUMP_MAXVALUE, NULL((void*)0), NULL((void*)0), 0},
2203};
2204
2205
2206struct rpcsvc_program gluster_dump_prog = {
2207 .progname = "GF-DUMP",
2208 .prognum = GLUSTER_DUMP_PROGRAM123451501,
2209 .progver = GLUSTER_DUMP_VERSION1,
2210 .actors = gluster_dump_actors,
2211 .numactors = 2,
2212};