/* Copyright (c) 2018 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #include "portmap-xdr.h" #include "protocol-common.h" #include "rpc-clnt.h" #include "xdr-generic.h" /* Defining a minimal RPC client program for portmap signout */ char *clnt_pmap_signout_procs[GF_PMAP_MAXVALUE] = { [GF_PMAP_SIGNOUT] = "SIGNOUT", }; rpc_clnt_prog_t clnt_pmap_signout_prog = { .progname = "Gluster Portmap", .prognum = GLUSTER_PMAP_PROGRAM, .progver = GLUSTER_PMAP_VERSION, .procnames = clnt_pmap_signout_procs, }; static int mgmt_pmap_signout_cbk(struct rpc_req *req, struct iovec *iov, int count, void *myframe) { pmap_signout_rsp rsp = { 0, }; int ret = 0; call_frame_t *frame = NULL; frame = myframe; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_pmap_signout_rsp); if (ret < 0) { gf_log(THIS->name, GF_LOG_ERROR, "XDR decoding failed"); rsp.op_ret = -1; rsp.op_errno = EINVAL; goto out; } if (-1 == rsp.op_ret) { gf_log(THIS->name, GF_LOG_ERROR, "failed to register the port with glusterd"); goto out; } out: if (frame) { STACK_DESTROY(frame->root); } return 0; } int rpc_clnt_mgmt_pmap_signout(glusterfs_ctx_t *ctx, char *brickname) { int ret = 0; pmap_signout_req req = { 0, }; call_frame_t *frame = NULL; cmd_args_t *cmd_args = NULL; char brick_name[PATH_MAX] = { 0, }; struct iovec iov = { 0, }; struct iobuf *iobuf = NULL; struct iobref *iobref = NULL; ssize_t xdr_size = 0; frame = create_frame(THIS, ctx->pool); cmd_args = &ctx->cmd_args; if (!cmd_args->brick_port && (!cmd_args->brick_name || !brickname)) { gf_log("fsd-mgmt", GF_LOG_DEBUG, "portmapper signout arguments not given"); goto out; } if (cmd_args->volfile_server_transport && !strcmp(cmd_args->volfile_server_transport, "rdma")) { snprintf(brick_name, sizeof(brick_name), "%s.rdma", cmd_args->brick_name); req.brick = brick_name; } else { if (brickname) req.brick = brickname; else req.brick = cmd_args->brick_name; } req.port = cmd_args->brick_port; req.rdma_port = cmd_args->brick_port2; /* mgmt_submit_request is not available in libglusterfs. * Need to serialize and submit manually. */ iobref = iobref_new(); if (!iobref) { goto out; } xdr_size = xdr_sizeof((xdrproc_t)xdr_pmap_signout_req, &req); iobuf = iobuf_get2(ctx->iobuf_pool, xdr_size); if (!iobuf) { goto out; }; iobref_add(iobref, iobuf); iov.iov_base = iobuf->ptr; iov.iov_len = iobuf_pagesize(iobuf); /* Create the xdr payload */ ret = xdr_serialize_generic(iov, &req, (xdrproc_t)xdr_pmap_signout_req); if (ret == -1) { gf_log(THIS->name, GF_LOG_WARNING, "failed to create XDR payload"); goto out; } iov.iov_len = ret; ret = rpc_clnt_submit(ctx->mgmt, &clnt_pmap_signout_prog, GF_PMAP_SIGNOUT, mgmt_pmap_signout_cbk, &iov, 1, NULL, 0, iobref, frame, NULL, 0, NULL, 0, NULL); out: if (iobref) iobref_unref(iobref); if (iobuf) iobuf_unref(iobuf); return ret; }