|
Packit Service |
e080da |
/*
|
|
Packit Service |
e080da |
Copyright (c) 2012-2018 Red Hat, Inc. <http://www.redhat.com>
|
|
Packit Service |
e080da |
This file is part of GlusterFS.
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
This file is licensed to you under your choice of the GNU Lesser
|
|
Packit Service |
e080da |
General Public License, version 3 or any later version (LGPLv3 or
|
|
Packit Service |
e080da |
later), or the GNU General Public License, version 2 (GPLv2), in all
|
|
Packit Service |
e080da |
cases as published by the Free Software Foundation.
|
|
Packit Service |
e080da |
*/
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
#include <stdio.h>
|
|
Packit Service |
e080da |
#include <sys/types.h>
|
|
Packit Service |
e080da |
#include <sys/wait.h>
|
|
Packit Service |
e080da |
#include <stdlib.h>
|
|
Packit Service |
e080da |
#include <signal.h>
|
|
Packit Service |
e080da |
#include <pthread.h>
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
#include <glusterfs/glusterfs.h>
|
|
Packit Service |
e080da |
#include "glfs.h"
|
|
Packit Service |
e080da |
#include <glusterfs/dict.h>
|
|
Packit Service |
e080da |
#include <glusterfs/gf-event.h>
|
|
Packit Service |
e080da |
#include <glusterfs/defaults.h>
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
#include "rpc-clnt.h"
|
|
Packit Service |
e080da |
#include "protocol-common.h"
|
|
Packit Service |
e080da |
#include "glusterfs3.h"
|
|
Packit Service |
e080da |
#include "portmap-xdr.h"
|
|
Packit Service |
e080da |
#include "xdr-common.h"
|
|
Packit Service |
e080da |
#include "xdr-generic.h"
|
|
Packit Service |
e080da |
#include "rpc-common-xdr.h"
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
#include <glusterfs/syncop.h>
|
|
Packit Service |
e080da |
#include <glusterfs/xlator.h>
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
#include "glfs-internal.h"
|
|
Packit Service |
e080da |
#include "glfs-mem-types.h"
|
|
Packit Service |
e080da |
#include "gfapi-messages.h"
|
|
Packit Service |
e080da |
#include <glusterfs/syscall.h>
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
int
|
|
Packit Service |
e080da |
glfs_volfile_fetch(struct glfs *fs);
|
|
Packit Service |
e080da |
int32_t
|
|
Packit Service |
e080da |
glfs_get_volume_info_rpc(call_frame_t *frame, xlator_t *this, struct glfs *fs);
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
int
|
|
Packit Service |
e080da |
glfs_process_volfp(struct glfs *fs, FILE *fp)
|
|
Packit Service |
e080da |
{
|
|
Packit Service |
e080da |
glusterfs_graph_t *graph = NULL;
|
|
Packit Service |
e080da |
int ret = -1;
|
|
Packit Service |
e080da |
xlator_t *trav = NULL;
|
|
Packit Service |
e080da |
glusterfs_ctx_t *ctx = NULL;
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
ctx = fs->ctx;
|
|
Packit Service |
e080da |
graph = glusterfs_graph_construct(fp);
|
|
Packit Service |
e080da |
if (!graph) {
|
|
Packit Service |
e080da |
gf_msg("glfs", GF_LOG_ERROR, errno, API_MSG_GRAPH_CONSTRUCT_FAILED,
|
|
Packit Service |
e080da |
"failed to construct the graph");
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
for (trav = graph->first; trav; trav = trav->next) {
|
|
Packit Service |
e080da |
if (strcmp(trav->type, "mount/api") == 0) {
|
|
Packit Service |
e080da |
gf_msg("glfs", GF_LOG_ERROR, EINVAL, API_MSG_API_XLATOR_ERROR,
|
|
Packit Service |
e080da |
"api master xlator cannot be specified "
|
|
Packit Service |
e080da |
"in volume file");
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
ret = glusterfs_graph_prepare(graph, ctx, fs->volname);
|
|
Packit Service |
e080da |
if (ret) {
|
|
Packit Service |
e080da |
glusterfs_graph_destroy(graph);
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
ret = glusterfs_graph_activate(graph, ctx);
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if (ret) {
|
|
Packit Service |
e080da |
glusterfs_graph_destroy(graph);
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
gf_log_dump_graph(fp, graph);
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
ret = 0;
|
|
Packit Service |
e080da |
out:
|
|
Packit Service |
e080da |
if (fp)
|
|
Packit Service |
e080da |
fclose(fp);
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if (!ctx->active) {
|
|
Packit Service |
e080da |
ret = -1;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
return ret;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
int
|
|
Packit Service |
e080da |
mgmt_cbk_spec(struct rpc_clnt *rpc, void *mydata, void *data)
|
|
Packit Service |
e080da |
{
|
|
Packit Service |
e080da |
struct glfs *fs = NULL;
|
|
Packit Service |
e080da |
xlator_t *this = NULL;
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
this = mydata;
|
|
Packit Service |
e080da |
fs = this->private;
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
glfs_volfile_fetch(fs);
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
return 0;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
int
|
|
Packit Service |
e080da |
mgmt_cbk_event(struct rpc_clnt *rpc, void *mydata, void *data)
|
|
Packit Service |
e080da |
{
|
|
Packit Service |
e080da |
return 0;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
static int
|
|
Packit Service |
e080da |
mgmt_cbk_statedump(struct rpc_clnt *rpc, void *mydata, void *data)
|
|
Packit Service |
e080da |
{
|
|
Packit Service |
e080da |
struct glfs *fs = NULL;
|
|
Packit Service |
e080da |
xlator_t *this = NULL;
|
|
Packit Service |
e080da |
gf_statedump target_pid = {
|
|
Packit Service |
e080da |
0,
|
|
Packit Service |
e080da |
};
|
|
Packit Service |
e080da |
struct iovec *iov = NULL;
|
|
Packit Service |
e080da |
int ret = -1;
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
this = mydata;
|
|
Packit Service |
e080da |
if (!this) {
|
|
Packit Service |
e080da |
gf_msg("glfs", GF_LOG_ERROR, EINVAL, API_MSG_STATEDUMP_FAILED,
|
|
Packit Service |
e080da |
"NULL mydata");
|
|
Packit Service |
e080da |
errno = EINVAL;
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
fs = this->private;
|
|
Packit Service |
e080da |
if (!fs) {
|
|
Packit Service |
e080da |
gf_msg("glfs", GF_LOG_ERROR, EINVAL, API_MSG_STATEDUMP_FAILED,
|
|
Packit Service |
e080da |
"NULL glfs");
|
|
Packit Service |
e080da |
errno = EINVAL;
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
iov = (struct iovec *)data;
|
|
Packit Service |
e080da |
if (!iov) {
|
|
Packit Service |
e080da |
gf_msg("glfs", GF_LOG_ERROR, EINVAL, API_MSG_STATEDUMP_FAILED,
|
|
Packit Service |
e080da |
"NULL iovec data");
|
|
Packit Service |
e080da |
errno = EINVAL;
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
ret = xdr_to_generic(*iov, &target_pid, (xdrproc_t)xdr_gf_statedump);
|
|
Packit Service |
e080da |
if (ret < 0) {
|
|
Packit Service |
e080da |
gf_msg("glfs", GF_LOG_ERROR, EINVAL, API_MSG_STATEDUMP_FAILED,
|
|
Packit Service |
e080da |
"Failed to decode xdr response for GF_CBK_STATEDUMP");
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
gf_msg_trace("glfs", 0, "statedump requested for pid: %d", target_pid.pid);
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if ((uint64_t)getpid() == target_pid.pid) {
|
|
Packit Service |
e080da |
gf_msg_debug("glfs", 0, "Taking statedump for pid: %d", target_pid.pid);
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
ret = glfs_sysrq(fs, GLFS_SYSRQ_STATEDUMP);
|
|
Packit Service |
e080da |
if (ret < 0) {
|
|
Packit Service |
e080da |
gf_msg("glfs", GF_LOG_INFO, 0, API_MSG_STATEDUMP_FAILED,
|
|
Packit Service |
e080da |
"statedump failed");
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
out:
|
|
Packit Service |
e080da |
return ret;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
rpcclnt_cb_actor_t mgmt_cbk_actors[GF_CBK_MAXVALUE] = {
|
|
Packit Service |
e080da |
[GF_CBK_FETCHSPEC] = {"FETCHSPEC", GF_CBK_FETCHSPEC, mgmt_cbk_spec},
|
|
Packit Service |
e080da |
[GF_CBK_EVENT_NOTIFY] = {"EVENTNOTIFY", GF_CBK_EVENT_NOTIFY,
|
|
Packit Service |
e080da |
mgmt_cbk_event},
|
|
Packit Service |
e080da |
[GF_CBK_STATEDUMP] = {"STATEDUMP", GF_CBK_STATEDUMP, mgmt_cbk_statedump},
|
|
Packit Service |
e080da |
};
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
struct rpcclnt_cb_program mgmt_cbk_prog = {
|
|
Packit Service |
e080da |
.progname = "GlusterFS Callback",
|
|
Packit Service |
e080da |
.prognum = GLUSTER_CBK_PROGRAM,
|
|
Packit Service |
e080da |
.progver = GLUSTER_CBK_VERSION,
|
|
Packit Service |
e080da |
.actors = mgmt_cbk_actors,
|
|
Packit Service |
e080da |
.numactors = GF_CBK_MAXVALUE,
|
|
Packit Service |
e080da |
};
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
char *clnt_handshake_procs[GF_HNDSK_MAXVALUE] = {
|
|
Packit Service |
e080da |
[GF_HNDSK_NULL] = "NULL",
|
|
Packit Service |
e080da |
[GF_HNDSK_SETVOLUME] = "SETVOLUME",
|
|
Packit Service |
e080da |
[GF_HNDSK_GETSPEC] = "GETSPEC",
|
|
Packit Service |
e080da |
[GF_HNDSK_PING] = "PING",
|
|
Packit Service |
e080da |
[GF_HNDSK_EVENT_NOTIFY] = "EVENTNOTIFY",
|
|
Packit Service |
e080da |
[GF_HNDSK_GET_VOLUME_INFO] = "GETVOLUMEINFO",
|
|
Packit Service |
e080da |
};
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
rpc_clnt_prog_t clnt_handshake_prog = {
|
|
Packit Service |
e080da |
.progname = "GlusterFS Handshake",
|
|
Packit Service |
e080da |
.prognum = GLUSTER_HNDSK_PROGRAM,
|
|
Packit Service |
e080da |
.progver = GLUSTER_HNDSK_VERSION,
|
|
Packit Service |
e080da |
.procnames = clnt_handshake_procs,
|
|
Packit Service |
e080da |
};
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
int
|
|
Packit Service |
e080da |
mgmt_submit_request(void *req, call_frame_t *frame, glusterfs_ctx_t *ctx,
|
|
Packit Service |
e080da |
rpc_clnt_prog_t *prog, int procnum, fop_cbk_fn_t cbkfn,
|
|
Packit Service |
e080da |
xdrproc_t xdrproc)
|
|
Packit Service |
e080da |
{
|
|
Packit Service |
e080da |
int ret = -1;
|
|
Packit Service |
e080da |
int count = 0;
|
|
Packit Service |
e080da |
struct iovec iov = {
|
|
Packit Service |
e080da |
0,
|
|
Packit Service |
e080da |
};
|
|
Packit Service |
e080da |
struct iobuf *iobuf = NULL;
|
|
Packit Service |
e080da |
struct iobref *iobref = NULL;
|
|
Packit Service |
e080da |
ssize_t xdr_size = 0;
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
iobref = iobref_new();
|
|
Packit Service |
e080da |
if (!iobref) {
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if (req) {
|
|
Packit Service |
e080da |
xdr_size = xdr_sizeof(xdrproc, req);
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
iobuf = iobuf_get2(ctx->iobuf_pool, xdr_size);
|
|
Packit Service |
e080da |
if (!iobuf) {
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
};
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
iobref_add(iobref, iobuf);
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
iov.iov_base = iobuf->ptr;
|
|
Packit Service |
e080da |
iov.iov_len = iobuf_pagesize(iobuf);
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
/* Create the xdr payload */
|
|
Packit Service |
e080da |
ret = xdr_serialize_generic(iov, req, xdrproc);
|
|
Packit Service |
e080da |
if (ret == -1) {
|
|
Packit Service |
e080da |
gf_msg(THIS->name, GF_LOG_WARNING, 0, API_MSG_XDR_PAYLOAD_FAILED,
|
|
Packit Service |
e080da |
"failed to create XDR payload");
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
iov.iov_len = ret;
|
|
Packit Service |
e080da |
count = 1;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
/* Send the msg */
|
|
Packit Service |
e080da |
ret = rpc_clnt_submit(ctx->mgmt, prog, procnum, cbkfn, &iov, count, NULL, 0,
|
|
Packit Service |
e080da |
iobref, frame, NULL, 0, NULL, 0, NULL);
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
out:
|
|
Packit Service |
e080da |
if (iobref)
|
|
Packit Service |
e080da |
iobref_unref(iobref);
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if (iobuf)
|
|
Packit Service |
e080da |
iobuf_unref(iobuf);
|
|
Packit Service |
e080da |
return ret;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
/*
|
|
Packit Service |
e080da |
* Callback routine for 'GF_HNDSK_GET_VOLUME_INFO' rpc request
|
|
Packit Service |
e080da |
*/
|
|
Packit Service |
e080da |
int
|
|
Packit Service |
e080da |
mgmt_get_volinfo_cbk(struct rpc_req *req, struct iovec *iov, int count,
|
|
Packit Service |
e080da |
void *myframe)
|
|
Packit Service |
e080da |
{
|
|
Packit Service |
e080da |
int ret = 0;
|
|
Packit Service |
e080da |
char *volume_id_str = NULL;
|
|
Packit Service |
e080da |
dict_t *dict = NULL;
|
|
Packit Service |
e080da |
char key[1024] = {0};
|
|
Packit Service |
e080da |
gf_get_volume_info_rsp rsp = {
|
|
Packit Service |
e080da |
0,
|
|
Packit Service |
e080da |
};
|
|
Packit Service |
e080da |
call_frame_t *frame = NULL;
|
|
Packit Service |
e080da |
glusterfs_ctx_t *ctx = NULL;
|
|
Packit Service |
e080da |
struct glfs *fs = NULL;
|
|
Packit Service |
e080da |
struct syncargs *args;
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
frame = myframe;
|
|
Packit Service |
e080da |
ctx = frame->this->ctx;
|
|
Packit Service |
e080da |
args = frame->local;
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if (!ctx) {
|
|
Packit Service |
e080da |
gf_msg(frame->this->name, GF_LOG_ERROR, EINVAL, API_MSG_INVALID_ENTRY,
|
|
Packit Service |
e080da |
"NULL context");
|
|
Packit Service |
e080da |
errno = EINVAL;
|
|
Packit Service |
e080da |
ret = -1;
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
fs = ((xlator_t *)ctx->master)->private;
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if (-1 == req->rpc_status) {
|
|
Packit Service |
e080da |
gf_msg(frame->this->name, GF_LOG_ERROR, EINVAL, API_MSG_INVALID_ENTRY,
|
|
Packit Service |
e080da |
"GET_VOLUME_INFO RPC call is not successful");
|
|
Packit Service |
e080da |
errno = EINVAL;
|
|
Packit Service |
e080da |
ret = -1;
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_get_volume_info_rsp);
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if (ret < 0) {
|
|
Packit Service |
e080da |
gf_msg(frame->this->name, GF_LOG_ERROR, 0,
|
|
Packit Service |
e080da |
API_MSG_XDR_RESPONSE_DECODE_FAILED,
|
|
Packit Service |
e080da |
"Failed to decode xdr response for GET_VOLUME_INFO");
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
gf_msg_debug(frame->this->name, 0,
|
|
Packit Service |
e080da |
"Received resp to GET_VOLUME_INFO "
|
|
Packit Service |
e080da |
"RPC: %d",
|
|
Packit Service |
e080da |
rsp.op_ret);
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if (rsp.op_ret == -1) {
|
|
Packit Service |
e080da |
errno = rsp.op_errno;
|
|
Packit Service |
e080da |
ret = -1;
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if (!rsp.dict.dict_len) {
|
|
Packit Service |
e080da |
gf_msg(frame->this->name, GF_LOG_ERROR, EINVAL, API_MSG_INVALID_ENTRY,
|
|
Packit Service |
e080da |
"Response received for "
|
|
Packit Service |
e080da |
"GET_VOLUME_INFO RPC call is not valid");
|
|
Packit Service |
e080da |
ret = -1;
|
|
Packit Service |
e080da |
errno = EINVAL;
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
dict = dict_new();
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if (!dict) {
|
|
Packit Service |
e080da |
ret = -1;
|
|
Packit Service |
e080da |
errno = ENOMEM;
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
ret = dict_unserialize(rsp.dict.dict_val, rsp.dict.dict_len, &dict);
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if (ret) {
|
|
Packit Service |
e080da |
errno = ENOMEM;
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
snprintf(key, sizeof(key), "volume_id");
|
|
Packit Service |
e080da |
ret = dict_get_str(dict, key, &volume_id_str);
|
|
Packit Service |
e080da |
if (ret) {
|
|
Packit Service |
e080da |
errno = EINVAL;
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
ret = 0;
|
|
Packit Service |
e080da |
out:
|
|
Packit Service |
e080da |
if (volume_id_str) {
|
|
Packit Service |
e080da |
gf_msg_debug(frame->this->name, 0, "Volume Id: %s", volume_id_str);
|
|
Packit Service |
e080da |
pthread_mutex_lock(&fs->mutex);
|
|
Packit Service |
e080da |
gf_uuid_parse(volume_id_str, fs->vol_uuid);
|
|
Packit Service |
e080da |
pthread_mutex_unlock(&fs->mutex);
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if (ret) {
|
|
Packit Service |
e080da |
gf_msg(frame->this->name, GF_LOG_ERROR, errno,
|
|
Packit Service |
e080da |
API_MSG_GET_VOLINFO_CBK_FAILED,
|
|
Packit Service |
e080da |
"In GET_VOLUME_INFO "
|
|
Packit Service |
e080da |
"cbk, received error: %s",
|
|
Packit Service |
e080da |
strerror(errno));
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if (dict)
|
|
Packit Service |
e080da |
dict_unref(dict);
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if (rsp.dict.dict_val)
|
|
Packit Service |
e080da |
free(rsp.dict.dict_val);
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if (rsp.op_errstr)
|
|
Packit Service |
e080da |
free(rsp.op_errstr);
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
gf_msg_debug(frame->this->name, 0, "Returning: %d", ret);
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
__wake(args);
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
return ret;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
int
|
|
Packit Service |
e080da |
pub_glfs_get_volumeid(struct glfs *fs, char *volid, size_t size)
|
|
Packit Service |
e080da |
{
|
|
Packit Service |
e080da |
/* TODO: Define a global macro to store UUID size */
|
|
Packit Service |
e080da |
size_t uuid_size = 16;
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
DECLARE_OLD_THIS;
|
|
Packit Service |
e080da |
__GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
pthread_mutex_lock(&fs->mutex);
|
|
Packit Service |
e080da |
{
|
|
Packit Service |
e080da |
/* check if the volume uuid is initialized */
|
|
Packit Service |
e080da |
if (!gf_uuid_is_null(fs->vol_uuid)) {
|
|
Packit Service |
e080da |
pthread_mutex_unlock(&fs->mutex);
|
|
Packit Service |
e080da |
goto done;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
pthread_mutex_unlock(&fs->mutex);
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
/* Need to fetch volume_uuid */
|
|
Packit Service |
e080da |
glfs_get_volume_info(fs);
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if (gf_uuid_is_null(fs->vol_uuid)) {
|
|
Packit Service |
e080da |
gf_msg(THIS->name, GF_LOG_ERROR, EINVAL, API_MSG_FETCH_VOLUUID_FAILED,
|
|
Packit Service |
e080da |
"Unable to fetch "
|
|
Packit Service |
e080da |
"volume UUID");
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
done:
|
|
Packit Service |
e080da |
if (!volid || !size) {
|
|
Packit Service |
e080da |
gf_msg_debug(THIS->name, 0, "volumeid/size is null");
|
|
Packit Service |
e080da |
__GLFS_EXIT_FS;
|
|
Packit Service |
e080da |
return uuid_size;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if (size < uuid_size) {
|
|
Packit Service |
e080da |
gf_msg(THIS->name, GF_LOG_ERROR, ERANGE, API_MSG_INSUFF_SIZE,
|
|
Packit Service |
e080da |
"Insufficient size passed");
|
|
Packit Service |
e080da |
errno = ERANGE;
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
memcpy(volid, fs->vol_uuid, uuid_size);
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
__GLFS_EXIT_FS;
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
return uuid_size;
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
out:
|
|
Packit Service |
e080da |
__GLFS_EXIT_FS;
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
invalid_fs:
|
|
Packit Service |
e080da |
return -1;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_get_volumeid, 3.5.0);
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
int
|
|
Packit Service |
e080da |
glfs_get_volume_info(struct glfs *fs)
|
|
Packit Service |
e080da |
{
|
|
Packit Service |
e080da |
call_frame_t *frame = NULL;
|
|
Packit Service |
e080da |
glusterfs_ctx_t *ctx = NULL;
|
|
Packit Service |
e080da |
struct syncargs args = {
|
|
Packit Service |
e080da |
0,
|
|
Packit Service |
e080da |
};
|
|
Packit Service |
e080da |
int ret = 0;
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
ctx = fs->ctx;
|
|
Packit Service |
e080da |
frame = create_frame(THIS, ctx->pool);
|
|
Packit Service |
e080da |
if (!frame) {
|
|
Packit Service |
e080da |
gf_msg("glfs", GF_LOG_ERROR, ENOMEM, API_MSG_FRAME_CREAT_FAILED,
|
|
Packit Service |
e080da |
"failed to create the frame");
|
|
Packit Service |
e080da |
ret = -1;
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
frame->local = &arg;;
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
__yawn((&args));
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
ret = glfs_get_volume_info_rpc(frame, THIS, fs);
|
|
Packit Service |
e080da |
if (ret)
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
__yield((&args));
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
frame->local = NULL;
|
|
Packit Service |
e080da |
STACK_DESTROY(frame->root);
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
out:
|
|
Packit Service |
e080da |
return ret;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
int32_t
|
|
Packit Service |
e080da |
glfs_get_volume_info_rpc(call_frame_t *frame, xlator_t *this, struct glfs *fs)
|
|
Packit Service |
e080da |
{
|
|
Packit Service |
e080da |
gf_get_volume_info_req req = {{
|
|
Packit Service |
e080da |
0,
|
|
Packit Service |
e080da |
}};
|
|
Packit Service |
e080da |
int ret = 0;
|
|
Packit Service |
e080da |
glusterfs_ctx_t *ctx = NULL;
|
|
Packit Service |
e080da |
dict_t *dict = NULL;
|
|
Packit Service |
e080da |
int32_t flags = 0;
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if (!frame || !this || !fs) {
|
|
Packit Service |
e080da |
ret = -1;
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
ctx = fs->ctx;
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
dict = dict_new();
|
|
Packit Service |
e080da |
if (!dict) {
|
|
Packit Service |
e080da |
ret = -1;
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if (fs->volname) {
|
|
Packit Service |
e080da |
ret = dict_set_str(dict, "volname", fs->volname);
|
|
Packit Service |
e080da |
if (ret)
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
// Set the flags for the fields which we are interested in
|
|
Packit Service |
e080da |
flags = (int32_t)GF_GET_VOLUME_UUID; // ctx->flags;
|
|
Packit Service |
e080da |
ret = dict_set_int32(dict, "flags", flags);
|
|
Packit Service |
e080da |
if (ret) {
|
|
Packit Service |
e080da |
gf_msg(frame->this->name, GF_LOG_ERROR, EINVAL, API_MSG_DICT_SET_FAILED,
|
|
Packit Service |
e080da |
"failed to set flags");
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
ret = dict_allocate_and_serialize(dict, &req.dict.dict_val,
|
|
Packit Service |
e080da |
&req.dict.dict_len);
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
ret = mgmt_submit_request(&req, frame, ctx, &clnt_handshake_prog,
|
|
Packit Service |
e080da |
GF_HNDSK_GET_VOLUME_INFO, mgmt_get_volinfo_cbk,
|
|
Packit Service |
e080da |
(xdrproc_t)xdr_gf_get_volume_info_req);
|
|
Packit Service |
e080da |
out:
|
|
Packit Service |
e080da |
if (dict) {
|
|
Packit Service |
e080da |
dict_unref(dict);
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
GF_FREE(req.dict.dict_val);
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
return ret;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
static int
|
|
Packit Service |
e080da |
glusterfs_oldvolfile_update(struct glfs *fs, char *volfile, ssize_t size)
|
|
Packit Service |
e080da |
{
|
|
Packit Service |
e080da |
int ret = -1;
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
pthread_mutex_lock(&fs->mutex);
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
fs->oldvollen = size;
|
|
Packit Service |
e080da |
if (!fs->oldvolfile) {
|
|
Packit Service |
e080da |
fs->oldvolfile = CALLOC(1, size + 1);
|
|
Packit Service |
e080da |
} else {
|
|
Packit Service |
e080da |
fs->oldvolfile = REALLOC(fs->oldvolfile, size + 1);
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if (!fs->oldvolfile) {
|
|
Packit Service |
e080da |
fs->oldvollen = 0;
|
|
Packit Service |
e080da |
} else {
|
|
Packit Service |
e080da |
memcpy(fs->oldvolfile, volfile, size);
|
|
Packit Service |
e080da |
fs->oldvollen = size;
|
|
Packit Service |
e080da |
ret = 0;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
pthread_mutex_unlock(&fs->mutex);
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
return ret;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
int
|
|
Packit Service |
e080da |
glfs_mgmt_getspec_cbk(struct rpc_req *req, struct iovec *iov, int count,
|
|
Packit Service |
e080da |
void *myframe)
|
|
Packit Service |
e080da |
{
|
|
Packit Service |
e080da |
gf_getspec_rsp rsp = {
|
|
Packit Service |
e080da |
0,
|
|
Packit Service |
e080da |
};
|
|
Packit Service |
e080da |
call_frame_t *frame = NULL;
|
|
Packit Service |
e080da |
glusterfs_ctx_t *ctx = NULL;
|
|
Packit Service |
e080da |
int ret = 0;
|
|
Packit Service |
e080da |
ssize_t size = 0;
|
|
Packit Service |
e080da |
FILE *tmpfp = NULL;
|
|
Packit Service |
e080da |
int need_retry = 0;
|
|
Packit Service |
e080da |
struct glfs *fs = NULL;
|
|
Packit Service |
e080da |
dict_t *dict = NULL;
|
|
Packit Service |
e080da |
char *servers_list = NULL;
|
|
Packit Service |
e080da |
int tmp_fd = -1;
|
|
Packit Service |
e080da |
char template[] = "/tmp/gfapi.volfile.XXXXXX";
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
frame = myframe;
|
|
Packit Service |
e080da |
ctx = frame->this->ctx;
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if (!ctx) {
|
|
Packit Service |
e080da |
gf_msg(frame->this->name, GF_LOG_ERROR, EINVAL, API_MSG_INVALID_ENTRY,
|
|
Packit Service |
e080da |
"NULL context");
|
|
Packit Service |
e080da |
errno = EINVAL;
|
|
Packit Service |
e080da |
ret = -1;
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
fs = ((xlator_t *)ctx->master)->private;
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if (-1 == req->rpc_status) {
|
|
Packit Service |
e080da |
ret = -1;
|
|
Packit Service |
e080da |
need_retry = 1;
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_getspec_rsp);
|
|
Packit Service |
e080da |
if (ret < 0) {
|
|
Packit Service |
e080da |
gf_msg(frame->this->name, GF_LOG_ERROR, 0, API_MSG_XDR_DECODE_FAILED,
|
|
Packit Service |
e080da |
"XDR decoding error");
|
|
Packit Service |
e080da |
ret = -1;
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if (-1 == rsp.op_ret) {
|
|
Packit Service |
e080da |
gf_msg(frame->this->name, GF_LOG_ERROR, rsp.op_errno,
|
|
Packit Service |
e080da |
API_MSG_GET_VOLFILE_FAILED,
|
|
Packit Service |
e080da |
"failed to get the 'volume file' from server");
|
|
Packit Service |
e080da |
ret = -1;
|
|
Packit Service |
e080da |
errno = rsp.op_errno;
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if (!rsp.xdata.xdata_len) {
|
|
Packit Service |
e080da |
goto volfile;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
dict = dict_new();
|
|
Packit Service |
e080da |
if (!dict) {
|
|
Packit Service |
e080da |
ret = -1;
|
|
Packit Service |
e080da |
errno = ENOMEM;
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
ret = dict_unserialize(rsp.xdata.xdata_val, rsp.xdata.xdata_len, &dict);
|
|
Packit Service |
e080da |
if (ret) {
|
|
Packit Service |
e080da |
gf_log(frame->this->name, GF_LOG_ERROR,
|
|
Packit Service |
e080da |
"failed to unserialize xdata to dictionary");
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
dict->extra_stdfree = rsp.xdata.xdata_val;
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
/* glusterd2 only */
|
|
Packit Service |
e080da |
ret = dict_get_str(dict, "servers-list", &servers_list);
|
|
Packit Service |
e080da |
if (ret) {
|
|
Packit Service |
e080da |
goto volfile;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
gf_log(frame->this->name, GF_LOG_INFO,
|
|
Packit Service |
e080da |
"Received list of available volfile servers: %s", servers_list);
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
ret = gf_process_getspec_servers_list(&ctx->cmd_args, servers_list);
|
|
Packit Service |
e080da |
if (ret) {
|
|
Packit Service |
e080da |
gf_log(frame->this->name, GF_LOG_ERROR,
|
|
Packit Service |
e080da |
"Failed (%s) to process servers list: %s", strerror(errno),
|
|
Packit Service |
e080da |
servers_list);
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
volfile:
|
|
Packit Service |
e080da |
ret = 0;
|
|
Packit Service |
e080da |
size = rsp.op_ret;
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
pthread_mutex_lock(&fs->mutex);
|
|
Packit Service |
e080da |
if ((size == fs->oldvollen) &&
|
|
Packit Service |
e080da |
(memcmp(fs->oldvolfile, rsp.spec, size) == 0)) {
|
|
Packit Service |
e080da |
pthread_mutex_unlock(&fs->mutex);
|
|
Packit Service |
e080da |
gf_msg(frame->this->name, GF_LOG_INFO, 0, API_MSG_VOLFILE_INFO,
|
|
Packit Service |
e080da |
"No change in volfile, continuing");
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
pthread_mutex_unlock(&fs->mutex);
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
/* coverity[secure_temp] mkstemp uses 0600 as the mode and is safe */
|
|
Packit Service |
e080da |
tmp_fd = mkstemp(template);
|
|
Packit Service |
e080da |
if (-1 == tmp_fd) {
|
|
Packit Service |
e080da |
ret = -1;
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
/* Calling unlink so that when the file is closed or program
|
|
Packit Service |
e080da |
* terminates the temporary file is deleted.
|
|
Packit Service |
e080da |
*/
|
|
Packit Service |
e080da |
ret = sys_unlink(template);
|
|
Packit Service |
e080da |
if (ret < 0) {
|
|
Packit Service |
e080da |
gf_msg(frame->this->name, GF_LOG_INFO, 0, API_MSG_VOLFILE_INFO,
|
|
Packit Service |
e080da |
"Unable to delete file: %s", template);
|
|
Packit Service |
e080da |
ret = 0;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
tmpfp = fdopen(tmp_fd, "w+b");
|
|
Packit Service |
e080da |
if (!tmpfp) {
|
|
Packit Service |
e080da |
ret = -1;
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
fwrite(rsp.spec, size, 1, tmpfp);
|
|
Packit Service |
e080da |
fflush(tmpfp);
|
|
Packit Service |
e080da |
if (ferror(tmpfp)) {
|
|
Packit Service |
e080da |
ret = -1;
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
/* Check if only options have changed. No need to reload the
|
|
Packit Service |
e080da |
* volfile if topology hasn't changed.
|
|
Packit Service |
e080da |
* glusterfs_volfile_reconfigure returns 3 possible return states
|
|
Packit Service |
e080da |
* return 0 =======> reconfiguration of options has succeeded
|
|
Packit Service |
e080da |
* return 1 =======> the graph has to be reconstructed and all
|
|
Packit Service |
e080da |
* the xlators should be inited return -1(or -ve) =======> Some Internal
|
|
Packit Service |
e080da |
* Error occurred during the operation
|
|
Packit Service |
e080da |
*/
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
pthread_mutex_lock(&fs->mutex);
|
|
Packit Service |
e080da |
ret = gf_volfile_reconfigure(fs->oldvollen, tmpfp, fs->ctx, fs->oldvolfile);
|
|
Packit Service |
e080da |
pthread_mutex_unlock(&fs->mutex);
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if (ret == 0) {
|
|
Packit Service |
e080da |
gf_msg_debug("glusterfsd-mgmt", 0,
|
|
Packit Service |
e080da |
"No need to re-load "
|
|
Packit Service |
e080da |
"volfile, reconfigure done");
|
|
Packit Service |
e080da |
ret = glusterfs_oldvolfile_update(fs, rsp.spec, size);
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if (ret < 0) {
|
|
Packit Service |
e080da |
gf_msg_debug("glusterfsd-mgmt", 0, "Reconfigure failed !!");
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
ret = glfs_process_volfp(fs, tmpfp);
|
|
Packit Service |
e080da |
/* tmpfp closed */
|
|
Packit Service |
e080da |
tmpfp = NULL;
|
|
Packit Service |
e080da |
tmp_fd = -1;
|
|
Packit Service |
e080da |
if (ret)
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
ret = glusterfs_oldvolfile_update(fs, rsp.spec, size);
|
|
Packit Service |
e080da |
out:
|
|
Packit Service |
e080da |
STACK_DESTROY(frame->root);
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if (rsp.spec)
|
|
Packit Service |
e080da |
free(rsp.spec);
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if (dict)
|
|
Packit Service |
e080da |
dict_unref(dict);
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
// Stop if server is running at an unsupported op-version
|
|
Packit Service |
e080da |
if (ENOTSUP == ret) {
|
|
Packit Service |
e080da |
gf_msg("mgmt", GF_LOG_ERROR, ENOTSUP, API_MSG_WRONG_OPVERSION,
|
|
Packit Service |
e080da |
"Server is operating at an op-version which is not "
|
|
Packit Service |
e080da |
"supported");
|
|
Packit Service |
e080da |
errno = ENOTSUP;
|
|
Packit Service |
e080da |
glfs_init_done(fs, -1);
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if (ret && ctx && !ctx->active) {
|
|
Packit Service |
e080da |
/* Do it only for the first time */
|
|
Packit Service |
e080da |
/* Failed to get the volume file, something wrong,
|
|
Packit Service |
e080da |
restart the process */
|
|
Packit Service |
e080da |
gf_msg("glfs-mgmt", GF_LOG_ERROR, EINVAL, API_MSG_INVALID_ENTRY,
|
|
Packit Service |
e080da |
"failed to fetch volume file (key:%s)",
|
|
Packit Service |
e080da |
ctx->cmd_args.volfile_id);
|
|
Packit Service |
e080da |
if (!need_retry) {
|
|
Packit Service |
e080da |
if (!errno)
|
|
Packit Service |
e080da |
errno = EINVAL;
|
|
Packit Service |
e080da |
glfs_init_done(fs, -1);
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if (tmpfp)
|
|
Packit Service |
e080da |
fclose(tmpfp);
|
|
Packit Service |
e080da |
else if (tmp_fd != -1)
|
|
Packit Service |
e080da |
sys_close(tmp_fd);
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
return 0;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
int
|
|
Packit Service |
e080da |
glfs_volfile_fetch(struct glfs *fs)
|
|
Packit Service |
e080da |
{
|
|
Packit Service |
e080da |
cmd_args_t *cmd_args = NULL;
|
|
Packit Service |
e080da |
gf_getspec_req req = {
|
|
Packit Service |
e080da |
0,
|
|
Packit Service |
e080da |
};
|
|
Packit Service |
e080da |
int ret = 0;
|
|
Packit Service |
e080da |
call_frame_t *frame = NULL;
|
|
Packit Service |
e080da |
glusterfs_ctx_t *ctx = NULL;
|
|
Packit Service |
e080da |
dict_t *dict = NULL;
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
ctx = fs->ctx;
|
|
Packit Service |
e080da |
cmd_args = &ctx->cmd_args;
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
frame = create_frame(THIS, ctx->pool);
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
req.key = cmd_args->volfile_id;
|
|
Packit Service |
e080da |
req.flags = 0;
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
dict = dict_new();
|
|
Packit Service |
e080da |
if (!dict) {
|
|
Packit Service |
e080da |
ret = -1;
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
// Set the supported min and max op-versions, so glusterd can make a
|
|
Packit Service |
e080da |
// decision
|
|
Packit Service |
e080da |
ret = dict_set_int32(dict, "min-op-version", GD_OP_VERSION_MIN);
|
|
Packit Service |
e080da |
if (ret) {
|
|
Packit Service |
e080da |
gf_msg(THIS->name, GF_LOG_ERROR, EINVAL, API_MSG_DICT_SET_FAILED,
|
|
Packit Service |
e080da |
"Failed to set min-op-version in request dict");
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
ret = dict_set_int32(dict, "max-op-version", GD_OP_VERSION_MAX);
|
|
Packit Service |
e080da |
if (ret) {
|
|
Packit Service |
e080da |
gf_msg(THIS->name, GF_LOG_ERROR, EINVAL, API_MSG_DICT_SET_FAILED,
|
|
Packit Service |
e080da |
"Failed to set max-op-version in request dict");
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
/* Ask for a list of volfile (glusterd2 only) servers */
|
|
Packit Service |
e080da |
if (GF_CLIENT_PROCESS == ctx->process_mode) {
|
|
Packit Service |
e080da |
req.flags = req.flags | GF_GETSPEC_FLAG_SERVERS_LIST;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
ret = dict_allocate_and_serialize(dict, &req.xdata.xdata_val,
|
|
Packit Service |
e080da |
&req.xdata.xdata_len);
|
|
Packit Service |
e080da |
if (ret < 0) {
|
|
Packit Service |
e080da |
gf_msg(THIS->name, GF_LOG_ERROR, 0, API_MSG_DICT_SERIALIZE_FAILED,
|
|
Packit Service |
e080da |
"Failed to serialize dictionary");
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
ret = mgmt_submit_request(&req, frame, ctx, &clnt_handshake_prog,
|
|
Packit Service |
e080da |
GF_HNDSK_GETSPEC, glfs_mgmt_getspec_cbk,
|
|
Packit Service |
e080da |
(xdrproc_t)xdr_gf_getspec_req);
|
|
Packit Service |
e080da |
out:
|
|
Packit Service |
e080da |
if (req.xdata.xdata_val)
|
|
Packit Service |
e080da |
GF_FREE(req.xdata.xdata_val);
|
|
Packit Service |
e080da |
if (dict)
|
|
Packit Service |
e080da |
dict_unref(dict);
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
return ret;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
static int
|
|
Packit Service |
e080da |
mgmt_rpc_notify(struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event,
|
|
Packit Service |
e080da |
void *data)
|
|
Packit Service |
e080da |
{
|
|
Packit Service |
e080da |
xlator_t *this = NULL;
|
|
Packit Service |
e080da |
glusterfs_ctx_t *ctx = NULL;
|
|
Packit Service |
e080da |
server_cmdline_t *server = NULL;
|
|
Packit Service |
e080da |
rpc_transport_t *rpc_trans = NULL;
|
|
Packit Service |
e080da |
struct glfs *fs = NULL;
|
|
Packit Service |
e080da |
int ret = 0;
|
|
Packit Service |
e080da |
struct dnscache6 *dnscache = NULL;
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
this = mydata;
|
|
Packit Service |
e080da |
rpc_trans = rpc->conn.trans;
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
ctx = this->ctx;
|
|
Packit Service |
e080da |
if (!ctx)
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
fs = ((xlator_t *)ctx->master)->private;
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
switch (event) {
|
|
Packit Service |
e080da |
case RPC_CLNT_DISCONNECT:
|
|
Packit Service |
e080da |
if (!ctx->active) {
|
|
Packit Service |
e080da |
if (rpc_trans->connect_failed)
|
|
Packit Service |
e080da |
gf_msg("glfs-mgmt", GF_LOG_ERROR, 0,
|
|
Packit Service |
e080da |
API_MSG_REMOTE_HOST_CONN_FAILED,
|
|
Packit Service |
e080da |
"failed to connect to remote-host: %s",
|
|
Packit Service |
e080da |
ctx->cmd_args.volfile_server);
|
|
Packit Service |
e080da |
else
|
|
Packit Service |
e080da |
gf_msg("glfs-mgmt", GF_LOG_INFO, 0,
|
|
Packit Service |
e080da |
API_MSG_REMOTE_HOST_CONN_FAILED,
|
|
Packit Service |
e080da |
"disconnected from remote-host: %s",
|
|
Packit Service |
e080da |
ctx->cmd_args.volfile_server);
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if (!rpc->disabled) {
|
|
Packit Service |
e080da |
/*
|
|
Packit Service |
e080da |
* Check if dnscache is exhausted for current server
|
|
Packit Service |
e080da |
* and continue until cache is exhausted
|
|
Packit Service |
e080da |
*/
|
|
Packit Service |
e080da |
dnscache = rpc_trans->dnscache;
|
|
Packit Service |
e080da |
if (dnscache && dnscache->next) {
|
|
Packit Service |
e080da |
break;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
server = ctx->cmd_args.curr_server;
|
|
Packit Service |
e080da |
if (server->list.next == &ctx->cmd_args.volfile_servers) {
|
|
Packit Service |
e080da |
errno = ENOTCONN;
|
|
Packit Service |
e080da |
gf_msg("glfs-mgmt", GF_LOG_INFO, ENOTCONN,
|
|
Packit Service |
e080da |
API_MSG_VOLFILE_SERVER_EXHAUST,
|
|
Packit Service |
e080da |
"Exhausted all volfile servers");
|
|
Packit Service |
e080da |
glfs_init_done(fs, -1);
|
|
Packit Service |
e080da |
break;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
server = list_entry(server->list.next, typeof(*server), list);
|
|
Packit Service |
e080da |
ctx->cmd_args.curr_server = server;
|
|
Packit Service |
e080da |
ctx->cmd_args.volfile_server_port = server->port;
|
|
Packit Service |
e080da |
ctx->cmd_args.volfile_server = server->volfile_server;
|
|
Packit Service |
e080da |
ctx->cmd_args.volfile_server_transport = server->transport;
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
ret = dict_set_str(rpc_trans->options, "transport-type",
|
|
Packit Service |
e080da |
server->transport);
|
|
Packit Service |
e080da |
if (ret != 0) {
|
|
Packit Service |
e080da |
gf_msg("glfs-mgmt", GF_LOG_ERROR, ENOTCONN,
|
|
Packit Service |
e080da |
API_MSG_DICT_SET_FAILED,
|
|
Packit Service |
e080da |
"failed to set transport-type: %s",
|
|
Packit Service |
e080da |
server->transport);
|
|
Packit Service |
e080da |
errno = ENOTCONN;
|
|
Packit Service |
e080da |
glfs_init_done(fs, -1);
|
|
Packit Service |
e080da |
break;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if (strcmp(server->transport, "unix") == 0) {
|
|
Packit Service |
e080da |
ret = dict_set_str(rpc_trans->options,
|
|
Packit Service |
e080da |
"transport.socket.connect-path",
|
|
Packit Service |
e080da |
server->volfile_server);
|
|
Packit Service |
e080da |
if (ret != 0) {
|
|
Packit Service |
e080da |
gf_msg("glfs-mgmt", GF_LOG_ERROR, ENOTCONN,
|
|
Packit Service |
e080da |
API_MSG_DICT_SET_FAILED,
|
|
Packit Service |
e080da |
"failed to set socket.connect-path: %s",
|
|
Packit Service |
e080da |
server->volfile_server);
|
|
Packit Service |
e080da |
errno = ENOTCONN;
|
|
Packit Service |
e080da |
glfs_init_done(fs, -1);
|
|
Packit Service |
e080da |
break;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
/* delete the remote-host and remote-port keys
|
|
Packit Service |
e080da |
* in case they were set while looping through
|
|
Packit Service |
e080da |
* list of volfile servers previously
|
|
Packit Service |
e080da |
*/
|
|
Packit Service |
e080da |
dict_del(rpc_trans->options, "remote-host");
|
|
Packit Service |
e080da |
dict_del(rpc_trans->options, "remote-port");
|
|
Packit Service |
e080da |
} else {
|
|
Packit Service |
e080da |
ret = dict_set_int32(rpc_trans->options, "remote-port",
|
|
Packit Service |
e080da |
server->port);
|
|
Packit Service |
e080da |
if (ret != 0) {
|
|
Packit Service |
e080da |
gf_msg("glfs-mgmt", GF_LOG_ERROR, ENOTCONN,
|
|
Packit Service |
e080da |
API_MSG_DICT_SET_FAILED,
|
|
Packit Service |
e080da |
"failed to set remote-port: %d", server->port);
|
|
Packit Service |
e080da |
errno = ENOTCONN;
|
|
Packit Service |
e080da |
glfs_init_done(fs, -1);
|
|
Packit Service |
e080da |
break;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
ret = dict_set_str(rpc_trans->options, "remote-host",
|
|
Packit Service |
e080da |
server->volfile_server);
|
|
Packit Service |
e080da |
if (ret != 0) {
|
|
Packit Service |
e080da |
gf_msg("glfs-mgmt", GF_LOG_ERROR, ENOTCONN,
|
|
Packit Service |
e080da |
API_MSG_DICT_SET_FAILED,
|
|
Packit Service |
e080da |
"failed to set remote-host: %s",
|
|
Packit Service |
e080da |
server->volfile_server);
|
|
Packit Service |
e080da |
errno = ENOTCONN;
|
|
Packit Service |
e080da |
glfs_init_done(fs, -1);
|
|
Packit Service |
e080da |
break;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
/* delete the "transport.socket.connect-path"
|
|
Packit Service |
e080da |
* key in case if it was set while looping
|
|
Packit Service |
e080da |
* through list of volfile servers previously
|
|
Packit Service |
e080da |
*/
|
|
Packit Service |
e080da |
dict_del(rpc_trans->options,
|
|
Packit Service |
e080da |
"transport.socket.connect-path");
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
gf_msg("glfs-mgmt", GF_LOG_INFO, 0, API_MSG_VOLFILE_CONNECTING,
|
|
Packit Service |
e080da |
"connecting to next volfile server %s"
|
|
Packit Service |
e080da |
" at port %d with transport: %s",
|
|
Packit Service |
e080da |
server->volfile_server, server->port, server->transport);
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
break;
|
|
Packit Service |
e080da |
case RPC_CLNT_CONNECT:
|
|
Packit Service |
e080da |
ret = glfs_volfile_fetch(fs);
|
|
Packit Service |
e080da |
if (ret && (ctx->active == NULL)) {
|
|
Packit Service |
e080da |
/* Do it only for the first time */
|
|
Packit Service |
e080da |
/* Exit the process.. there are some wrong options */
|
|
Packit Service |
e080da |
gf_msg("glfs-mgmt", GF_LOG_ERROR, EINVAL, API_MSG_INVALID_ENTRY,
|
|
Packit Service |
e080da |
"failed to fetch volume file (key:%s)",
|
|
Packit Service |
e080da |
ctx->cmd_args.volfile_id);
|
|
Packit Service |
e080da |
errno = EINVAL;
|
|
Packit Service |
e080da |
glfs_init_done(fs, -1);
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
break;
|
|
Packit Service |
e080da |
default:
|
|
Packit Service |
e080da |
break;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
out:
|
|
Packit Service |
e080da |
return 0;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
int
|
|
Packit Service |
e080da |
glusterfs_mgmt_notify(int32_t op, void *data, ...)
|
|
Packit Service |
e080da |
{
|
|
Packit Service |
e080da |
int ret = 0;
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
switch (op) {
|
|
Packit Service |
e080da |
case GF_EN_DEFRAG_STATUS:
|
|
Packit Service |
e080da |
break;
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
default:
|
|
Packit Service |
e080da |
break;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
return ret;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
int
|
|
Packit Service |
e080da |
glfs_mgmt_init(struct glfs *fs)
|
|
Packit Service |
e080da |
{
|
|
Packit Service |
e080da |
cmd_args_t *cmd_args = NULL;
|
|
Packit Service |
e080da |
struct rpc_clnt *rpc = NULL;
|
|
Packit Service |
e080da |
dict_t *options = NULL;
|
|
Packit Service |
e080da |
int ret = -1;
|
|
Packit Service |
e080da |
int port = GF_DEFAULT_BASE_PORT;
|
|
Packit Service |
e080da |
char *host = NULL;
|
|
Packit Service |
e080da |
glusterfs_ctx_t *ctx = NULL;
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
ctx = fs->ctx;
|
|
Packit Service |
e080da |
cmd_args = &ctx->cmd_args;
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if (ctx->mgmt)
|
|
Packit Service |
e080da |
return 0;
|
|
Packit Service |
e080da |
|
|
Packit Service |
173fb3 |
options = dict_new();
|
|
Packit Service |
173fb3 |
if (!options)
|
|
Packit Service |
173fb3 |
goto out;
|
|
Packit Service |
173fb3 |
|
|
Packit Service |
e080da |
if (cmd_args->volfile_server_port)
|
|
Packit Service |
e080da |
port = cmd_args->volfile_server_port;
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if (cmd_args->volfile_server) {
|
|
Packit Service |
e080da |
host = cmd_args->volfile_server;
|
|
Packit Service |
e080da |
} else if (cmd_args->volfile_server_transport &&
|
|
Packit Service |
e080da |
!strcmp(cmd_args->volfile_server_transport, "unix")) {
|
|
Packit Service |
e080da |
host = DEFAULT_GLUSTERD_SOCKFILE;
|
|
Packit Service |
e080da |
} else {
|
|
Packit Service |
e080da |
host = "localhost";
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if (cmd_args->volfile_server_transport &&
|
|
Packit Service |
e080da |
!strcmp(cmd_args->volfile_server_transport, "unix")) {
|
|
Packit Service |
173fb3 |
ret = rpc_transport_unix_options_build(options, host, 0);
|
|
Packit Service |
e080da |
} else {
|
|
Packit Service |
e080da |
xlator_cmdline_option_t *opt = find_xlator_option_in_cmd_args_t(
|
|
Packit Service |
e080da |
"address-family", cmd_args);
|
|
Packit Service |
173fb3 |
ret = rpc_transport_inet_options_build(options, host, port,
|
|
Packit Service |
e080da |
(opt ? opt->value : NULL));
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if (ret)
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if (sys_access(SECURE_ACCESS_FILE, F_OK) == 0) {
|
|
Packit Service |
e080da |
ctx->secure_mgmt = 1;
|
|
Packit Service |
e080da |
ctx->ssl_cert_depth = glusterfs_read_secure_access_file();
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
rpc = rpc_clnt_new(options, THIS, THIS->name, 8);
|
|
Packit Service |
e080da |
if (!rpc) {
|
|
Packit Service |
e080da |
ret = -1;
|
|
Packit Service |
e080da |
gf_msg(THIS->name, GF_LOG_WARNING, 0, API_MSG_CREATE_RPC_CLIENT_FAILED,
|
|
Packit Service |
e080da |
"failed to create rpc clnt");
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
ret = rpc_clnt_register_notify(rpc, mgmt_rpc_notify, THIS);
|
|
Packit Service |
e080da |
if (ret) {
|
|
Packit Service |
e080da |
gf_msg(THIS->name, GF_LOG_WARNING, 0, API_MSG_REG_NOTIFY_FUNC_FAILED,
|
|
Packit Service |
e080da |
"failed to register notify function");
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
ret = rpcclnt_cbk_program_register(rpc, &mgmt_cbk_prog, THIS);
|
|
Packit Service |
e080da |
if (ret) {
|
|
Packit Service |
e080da |
gf_msg(THIS->name, GF_LOG_WARNING, 0, API_MSG_REG_CBK_FUNC_FAILED,
|
|
Packit Service |
e080da |
"failed to register callback function");
|
|
Packit Service |
e080da |
goto out;
|
|
Packit Service |
e080da |
}
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
ctx->notify = glusterfs_mgmt_notify;
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
/* This value should be set before doing the 'rpc_clnt_start()' as
|
|
Packit Service |
e080da |
the notify function uses this variable */
|
|
Packit Service |
e080da |
ctx->mgmt = rpc;
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
ret = rpc_clnt_start(rpc);
|
|
Packit Service |
e080da |
out:
|
|
Packit Service |
173fb3 |
if (options)
|
|
Packit Service |
173fb3 |
dict_unref(options);
|
|
Packit Service |
e080da |
return ret;
|
|
Packit Service |
e080da |
}
|