2
Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
3
This file is part of GlusterFS.
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.
13
#include "quotad-helpers.h"
14
#include "quotad-aggregator.h"
16
static char *qd_ext_xattrs[] = {
19
QUOTA_LIMIT_OBJECTS_KEY,
23
static struct rpcsvc_program quotad_aggregator_prog;
26
quotad_serialize_reply(rpcsvc_request_t *req, void *arg, struct iovec *outmsg,
29
struct iobuf *iob = NULL;
33
GF_VALIDATE_OR_GOTO("server", req, ret);
35
/* First, get the io buffer into which the reply in arg will
39
xdr_size = xdr_sizeof(xdrproc, arg);
40
iob = iobuf_get2(req->svc->ctx->iobuf_pool, xdr_size);
42
gf_log_callingfn(THIS->name, GF_LOG_ERROR, "Failed to get iobuf");
46
iobuf_to_iovec(iob, outmsg);
47
/* Use the given serializer to translate the given C structure
48
* in arg to XDR format which will be written into the buffer
51
/* retlen is used to received the error since size_t is unsigned and we
52
* need -1 for error notification during encoding.
55
retlen = xdr_serialize_generic(*outmsg, arg, xdrproc);
57
/* Failed to Encode 'GlusterFS' msg in RPC is not exactly
58
failure of RPC return values.. Client should get
59
notified about this, so there are no missing frames */
60
gf_log_callingfn("", GF_LOG_ERROR, "Failed to encode message");
61
req->rpc_err = GARBAGE_ARGS;
65
outmsg->iov_len = retlen;
71
quotad_aggregator_submit_reply(call_frame_t *frame, rpcsvc_request_t *req,
72
void *arg, struct iovec *payload,
73
int payloadcount, struct iobref *iobref,
76
struct iobuf *iob = NULL;
81
quotad_aggregator_state_t *state = NULL;
84
GF_VALIDATE_OR_GOTO("server", req, ret);
87
state = frame->root->state;
92
iobref = iobref_new();
100
iob = quotad_serialize_reply(req, arg, &rsp, xdrproc);
102
gf_msg("", GF_LOG_ERROR, 0, Q_MSG_DICT_SERIALIZE_FAIL,
103
"Failed to serialize reply");
107
iobref_add(iobref, iob);
109
ret = rpcsvc_submit_generic(req, &rsp, 1, payload, payloadcount, iobref);
116
quotad_aggregator_free_state(state);
120
STACK_DESTROY(frame->root);
123
iobref_unref(iobref);
130
quotad_aggregator_getlimit_cbk(xlator_t *this, call_frame_t *frame,
133
gfs3_lookup_rsp *rsp = lookup_rsp;
134
gf_cli_rsp cli_rsp = {
137
dict_t *xdata = NULL;
138
quotad_aggregator_state_t *state = NULL;
142
if (!rsp || (rsp->op_ret == -1))
145
GF_PROTOCOL_DICT_UNSERIALIZE(frame->this, xdata, (rsp->xdata.xdata_val),
146
(rsp->xdata.xdata_len), rsp->op_ret,
150
state = frame->root->state;
151
ret = dict_get_int32n(state->req_xdata, "type", SLEN("type"), &type);
155
ret = dict_set_int32_sizen(xdata, "type", type);
164
gf_msg(this->name, GF_LOG_ERROR, 0, Q_MSG_DICT_UNSERIALIZE_FAIL,
165
"failed to unserialize "
166
"nameless lookup rsp");
169
cli_rsp.op_ret = rsp->op_ret;
170
cli_rsp.op_errno = rsp->op_errno;
171
cli_rsp.op_errstr = "";
173
GF_PROTOCOL_DICT_SERIALIZE(frame->this, xdata, (&cli_rsp.dict.dict_val),
174
(cli_rsp.dict.dict_len), cli_rsp.op_errno,
179
quotad_aggregator_submit_reply(frame, (frame) ? frame->local : NULL,
180
(void *)&cli_rsp, NULL, 0, NULL,
181
(xdrproc_t)xdr_gf_cli_rsp);
184
GF_FREE(cli_rsp.dict.dict_val);
189
quotad_aggregator_getlimit(rpcsvc_request_t *req)
191
call_frame_t *frame = NULL;
192
gf_cli_req cli_req = {
195
gf_cli_rsp cli_rsp = {0};
196
quotad_aggregator_state_t *state = NULL;
197
xlator_t *this = NULL;
199
int ret = -1, op_errno = 0;
200
char *gfid_str = NULL;
202
char *volume_uuid = NULL;
204
GF_VALIDATE_OR_GOTO("quotad-aggregator", req, err);
208
cli_req.dict.dict_val = alloca(req->msg[0].iov_len);
210
ret = xdr_to_generic(req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req);
212
// failed to decode msg;
213
gf_msg("this->name", GF_LOG_ERROR, 0, Q_MSG_XDR_DECODE_ERROR,
214
"xdr decoding error");
215
req->rpc_err = GARBAGE_ARGS;
219
if (cli_req.dict.dict_len) {
221
ret = dict_unserialize(cli_req.dict.dict_val, cli_req.dict.dict_len,
224
gf_msg(this->name, GF_LOG_ERROR, 0, Q_MSG_DICT_UNSERIALIZE_FAIL,
225
"Failed to unserialize req-buffer to "
231
ret = dict_get_strn(dict, "gfid", SLEN("gfid"), &gfid_str);
236
ret = dict_get_strn(dict, "volume-uuid", SLEN("volume-uuid"), &volume_uuid);
241
gf_uuid_parse((const char *)gfid_str, gfid);
243
frame = quotad_aggregator_get_frame_from_req(req);
245
cli_rsp.op_errno = ENOMEM;
248
state = frame->root->state;
249
state->req_xdata = dict;
250
state->xdata = dict_new();
253
ret = dict_set_int32_sizen(state->xdata, QUOTA_LIMIT_KEY, 42);
257
ret = dict_set_int32_sizen(state->xdata, QUOTA_LIMIT_OBJECTS_KEY, 42);
259
gf_msg(this->name, GF_LOG_ERROR, ENOMEM, Q_MSG_ENOMEM,
260
"Failed to set QUOTA_LIMIT_OBJECTS_KEY");
264
ret = dict_set_int32_sizen(state->xdata, QUOTA_SIZE_KEY, 42);
268
ret = dict_set_int32_sizen(state->xdata, GET_ANCESTRY_PATH_KEY, 42);
272
ret = qd_nameless_lookup(this, frame, (char *)gfid, state->xdata,
273
volume_uuid, quotad_aggregator_getlimit_cbk);
275
cli_rsp.op_errno = ret;
282
cli_rsp.op_errno = op_errno;
285
cli_rsp.op_errstr = "";
287
quotad_aggregator_getlimit_cbk(this, frame, &cli_rsp);
294
quotad_aggregator_lookup_cbk(xlator_t *this, call_frame_t *frame, void *rsp)
296
quotad_aggregator_submit_reply(frame, frame ? frame->local : NULL, rsp,
298
(xdrproc_t)xdr_gfs3_lookup_rsp);
304
quotad_aggregator_lookup(rpcsvc_request_t *req)
306
call_frame_t *frame = NULL;
307
gfs3_lookup_req args = {
312
int i = 0, ret = -1, op_errno = 0;
313
gfs3_lookup_rsp rsp = {
316
quotad_aggregator_state_t *state = NULL;
317
xlator_t *this = NULL;
319
char *volume_uuid = NULL;
321
GF_VALIDATE_OR_GOTO("quotad-aggregator", req, err);
325
args.bname = alloca(req->msg[0].iov_len);
326
args.xdata.xdata_val = alloca(req->msg[0].iov_len);
328
ret = xdr_to_generic(req->msg[0], &args, (xdrproc_t)xdr_gfs3_lookup_req);
330
rsp.op_errno = EINVAL;
334
frame = quotad_aggregator_get_frame_from_req(req);
336
rsp.op_errno = ENOMEM;
340
state = frame->root->state;
342
GF_PROTOCOL_DICT_UNSERIALIZE(this, dict, (args.xdata.xdata_val),
343
(args.xdata.xdata_len), ret, op_errno, err);
345
ret = dict_get_str(dict, "volume-uuid", &volume_uuid);
350
state->xdata = dict_new();
352
for (i = 0; qd_ext_xattrs[i]; i++) {
353
if (dict_get(dict, qd_ext_xattrs[i])) {
354
ret = dict_set_uint32(state->xdata, qd_ext_xattrs[i], 1);
360
ret = qd_nameless_lookup(this, frame, args.gfid, state->xdata, volume_uuid,
361
quotad_aggregator_lookup_cbk);
374
rsp.op_errno = op_errno;
376
quotad_aggregator_lookup_cbk(this, frame, &rsp);
384
quotad_aggregator_rpc_notify(rpcsvc_t *rpc, void *xl, rpcsvc_event_t event,
388
gf_log_callingfn("server", GF_LOG_WARNING,
389
"Calling rpc_notify without initializing");
394
case RPCSVC_EVENT_ACCEPT:
397
case RPCSVC_EVENT_DISCONNECT:
409
quotad_aggregator_init(xlator_t *this)
411
quota_priv_t *priv = NULL;
414
priv = this->private;
417
/* Listener already created */
421
ret = dict_set_nstrn(this->options, "transport.address-family",
422
SLEN("transport.address-family"), "unix",
427
ret = dict_set_nstrn(this->options, "transport-type",
428
SLEN("transport-type"), "socket", SLEN("socket"));
432
ret = dict_set_nstrn(this->options, "transport.socket.listen-path",
433
SLEN("transport.socket.listen-path"),
434
"/var/run/gluster/quotad.socket",
435
SLEN("/var/run/gluster/quotad.socket"));
440
priv->rpcsvc = rpcsvc_init(this, this->ctx, this->options, 0);
441
if (priv->rpcsvc == NULL) {
442
gf_msg(this->name, GF_LOG_WARNING, 0, Q_MSG_RPCSVC_INIT_FAILED,
443
"creation of rpcsvc failed");
448
ret = rpcsvc_create_listeners(priv->rpcsvc, this->options, this->name);
450
gf_msg(this->name, GF_LOG_WARNING, 0,
451
Q_MSG_RPCSVC_LISTENER_CREATION_FAILED,
452
"creation of listener failed");
457
priv->quotad_aggregator = "ad_aggregator_prog;
458
quotad_aggregator_prog.options = this->options;
460
ret = rpcsvc_program_register(priv->rpcsvc, "ad_aggregator_prog,
463
gf_msg(this->name, GF_LOG_WARNING, 0, Q_MSG_RPCSVC_REGISTER_FAILED,
464
"registration of program (name:%s, prognum:%d, "
465
"progver:%d) failed",
466
quotad_aggregator_prog.progname, quotad_aggregator_prog.prognum,
467
quotad_aggregator_prog.progver);
473
if (ret && priv->rpcsvc) {
474
GF_FREE(priv->rpcsvc);
481
static rpcsvc_actor_t quotad_aggregator_actors[GF_AGGREGATOR_MAXVALUE] = {
482
[GF_AGGREGATOR_NULL] = {"NULL", NULL, NULL, GF_AGGREGATOR_NULL, DRC_NA, 0},
483
[GF_AGGREGATOR_LOOKUP] = {"LOOKUP", quotad_aggregator_lookup, NULL,
484
GF_AGGREGATOR_NULL, DRC_NA, 0},
485
[GF_AGGREGATOR_GETLIMIT] = {"GETLIMIT", quotad_aggregator_getlimit, NULL,
486
GF_AGGREGATOR_GETLIMIT, DRC_NA, 0},
489
static struct rpcsvc_program quotad_aggregator_prog = {
490
.progname = "GlusterFS 3.3",
491
.prognum = GLUSTER_AGGREGATOR_PROGRAM,
492
.progver = GLUSTER_AGGREGATOR_VERSION,
493
.numactors = GF_AGGREGATOR_MAXVALUE,
494
.actors = quotad_aggregator_actors};