/*
Copyright (c) 2007-2012 Red Hat, Inc. <http://www.redhat.com>
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 <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <signal.h>
#include "glusterfs.h"
#include "dict.h"
#include "event.h"
#include "defaults.h"
#include "rpc-clnt.h"
#include "protocol-common.h"
#include "glusterfsd-messages.h"
#include "glusterfs3.h"
#include "portmap-xdr.h"
#include "xdr-generic.h"
#include "glusterfsd.h"
#include "rpcsvc.h"
#include "cli1-xdr.h"
#include "statedump.h"
#include "syncop.h"
#include "xlator.h"
#include "syscall.h"
#include "monitoring.h"
static gf_boolean_t is_mgmt_rpc_reconnect = _gf_false;
int need_emancipate = 0;
int glusterfs_mgmt_pmap_signin (glusterfs_ctx_t *ctx);
int glusterfs_volfile_fetch (glusterfs_ctx_t *ctx);
int glusterfs_process_volfp (glusterfs_ctx_t *ctx, FILE *fp);
int glusterfs_graph_unknown_options (glusterfs_graph_t *graph);
int emancipate(glusterfs_ctx_t *ctx, int ret);
int
mgmt_cbk_spec (struct rpc_clnt *rpc, void *mydata, void *data)
{
glusterfs_ctx_t *ctx = NULL;
ctx = glusterfsd_ctx;
gf_log ("mgmt", GF_LOG_INFO, "Volume file changed");
glusterfs_volfile_fetch (ctx);
return 0;
}
int
mgmt_cbk_event (struct rpc_clnt *rpc, void *mydata, void *data)
{
return 0;
}
struct iobuf *
glusterfs_serialize_reply (rpcsvc_request_t *req, void *arg,
struct iovec *outmsg, xdrproc_t xdrproc)
{
struct iobuf *iob = NULL;
ssize_t retlen = -1;
ssize_t xdr_size = 0;
/* First, get the io buffer into which the reply in arg will
* be serialized.
*/
xdr_size = xdr_sizeof (xdrproc, arg);
iob = iobuf_get2 (req->svc->ctx->iobuf_pool, xdr_size);
if (!iob) {
gf_log (THIS->name, GF_LOG_ERROR, "Failed to get iobuf");
goto ret;
}
iobuf_to_iovec (iob, outmsg);
/* Use the given serializer to translate the give C structure in arg
* to XDR format which will be written into the buffer in outmsg.
*/
/* retlen is used to received the error since size_t is unsigned and we
* need -1 for error notification during encoding.
*/
retlen = xdr_serialize_generic (*outmsg, arg, xdrproc);
if (retlen == -1) {
gf_log (THIS->name, GF_LOG_ERROR, "Failed to encode message");
goto ret;
}
outmsg->iov_len = retlen;
ret:
if (retlen == -1) {
iob = NULL;
}
return iob;
}
int
glusterfs_submit_reply (rpcsvc_request_t *req, void *arg,
struct iovec *payload, int payloadcount,
struct iobref *iobref, xdrproc_t xdrproc)
{
struct iobuf *iob = NULL;
int ret = -1;
struct iovec rsp = {0,};
char new_iobref = 0;
if (!req) {
GF_ASSERT (req);
goto out;
}
if (!iobref) {
iobref = iobref_new ();
if (!iobref) {
gf_log (THIS->name, GF_LOG_ERROR, "out of memory");
goto out;
}
new_iobref = 1;
}
iob = glusterfs_serialize_reply (req, arg, &rsp, xdrproc);
if (!iob) {
gf_log_callingfn (THIS->name, GF_LOG_ERROR, "Failed to serialize reply");
} else {
iobref_add (iobref, iob);
}
ret = rpcsvc_submit_generic (req, &rsp, 1, payload, payloadcount,
iobref);
/* Now that we've done our job of handing the message to the RPC layer
* we can safely unref the iob in the hope that RPC layer must have
* ref'ed the iob on receiving into the txlist.
*/
if (ret == -1) {
gf_log (THIS->name, GF_LOG_ERROR, "Reply submission failed");
goto out;
}
ret = 0;
out:
if (iob)
iobuf_unref (iob);
if (new_iobref && iobref)
iobref_unref (iobref);
return ret;
}
int
glusterfs_terminate_response_send (rpcsvc_request_t *req, int op_ret)
{
gd1_mgmt_brick_op_rsp rsp = {0,};
dict_t *dict = NULL;
int ret = 0;
rsp.op_ret = op_ret;
rsp.op_errno = 0;
rsp.op_errstr = "";
dict = dict_new ();
if (dict)
ret = dict_allocate_and_serialize (dict, &rsp.output.output_val,
&rsp.output.output_len);
if (ret == 0)
ret = glusterfs_submit_reply (req, &rsp, NULL, 0, NULL,
(xdrproc_t)xdr_gd1_mgmt_brick_op_rsp);
GF_FREE (rsp.output.output_val);
if (dict)
dict_unref (dict);
return ret;
}
void
glusterfs_autoscale_threads (glusterfs_ctx_t *ctx, int incr)
{
struct event_pool *pool = ctx->event_pool;
pool->auto_thread_count += incr;
(void) event_reconfigure_threads (pool, pool->eventthreadcount+incr);
}
int
glusterfs_handle_terminate (rpcsvc_request_t *req)
{
gd1_mgmt_brick_op_req xlator_req = {0,};
ssize_t ret;
glusterfs_ctx_t *ctx = NULL;
xlator_t *top = NULL;
xlator_t *victim = NULL;
xlator_list_t **trav_p = NULL;
gf_boolean_t lockflag = _gf_false;
ret = xdr_to_generic (req->msg[0], &xlator_req,
(xdrproc_t)xdr_gd1_mgmt_brick_op_req);
if (ret < 0) {
req->rpc_err = GARBAGE_ARGS;
return -1;
}
ctx = glusterfsd_ctx;
LOCK (&ctx->volfile_lock);
{
/* Find the xlator_list_t that points to our victim. */
if (glusterfsd_ctx->active) {
top = glusterfsd_ctx->active->first;
for (trav_p = &top->children; *trav_p;
trav_p = &(*trav_p)->next) {
victim = (*trav_p)->xlator;
if (strcmp (victim->name, xlator_req.name) == 0) {
break;
}
}
}
}
|