diff options
author | Krutika Dhananjay <kdhananj@redhat.com> | 2013-09-04 16:06:02 +0530 |
---|---|---|
committer | Krutika Dhananjay <kdhananj@redhat.com> | 2013-09-06 14:57:09 +0530 |
commit | aa1da9c3207b9b1a1d91d09e5faf92510e7b61d7 (patch) | |
tree | 5cc1c605803054187705ed2677e37a651be332ef | |
parent | b045090e57ab53ffad3d51c298ad61262d91f7b9 (diff) |
cli: implement quota-list-all using quota.conf and quotad GETLIMIT rpc
Original-author: Krishnan Parthasarathi <kparthas@redhat.com>
Change-Id: I07797fb5402dba89f81a7d2b8b20a11db74f69c9
Signed-off-by: Krutika Dhananjay <kdhananj@redhat.com>
-rw-r--r-- | cli/src/Makefile.am | 4 | ||||
-rw-r--r-- | cli/src/cli-cmd-volume.c | 49 | ||||
-rw-r--r-- | cli/src/cli-cmd.c | 4 | ||||
-rw-r--r-- | cli/src/cli-cmd.h | 2 | ||||
-rw-r--r-- | cli/src/cli-rpc-ops.c | 212 | ||||
-rw-r--r-- | cli/src/cli.c | 48 | ||||
-rw-r--r-- | cli/src/cli.h | 2 | ||||
-rw-r--r-- | rpc/rpc-lib/src/protocol-common.h | 1 | ||||
-rw-r--r-- | xlators/features/quota/src/quotad-aggregator.c | 135 | ||||
-rw-r--r-- | xlators/features/quota/src/quotad-aggregator.h | 2 |
10 files changed, 438 insertions, 21 deletions
diff --git a/cli/src/Makefile.am b/cli/src/Makefile.am index ae523102..62f58b93 100644 --- a/cli/src/Makefile.am +++ b/cli/src/Makefile.am @@ -2,7 +2,7 @@ sbin_PROGRAMS = gluster gluster_SOURCES = cli.c registry.c input.c cli-cmd.c cli-rl.c \ cli-cmd-volume.c cli-cmd-peer.c cli-rpc-ops.c cli-cmd-parser.c\ - cli-cmd-system.c cli-cmd-misc.c cli-xml-output.c + cli-cmd-system.c cli-cmd-misc.c cli-xml-output.c cli-quotad-client.c if ENABLE_BD_XLATOR gluster_SOURCES += cli-cmd-volume-bdevice.c endif @@ -13,7 +13,7 @@ gluster_LDADD = $(top_builddir)/libglusterfs/src/libglusterfs.la $(GF_LDADD)\ $(GF_GLUSTERFS_LIBS) $(XML_LIBS) gluster_LDFLAGS = $(GF_LDFLAGS) -noinst_HEADERS = cli.h cli-mem-types.h cli-cmd.h +noinst_HEADERS = cli.h cli-mem-types.h cli-cmd.h cli-quotad-client.h AM_CPPFLAGS = $(GF_CPPFLAGS) \ -I$(top_srcdir)/libglusterfs/src -I$(top_srcdir)/rpc/rpc-lib/src\ diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c index 0657eee4..7dc26144 100644 --- a/cli/src/cli-cmd-volume.c +++ b/cli/src/cli-cmd-volume.c @@ -30,8 +30,10 @@ #include "run.h" extern struct rpc_clnt *global_rpc; +extern struct rpc_clnt *global_quotad_rpc; extern rpc_clnt_prog_t *cli_rpc_prog; +extern rpc_clnt_prog_t cli_quotad_clnt; int cli_cmd_volume_help_cbk (struct cli_state *state, struct cli_cmd_word *in_word, @@ -1083,6 +1085,16 @@ out: return ret; } +static void +print_quota_list_header (void) +{ + //Header + cli_out (" Path Hard-limit " + "Soft-limit Used Available"); + cli_out ("-----------------------------------------------------" + "---------------------------"); +} + int cli_cmd_quota_cbk (struct cli_state *state, struct cli_cmd_word *word, const char **words, int wordcount) @@ -1098,6 +1110,8 @@ cli_cmd_quota_cbk (struct cli_state *state, struct cli_cmd_word *word, cli_local_t *local = NULL; int sent = 0; char *volname = NULL; + dict_t *xdata = NULL; + char buf[256] = {0}; const char *question = "Disabling quota will delete all the quota " "configuration. Do you want to continue?"; @@ -1137,6 +1151,41 @@ cli_cmd_quota_cbk (struct cli_state *state, struct cli_cmd_word *word, gf_log ("cli", GF_LOG_ERROR, "Failed to get volume name"); goto out; } + if (type == GF_QUOTA_OPTION_TYPE_LIST && wordcount == 4) { + proc = &cli_quotad_clnt.proctable[GF_AGGREGATOR_GETLIMIT]; + xdata = dict_new (); + if (!xdata) { + ret = -1; + goto out; + } + ret = dict_set_str (xdata, "volume-uuid", volname); + if (ret) + goto out; + + char quota_conf_file[PATH_MAX] = {0}; + //TODO: fix hardcoding + sprintf (quota_conf_file, "/var/lib/glusterd/vols/%s/quota.conf", + volname); + FILE *fp = NULL; + fp = fopen (quota_conf_file, "r"); + if (!fp) { + gf_log ("cli", GF_LOG_ERROR, "Failed to open quota.conf"); + goto out; + } + + print_quota_list_header (); + while (fscanf (fp, "%s", buf) != EOF) { + + ret = dict_set_str (xdata, "gfid", buf); + if (ret) + goto out; + //Given the path, get the gfi + ret = proc->fn (frame, THIS, xdata); + dict_del (xdata, "gfid"); + + } + goto out; + } ret = cli_stage_quota_op (volname, type); if (ret) diff --git a/cli/src/cli-cmd.c b/cli/src/cli-cmd.c index aa760035..baae6f08 100644 --- a/cli/src/cli-cmd.c +++ b/cli/src/cli-cmd.c @@ -357,7 +357,7 @@ cli_cmd_broadcast_connected () } int -cli_cmd_submit (void *req, call_frame_t *frame, +cli_cmd_submit (struct rpc_clnt* rpc, void *req, call_frame_t *frame, rpc_clnt_prog_t *prog, int procnum, struct iobref *iobref, xlator_t *this, fop_cbk_fn_t cbkfn, xdrproc_t xdrproc) @@ -373,7 +373,7 @@ cli_cmd_submit (void *req, call_frame_t *frame, cli_cmd_lock (); cmd_sent = 0; - ret = cli_submit_request (req, frame, prog, + ret = cli_submit_request (rpc, req, frame, prog, procnum, NULL, this, cbkfn, xdrproc); if (!ret) { diff --git a/cli/src/cli-cmd.h b/cli/src/cli-cmd.h index 0ad37d49..479bfa88 100644 --- a/cli/src/cli-cmd.h +++ b/cli/src/cli-cmd.h @@ -110,7 +110,7 @@ int cli_cmd_lock (); int cli_cmd_unlock (); int -cli_cmd_submit (void *req, call_frame_t *frame, +cli_cmd_submit (struct rpc_clnt *rpc, void *req, call_frame_t *frame, rpc_clnt_prog_t *prog, int procnum, struct iobref *iobref, xlator_t *this, fop_cbk_fn_t cbkfn, xdrproc_t xdrproc); diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c index 6ec8c054..9c533af6 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -39,8 +39,11 @@ #include "portmap-xdr.h" #include "byte-order.h" +#include "cli-quotad-client.h" #include "run.h" +extern struct rpc_clnt *global_quotad_rpc; +extern rpc_clnt_prog_t cli_quotad_clnt; extern rpc_clnt_prog_t *cli_rpc_prog; extern int cli_op_ret; extern int connected; @@ -2454,6 +2457,179 @@ out: return ret; } +static int +print_quota_list_from_quotad (dict_t *rsp_dict) +{ + int64_t used_space = 0; + int64_t avail = 0; + int64_t *limit = NULL; + char *used_str = NULL; + char *avail_str = NULL; + char percent_str[20]= {0}; + char *hl_str = NULL; + char *sl_final = NULL; + char *path = NULL; + int ret = -1; + + struct quota_limit { + int64_t hl; + int64_t sl; + } __attribute__ ((__packed__)) *existing_limits = NULL; + + ret = dict_get_str (rsp_dict, GET_ANCESTRY_PATH_KEY, &path); + if (ret) { + gf_log ("cli", GF_LOG_WARNING, "path key is not present " + "in dict"); + goto out; + } + + ret = dict_get_bin (rsp_dict, QUOTA_LIMIT_KEY, (void**)&limit); + if (ret) { + gf_log ("cli", GF_LOG_WARNING, + "limit key not present in dict"); + goto out; + } + existing_limits = (struct quota_limit *)limit; + existing_limits->hl = ntoh64 (existing_limits->hl); + existing_limits->sl = ntoh64 (existing_limits->sl); + + hl_str = gf_uint64_2human_readable (existing_limits->hl); + + if (existing_limits->sl == 0) { + //TODO: need to fix this by fetching default sl from glusterd + sl_final = "80%"; + } else { + snprintf (percent_str, sizeof (percent_str), "%"PRIu64"%%", + existing_limits->sl); + sl_final = percent_str; + } + + ret = dict_get_bin (rsp_dict, QUOTA_SIZE_KEY, (void**)&limit); + if (ret < 0) { + gf_log ("cli", GF_LOG_WARNING, + "size key not present in dict"); + cli_out ("%-40s %7s %9s %11s %7s", path, hl_str, sl_final, + "N/A", "N/A"); + } else { + used_space = *limit; + used_space = ntoh64 (used_space); + used_str = gf_uint64_2human_readable (used_space); + + if (existing_limits->hl > used_space) + avail = existing_limits->hl - used_space; + else + avail = 0; + + avail_str = gf_uint64_2human_readable (avail); + if (used_str == NULL) + cli_out ("%-40s %7s %9s %11"PRIu64 + "%9"PRIu64, path, hl_str, + sl_final, used_space, avail); + else + cli_out ("%-40s %7s %9s %11s %7s", path, hl_str, + sl_final, used_str, avail_str); + } + + ret = 0; +out: + GF_FREE (used_str); + GF_FREE (avail_str); + GF_FREE (hl_str); + return ret; +} + +int +cli_quotad_getlimit_cbk (struct rpc_req *req, struct iovec *iov, + int count, void *myframe) +{ + //TODO: we need to gather the path, hard-limit, soft-limit and used space + gf_cli_rsp rsp = {0,}; + int ret = -1; + dict_t *dict = NULL; + call_frame_t *frame = NULL; + + if (-1 == req->rpc_status) { + goto out; + } + + frame = myframe; + + ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp); + if (ret < 0) { + gf_log (frame->this->name, GF_LOG_ERROR, + "Failed to decode xdr response"); + goto out; + } + + if (rsp.op_ret && strcmp (rsp.op_errstr, "") == 0) { + cli_err ("quota command : failed"); + goto out; + + } else if (strcmp (rsp.op_errstr, "")) + cli_err ("quota command failed : %s", rsp.op_errstr); + + if (rsp.dict.dict_len) { + /* Unserialize the dictionary */ + dict = dict_new (); + + ret = dict_unserialize (rsp.dict.dict_val, + rsp.dict.dict_len, + &dict); + if (ret < 0) { + gf_log ("cli", GF_LOG_ERROR, + "failed to " + "unserialize req-buffer to dictionary"); + goto out; + } + } + print_quota_list_from_quotad (dict); + +out: + cli_cmd_broadcast_response (ret); + if (dict) + dict_unref (dict); + + free (rsp.dict.dict_val); + return ret; +} + +int +cli_quotad_getlimit (call_frame_t *frame, xlator_t *this, void *data) +{ + gf_cli_req req = {{0,}}; + int ret = 0; + dict_t *dict = NULL; + + if (!frame || !this || !data) { + ret = -1; + goto out; + } + + dict = data; + ret = dict_allocate_and_serialize (dict, &req.dict.dict_val, + &req.dict.dict_len); + if (ret < 0) { + gf_log (this->name, GF_LOG_ERROR, + "failed to serialize the data"); + + goto out; + } + + ret = cli_cmd_submit (global_quotad_rpc, &req, frame, &cli_quotad_clnt, + GF_AGGREGATOR_GETLIMIT, NULL, + this, cli_quotad_getlimit_cbk, + (xdrproc_t) xdr_gf_cli_req); + +out: + if (ret) { + frame->local = NULL; + } + gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret); + return ret; + + +} + void gf_cli_quota_list (char *volname, dict_t *dict, int count, char *op_errstr, char *default_sl) @@ -2761,7 +2937,7 @@ gf_cli_list_friends (call_frame_t *frame, xlator_t *this, flags = (long)data; req.flags = flags; frame->local = (void*)flags; - ret = cli_cmd_submit (&req, frame, cli_rpc_prog, + ret = cli_cmd_submit (NULL, &req, frame, cli_rpc_prog, GLUSTER_CLI_LIST_FRIENDS, NULL, this, gf_cli_list_friends_cbk, (xdrproc_t) xdr_gf1_cli_peer_list_req); @@ -2875,7 +3051,7 @@ gf_cli_get_volume (call_frame_t *frame, xlator_t *this, ret = dict_allocate_and_serialize (dict, &req.dict.dict_val, &req.dict.dict_len); - ret = cli_cmd_submit (&req, frame, cli_rpc_prog, + ret = cli_cmd_submit (NULL, &req, frame, cli_rpc_prog, GLUSTER_CLI_GET_VOLUME, NULL, this, gf_cli_get_volume_cbk, (xdrproc_t) xdr_gf_cli_req); @@ -3230,7 +3406,7 @@ gf_cli_rename_volume (call_frame_t *frame, xlator_t *this, } - ret = cli_cmd_submit (&req, frame, cli_rpc_prog, + ret = cli_cmd_submit (NULL, &req, frame, cli_rpc_prog, GLUSTER_CLI_RENAME_VOLUME, NULL, this, gf_cli_rename_volume_cbk, (xdrproc_t) xdr_gf_cli_req); @@ -3582,7 +3758,7 @@ gf_cli_getspec (call_frame_t *frame, xlator_t *this, goto out; } - ret = cli_cmd_submit (&req, frame, &cli_handshake_prog, + ret = cli_cmd_submit (NULL, &req, frame, &cli_handshake_prog, GF_HNDSK_GETSPEC, NULL, this, gf_cli_getspec_cbk, (xdrproc_t) xdr_gf_getspec_req); @@ -3639,7 +3815,7 @@ gf_cli_pmap_b2p (call_frame_t *frame, xlator_t *this, void *data) if (ret) goto out; - ret = cli_cmd_submit (&req, frame, &cli_pmap_prog, + ret = cli_cmd_submit (NULL, &req, frame, &cli_pmap_prog, GF_PMAP_PORTBYBRICK, NULL, this, gf_cli_pmap_b2p_cbk, (xdrproc_t) xdr_pmap_port_by_brick_req); @@ -3754,7 +3930,7 @@ gf_cli_fsm_log (call_frame_t *frame, xlator_t *this, void *data) if (!frame || !this || !data) goto out; req.name = data; - ret = cli_cmd_submit (&req, frame, cli_rpc_prog, + ret = cli_cmd_submit (NULL, &req, frame, cli_rpc_prog, GLUSTER_CLI_FSM_LOG, NULL, this, gf_cli_fsm_log_cbk, (xdrproc_t) xdr_gf1_cli_fsm_log_req); @@ -5179,7 +5355,7 @@ gf_cli_getwd (call_frame_t *frame, xlator_t *this, void *data) if (!frame || !this) goto out; - ret = cli_cmd_submit (&req, frame, cli_rpc_prog, + ret = cli_cmd_submit (NULL, &req, frame, cli_rpc_prog, GLUSTER_CLI_GETWD, NULL, this, gf_cli_getwd_cbk, (xdrproc_t) xdr_gf1_cli_getwd_req); @@ -6672,7 +6848,7 @@ gf_cli_mount (call_frame_t *frame, xlator_t *this, void *data) goto out; } - ret = cli_cmd_submit (&req, frame, cli_rpc_prog, + ret = cli_cmd_submit (NULL, &req, frame, cli_rpc_prog, GLUSTER_CLI_MOUNT, NULL, this, gf_cli_mount_cbk, (xdrproc_t)xdr_gf1_cli_mount_req); @@ -6735,7 +6911,7 @@ gf_cli_umount (call_frame_t *frame, xlator_t *this, void *data) goto out; } - ret = cli_cmd_submit (&req, frame, cli_rpc_prog, + ret = cli_cmd_submit (NULL, &req, frame, cli_rpc_prog, GLUSTER_CLI_UMOUNT, NULL, this, gf_cli_umount_cbk, (xdrproc_t)xdr_gf1_cli_umount_req); @@ -7137,7 +7313,7 @@ gf_cli_list_volume (call_frame_t *frame, xlator_t *this, void *data) if (!frame || !this) goto out; - ret = cli_cmd_submit (&req, frame, cli_rpc_prog, + ret = cli_cmd_submit (NULL, &req, frame, cli_rpc_prog, GLUSTER_CLI_LIST_VOLUME, NULL, this, gf_cli_list_volume_cbk, (xdrproc_t)xdr_gf_cli_req); @@ -7310,7 +7486,7 @@ cli_to_glusterd (gf_cli_req *req, call_frame_t *frame, goto out; } - ret = cli_cmd_submit (req, frame, prog, procnum, iobref, this, + ret = cli_cmd_submit (NULL, req, frame, prog, procnum, iobref, this, cbkfn, (xdrproc_t) xdrproc); out: @@ -7370,3 +7546,17 @@ struct rpc_clnt_program cli_prog = { .numproc = GLUSTER_CLI_MAXVALUE, .proctable = gluster_cli_actors, }; + +struct rpc_clnt_procedure cli_quotad_procs[GF_AGGREGATOR_MAXVALUE] = { + [GF_AGGREGATOR_NULL] = {"NULL", NULL}, + [GF_AGGREGATOR_LOOKUP] = {"LOOKUP", NULL}, + [GF_AGGREGATOR_GETLIMIT] = {"GETLIMIT", cli_quotad_getlimit}, +}; + +struct rpc_clnt_program cli_quotad_clnt = { + .progname = "CLI Quotad client", + .prognum = GLUSTER_AGGREGATOR_PROGRAM, + .progver = GLUSTER_AGGREGATOR_VERSION, + .numproc = GF_AGGREGATOR_MAXVALUE, + .proctable = cli_quotad_procs, +}; diff --git a/cli/src/cli.c b/cli/src/cli.c index 37015c33..7bcdae0e 100644 --- a/cli/src/cli.c +++ b/cli/src/cli.c @@ -45,6 +45,7 @@ #endif #include "cli.h" +#include "cli-quotad-client.h" #include "cli-cmd.h" #include "cli-mem-types.h" @@ -82,6 +83,7 @@ const char *argp_program_bug_address = "<" PACKAGE_BUGREPORT ">"; +struct rpc_clnt *global_quotad_rpc; struct rpc_clnt *global_rpc; rpc_clnt_prog_t *cli_rpc_prog; @@ -183,7 +185,7 @@ logging_init (glusterfs_ctx_t *ctx, struct cli_state *state) } int -cli_submit_request (void *req, call_frame_t *frame, +cli_submit_request (struct rpc_clnt *rpc, void *req, call_frame_t *frame, rpc_clnt_prog_t *prog, int procnum, struct iobref *iobref, xlator_t *this, fop_cbk_fn_t cbkfn, xdrproc_t xdrproc) @@ -228,8 +230,10 @@ cli_submit_request (void *req, call_frame_t *frame, count = 1; } + if (!rpc) + rpc = global_rpc; /* Send the msg */ - ret = rpc_clnt_submit (global_rpc, prog, procnum, cbkfn, + ret = rpc_clnt_submit (rpc, prog, procnum, cbkfn, &iov, count, NULL, 0, iobref, frame, NULL, 0, NULL, 0, NULL); ret = 0; @@ -485,6 +489,42 @@ _cli_out (const char *fmt, ...) } struct rpc_clnt * +cli_quotad_clnt_rpc_init (void) +{ + struct rpc_clnt *rpc = NULL; + dict_t *rpc_opts = NULL; + int ret = -1; + + rpc_opts = dict_new (); + if (!rpc_opts) { + ret = -1; + goto out; + } + + ret = dict_set_str (rpc_opts, "transport.address-family", "unix"); + if (ret) + goto out; + + ret = dict_set_str (rpc_opts, "transport-type", "socket"); + if (ret) + goto out; + + ret = dict_set_str (rpc_opts, "transport.socket.connect-path", + "/tmp/quotad.socket"); + if (ret) + goto out; + + rpc = cli_quotad_clnt_init (THIS, rpc_opts); + if (!rpc) + goto out; + + global_quotad_rpc = rpc; +out: + dict_unref (rpc_opts); + return rpc; +} + +struct rpc_clnt * cli_rpc_init (struct cli_state *state) { struct rpc_clnt *rpc = NULL; @@ -605,6 +645,10 @@ main (int argc, char *argv[]) if (!global_rpc) goto out; + global_quotad_rpc = cli_quotad_clnt_rpc_init (); + if (!global_quotad_rpc) + goto out; + ret = cli_cmds_register (&state); if (ret) goto out; diff --git a/cli/src/cli.h b/cli/src/cli.h index 83651dba..2eaed8f0 100644 --- a/cli/src/cli.h +++ b/cli/src/cli.h @@ -216,7 +216,7 @@ int _cli_err (const char *fmt, ...); } while (0) int -cli_submit_request (void *req, call_frame_t *frame, +cli_submit_request (struct rpc_clnt *rpc, void *req, call_frame_t *frame, rpc_clnt_prog_t *prog, int procnum, struct iobref *iobref, xlator_t *this, fop_cbk_fn_t cbkfn, xdrproc_t xdrproc); diff --git a/rpc/rpc-lib/src/protocol-common.h b/rpc/rpc-lib/src/protocol-common.h index 8fc35859..e4fe0032 100644 --- a/rpc/rpc-lib/src/protocol-common.h +++ b/rpc/rpc-lib/src/protocol-common.h @@ -84,6 +84,7 @@ enum gf_pmap_procnum { enum gf_aggregator_procnum { GF_AGGREGATOR_NULL = 0, GF_AGGREGATOR_LOOKUP, + GF_AGGREGATOR_GETLIMIT, GF_AGGREGATOR_MAXVALUE, }; diff --git a/xlators/features/quota/src/quotad-aggregator.c b/xlators/features/quota/src/quotad-aggregator.c index d3afd443..d370da38 100644 --- a/xlators/features/quota/src/quotad-aggregator.c +++ b/xlators/features/quota/src/quotad-aggregator.c @@ -8,6 +8,7 @@ cases as published by the Free Software Foundation. */ +#include "cli1-xdr.h" #include "quota.h" #include "quotad-helpers.h" #include "quotad-aggregator.h" @@ -126,8 +127,49 @@ ret: } int +quotad_aggregator_getlimit_cbk (xlator_t *this, call_frame_t *frame, + void *lookup_rsp) +{ + gfs3_lookup_rsp *rsp = lookup_rsp; + gf_cli_rsp cli_rsp = {0,}; + dict_t *xdata = NULL; + int ret = -1; + + GF_PROTOCOL_DICT_UNSERIALIZE (frame->this, xdata, + (rsp->xdata.xdata_val), + (rsp->xdata.xdata_len), rsp->op_ret, + rsp->op_errno, out); + + ret = 0; +out: + rsp->op_ret = ret; + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "failed to unserialize " + "nameless lookup rsp"); + goto reply; + } + cli_rsp.op_ret = rsp->op_ret; + cli_rsp.op_errno = rsp->op_errno; + cli_rsp.op_errstr = ""; + if (xdata) { + GF_PROTOCOL_DICT_SERIALIZE (frame->this, xdata, + (&cli_rsp.dict.dict_val), + (cli_rsp.dict.dict_len), + cli_rsp.op_errno, reply); + } + +reply: + quotad_aggregator_submit_reply (frame, frame->local, (void*)&cli_rsp, NULL, 0, + NULL, (xdrproc_t)xdr_gf_cli_rsp); + + dict_unref (xdata); + GF_FREE (cli_rsp.dict.dict_val); + return 0; +} + +int quotad_aggregator_lookup_cbk (xlator_t *this, call_frame_t *frame, - struct gfs3_lookup_rsp *rsp) + void *rsp) { quotad_aggregator_submit_reply (frame, frame->local, rsp, NULL, 0, NULL, (xdrproc_t)xdr_gfs3_lookup_rsp); @@ -136,6 +178,95 @@ quotad_aggregator_lookup_cbk (xlator_t *this, call_frame_t *frame, } int +quotad_aggregator_getlimit (rpcsvc_request_t *req) +{ + call_frame_t *frame = NULL; + gf_cli_req cli_req = {{0}, }; + gf_cli_rsp cli_rsp = {0}; + gfs3_lookup_req args = {{0,},}; + gfs3_lookup_rsp rsp = {0,}; + quotad_aggregator_state_t *state = NULL; + xlator_t *this = NULL; + dict_t *dict = NULL; + int ret = -1, op_errno = 0; + char *gfid_str = NULL; + uuid_t gfid = {0}; + + GF_VALIDATE_OR_GOTO ("quotad-aggregator", req, err); + + this = THIS; + + ret = xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req); + if (ret < 0) { + //failed to decode msg; + gf_log ("", GF_LOG_ERROR, "xdr decoding error"); + req->rpc_err = GARBAGE_ARGS; + goto err; + } + + if (cli_req.dict.dict_len) { + dict = dict_new (); + ret = dict_unserialize (cli_req.dict.dict_val, + cli_req.dict.dict_len, &dict); + if (ret < 0) { + gf_log (this->name, GF_LOG_ERROR, "Failed to " + "unserialize req-buffer to dictionary"); + goto err; + } + } + + ret = dict_get_str (dict, "gfid", &gfid_str); + if (ret) { + goto err; + } + + uuid_parse ((const char*)gfid_str, gfid); + + frame = quotad_aggregator_get_frame_from_req (req); + if (frame == NULL) { + rsp.op_errno = ENOMEM; + goto err; + } + state = frame->root->state; + state->xdata = dict; + ret = dict_set_int32 (state->xdata, QUOTA_LIMIT_KEY, 42); + if (ret) + goto err; + + ret = dict_set_int32 (state->xdata, QUOTA_SIZE_KEY, 42); + if (ret) + goto err; + + ret = dict_set_int32 (state->xdata, GET_ANCESTRY_PATH_KEY,42); + if (ret) + goto err; + + memcpy (&args.gfid, &gfid, 16); + + args.bname = alloca (req->msg[0].iov_len); + args.xdata.xdata_val = alloca (req->msg[0].iov_len); + + ret = qd_nameless_lookup (this, frame, &args, state->xdata, + quotad_aggregator_getlimit_cbk); + if (ret) { + rsp.op_errno = ret; + goto err; + } + + return ret; + +err: + cli_rsp.op_ret = -1; + cli_rsp.op_errno = op_errno; + cli_rsp.op_errstr = ""; + + quotad_aggregator_getlimit_cbk (this, frame, &cli_rsp); + dict_unref (dict); + + return ret; +} + +int quotad_aggregator_lookup (rpcsvc_request_t *req) { call_frame_t *frame = NULL; @@ -277,6 +408,8 @@ rpcsvc_actor_t quotad_aggregator_actors[] = { DRC_NA}, [GF_AGGREGATOR_LOOKUP] = {"LOOKUP", GF_AGGREGATOR_NULL, quotad_aggregator_lookup, NULL, 0, DRC_NA}, + [GF_AGGREGATOR_GETLIMIT] = {"GETLIMIT", GF_AGGREGATOR_GETLIMIT, + quotad_aggregator_getlimit, NULL, 0}, }; diff --git a/xlators/features/quota/src/quotad-aggregator.h b/xlators/features/quota/src/quotad-aggregator.h index ac5eb76b..5ddea5b3 100644 --- a/xlators/features/quota/src/quotad-aggregator.h +++ b/xlators/features/quota/src/quotad-aggregator.h @@ -27,7 +27,7 @@ typedef struct { typedef int (*quotad_aggregator_lookup_cbk_t) (xlator_t *this, call_frame_t *frame, - struct gfs3_lookup_rsp *rsp); + void *rsp); int qd_nameless_lookup (xlator_t *this, call_frame_t *frame, gfs3_lookup_req *req, dict_t *xdata, quotad_aggregator_lookup_cbk_t lookup_cbk); |