Blame api/src/glfs-mgmt.c

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
}