Blame api/src/glfs.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
/*
Packit Service e080da
  TODO:
Packit Service e080da
  - set proper pid/lk_owner to call frames (currently buried in syncop)
Packit Service e080da
  - fix logging.c/h to store logfp and loglevel in glusterfs_ctx_t and
Packit Service e080da
    reach it via THIS.
Packit Service e080da
  - update syncop functions to accept/return xdata. ???
Packit Service e080da
  - protocol/client to reconnect immediately after portmap disconnect.
Packit Service e080da
  - handle SEEK_END failure in _lseek()
Packit Service e080da
  - handle umask (per filesystem?)
Packit Service e080da
  - make itables LRU based
Packit Service e080da
  - 0-copy for readv/writev
Packit Service e080da
  - reconcile the open/creat mess
Packit Service e080da
*/
Packit Service e080da
Packit Service e080da
#include <unistd.h>
Packit Service e080da
#include <string.h>
Packit Service e080da
#include <stdlib.h>
Packit Service e080da
#include <stdio.h>
Packit Service e080da
#include <inttypes.h>
Packit Service e080da
#include <sys/types.h>
Packit Service e080da
#include <unistd.h>
Packit Service e080da
#include <limits.h>
Packit Service e080da
#ifdef GF_LINUX_HOST_OS
Packit Service e080da
#include <sys/prctl.h>
Packit Service e080da
#endif
Packit Service e080da
Packit Service e080da
#include <glusterfs/glusterfs.h>
Packit Service e080da
#include <glusterfs/logging.h>
Packit Service e080da
#include <glusterfs/stack.h>
Packit Service e080da
#include <glusterfs/gf-event.h>
Packit Service e080da
#include "glfs-mem-types.h"
Packit Service e080da
#include <glusterfs/common-utils.h>
Packit Service e080da
#include <glusterfs/syncop.h>
Packit Service e080da
#include <glusterfs/call-stub.h>
Packit Service e080da
#include <glusterfs/hashfn.h>
Packit Service e080da
#include "rpc-clnt.h"
Packit Service e080da
#include <glusterfs/statedump.h>
Packit Service e080da
Packit Service e080da
#include "gfapi-messages.h"
Packit Service e080da
#include "glfs.h"
Packit Service e080da
#include "glfs-internal.h"
Packit Service e080da
Packit Service e080da
static gf_boolean_t
Packit Service e080da
vol_assigned(cmd_args_t *args)
Packit Service e080da
{
Packit Service e080da
    return args->volfile || args->volfile_server;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
static int
Packit Service e080da
glusterfs_ctx_defaults_init(glusterfs_ctx_t *ctx)
Packit Service e080da
{
Packit Service e080da
    call_pool_t *pool = NULL;
Packit Service e080da
    int ret = -1;
Packit Service e080da
Packit Service e080da
    if (!ctx) {
Packit Service e080da
        goto err;
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    ret = xlator_mem_acct_init(THIS, glfs_mt_end + 1);
Packit Service e080da
    if (ret != 0) {
Packit Service e080da
        gf_msg(THIS->name, GF_LOG_ERROR, ENOMEM, API_MSG_MEM_ACCT_INIT_FAILED,
Packit Service e080da
               "Memory accounting init failed");
Packit Service e080da
        return ret;
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    /* reset ret to -1 so that we don't need to explicitly
Packit Service e080da
     * set it in all error paths before "goto err"
Packit Service e080da
     */
Packit Service e080da
Packit Service e080da
    ret = -1;
Packit Service e080da
Packit Service e080da
    ctx->process_uuid = generate_glusterfs_ctx_id();
Packit Service e080da
    if (!ctx->process_uuid) {
Packit Service e080da
        goto err;
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    ctx->page_size = 128 * GF_UNIT_KB;
Packit Service e080da
Packit Service e080da
    ctx->iobuf_pool = iobuf_pool_new();
Packit Service e080da
    if (!ctx->iobuf_pool) {
Packit Service e080da
        goto err;
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    ctx->event_pool = event_pool_new(DEFAULT_EVENT_POOL_SIZE,
Packit Service e080da
                                     STARTING_EVENT_THREADS);
Packit Service e080da
    if (!ctx->event_pool) {
Packit Service e080da
        goto err;
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    ctx->env = syncenv_new(0, 0, 0);
Packit Service e080da
    if (!ctx->env) {
Packit Service e080da
        goto err;
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    pool = GF_CALLOC(1, sizeof(call_pool_t), glfs_mt_call_pool_t);
Packit Service e080da
    if (!pool) {
Packit Service e080da
        goto err;
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    /* frame_mem_pool size 112 * 4k */
Packit Service e080da
    pool->frame_mem_pool = mem_pool_new(call_frame_t, 4096);
Packit Service e080da
    if (!pool->frame_mem_pool) {
Packit Service e080da
        goto err;
Packit Service e080da
    }
Packit Service e080da
    /* stack_mem_pool size 256 * 1024 */
Packit Service e080da
    pool->stack_mem_pool = mem_pool_new(call_stack_t, 1024);
Packit Service e080da
    if (!pool->stack_mem_pool) {
Packit Service e080da
        goto err;
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    ctx->stub_mem_pool = mem_pool_new(call_stub_t, 1024);
Packit Service e080da
    if (!ctx->stub_mem_pool) {
Packit Service e080da
        goto err;
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    ctx->dict_pool = mem_pool_new(dict_t, GF_MEMPOOL_COUNT_OF_DICT_T);
Packit Service e080da
    if (!ctx->dict_pool)
Packit Service e080da
        goto err;
Packit Service e080da
Packit Service e080da
    ctx->dict_pair_pool = mem_pool_new(data_pair_t,
Packit Service e080da
                                       GF_MEMPOOL_COUNT_OF_DATA_PAIR_T);
Packit Service e080da
    if (!ctx->dict_pair_pool)
Packit Service e080da
        goto err;
Packit Service e080da
Packit Service e080da
    ctx->dict_data_pool = mem_pool_new(data_t, GF_MEMPOOL_COUNT_OF_DATA_T);
Packit Service e080da
    if (!ctx->dict_data_pool)
Packit Service e080da
        goto err;
Packit Service e080da
Packit Service e080da
    ctx->logbuf_pool = mem_pool_new(log_buf_t, GF_MEMPOOL_COUNT_OF_LRU_BUF_T);
Packit Service e080da
    if (!ctx->logbuf_pool)
Packit Service e080da
        goto err;
Packit Service e080da
Packit Service e080da
    INIT_LIST_HEAD(&pool->all_frames);
Packit Service e080da
    INIT_LIST_HEAD(&ctx->cmd_args.xlator_options);
Packit Service e080da
    INIT_LIST_HEAD(&ctx->cmd_args.volfile_servers);
Packit Service e080da
Packit Service e080da
    LOCK_INIT(&pool->lock);
Packit Service e080da
    ctx->pool = pool;
Packit Service e080da
Packit Service e080da
    ret = 0;
Packit Service e080da
err:
Packit Service e080da
    if (ret && pool) {
Packit Service e080da
        if (pool->frame_mem_pool)
Packit Service e080da
            mem_pool_destroy(pool->frame_mem_pool);
Packit Service e080da
        if (pool->stack_mem_pool)
Packit Service e080da
            mem_pool_destroy(pool->stack_mem_pool);
Packit Service e080da
        GF_FREE(pool);
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    if (ret && ctx) {
Packit Service e080da
        if (ctx->stub_mem_pool)
Packit Service e080da
            mem_pool_destroy(ctx->stub_mem_pool);
Packit Service e080da
        if (ctx->dict_pool)
Packit Service e080da
            mem_pool_destroy(ctx->dict_pool);
Packit Service e080da
        if (ctx->dict_data_pool)
Packit Service e080da
            mem_pool_destroy(ctx->dict_data_pool);
Packit Service e080da
        if (ctx->dict_pair_pool)
Packit Service e080da
            mem_pool_destroy(ctx->dict_pair_pool);
Packit Service e080da
        if (ctx->logbuf_pool)
Packit Service e080da
            mem_pool_destroy(ctx->logbuf_pool);
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    return ret;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
static int
Packit Service e080da
create_master(struct glfs *fs)
Packit Service e080da
{
Packit Service e080da
    int ret = 0;
Packit Service e080da
    xlator_t *master = NULL;
Packit Service e080da
Packit Service e080da
    master = GF_CALLOC(1, sizeof(*master), glfs_mt_xlator_t);
Packit Service e080da
    if (!master)
Packit Service e080da
        goto err;
Packit Service e080da
Packit Service e080da
    master->name = gf_strdup("gfapi");
Packit Service e080da
    if (!master->name)
Packit Service e080da
        goto err;
Packit Service e080da
Packit Service e080da
    if (xlator_set_type(master, "mount/api") == -1) {
Packit Service e080da
        gf_msg("glfs", GF_LOG_ERROR, 0, API_MSG_MASTER_XLATOR_INIT_FAILED,
Packit Service e080da
               "master xlator "
Packit Service e080da
               "for %s initialization failed",
Packit Service e080da
               fs->volname);
Packit Service e080da
        goto err;
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    master->ctx = fs->ctx;
Packit Service e080da
    master->private = fs;
Packit Service e080da
    master->options = dict_new();
Packit Service e080da
    if (!master->options)
Packit Service e080da
        goto err;
Packit Service e080da
Packit Service e080da
    ret = xlator_init(master);
Packit Service e080da
    if (ret) {
Packit Service e080da
        gf_msg("glfs", GF_LOG_ERROR, 0, API_MSG_GFAPI_XLATOR_INIT_FAILED,
Packit Service e080da
               "failed to initialize gfapi translator");
Packit Service e080da
        goto err;
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    fs->ctx->master = master;
Packit Service e080da
    THIS = master;
Packit Service e080da
Packit Service e080da
    return 0;
Packit Service e080da
Packit Service e080da
err:
Packit Service e080da
    if (master) {
Packit Service e080da
        xlator_destroy(master);
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    return -1;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
static FILE *
Packit Service e080da
get_volfp(struct glfs *fs)
Packit Service e080da
{
Packit Service e080da
    cmd_args_t *cmd_args = NULL;
Packit Service e080da
    FILE *specfp = NULL;
Packit Service e080da
Packit Service e080da
    cmd_args = &fs->ctx->cmd_args;
Packit Service e080da
Packit Service e080da
    if ((specfp = fopen(cmd_args->volfile, "r")) == NULL) {
Packit Service e080da
        gf_msg("glfs", GF_LOG_ERROR, errno, API_MSG_VOLFILE_OPEN_FAILED,
Packit Service e080da
               "volume file %s open failed: %s", cmd_args->volfile,
Packit Service e080da
               strerror(errno));
Packit Service e080da
        return NULL;
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    gf_msg_debug("glfs", 0, "loading volume file %s", cmd_args->volfile);
Packit Service e080da
Packit Service e080da
    return specfp;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
int
Packit Service e080da
glfs_volumes_init(struct glfs *fs)
Packit Service e080da
{
Packit Service e080da
    FILE *fp = NULL;
Packit Service e080da
    cmd_args_t *cmd_args = NULL;
Packit Service e080da
    int ret = 0;
Packit Service e080da
Packit Service e080da
    cmd_args = &fs->ctx->cmd_args;
Packit Service e080da
Packit Service e080da
    if (!vol_assigned(cmd_args))
Packit Service e080da
        return -1;
Packit Service e080da
Packit Service e080da
    if (cmd_args->volfile_server) {
Packit Service e080da
        ret = glfs_mgmt_init(fs);
Packit Service e080da
        goto out;
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    fp = get_volfp(fs);
Packit Service e080da
Packit Service e080da
    if (!fp) {
Packit Service e080da
        gf_msg("glfs", GF_LOG_ERROR, ENOENT, API_MSG_VOL_SPEC_FILE_ERROR,
Packit Service e080da
               "Cannot reach volume specification file");
Packit Service e080da
        ret = -1;
Packit Service e080da
        goto out;
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    ret = glfs_process_volfp(fs, fp);
Packit Service e080da
    if (ret)
Packit Service e080da
        goto out;
Packit Service e080da
Packit Service e080da
out:
Packit Service e080da
    return ret;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
///////////////////////////////////////////////////////////////////////////////
Packit Service e080da
Packit Service e080da
int
Packit Service e080da
pub_glfs_set_xlator_option(struct glfs *fs, const char *xlator, const char *key,
Packit Service e080da
                           const char *value)
Packit Service e080da
{
Packit Service e080da
    xlator_cmdline_option_t *option = NULL;
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
    option = GF_CALLOC(1, sizeof(*option), glfs_mt_xlator_cmdline_option_t);
Packit Service e080da
    if (!option)
Packit Service e080da
        goto enomem;
Packit Service e080da
Packit Service e080da
    INIT_LIST_HEAD(&option->cmd_args);
Packit Service e080da
Packit Service e080da
    option->volume = gf_strdup(xlator);
Packit Service e080da
    if (!option->volume)
Packit Service e080da
        goto enomem;
Packit Service e080da
    option->key = gf_strdup(key);
Packit Service e080da
    if (!option->key)
Packit Service e080da
        goto enomem;
Packit Service e080da
    option->value = gf_strdup(value);
Packit Service e080da
    if (!option->value)
Packit Service e080da
        goto enomem;
Packit Service e080da
Packit Service e080da
    list_add(&option->cmd_args, &fs->ctx->cmd_args.xlator_options);
Packit Service e080da
Packit Service e080da
    __GLFS_EXIT_FS;
Packit Service e080da
Packit Service e080da
    return 0;
Packit Service e080da
enomem:
Packit Service e080da
    errno = ENOMEM;
Packit Service e080da
Packit Service e080da
    if (!option) {
Packit Service e080da
        __GLFS_EXIT_FS;
Packit Service e080da
        return -1;
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    GF_FREE(option->volume);
Packit Service e080da
    GF_FREE(option->key);
Packit Service e080da
    GF_FREE(option->value);
Packit Service e080da
    GF_FREE(option);
Packit Service e080da
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_set_xlator_option, 3.4.0);
Packit Service e080da
Packit Service e080da
int
Packit Service e080da
pub_glfs_unset_volfile_server(struct glfs *fs, const char *transport,
Packit Service e080da
                              const char *host, const int port)
Packit Service e080da
{
Packit Service e080da
    cmd_args_t *cmd_args = NULL;
Packit Service e080da
    server_cmdline_t *server = NULL;
Packit Service e080da
    server_cmdline_t *tmp = NULL;
Packit Service e080da
    char *transport_val = NULL;
Packit Service e080da
    int port_val = 0;
Packit Service e080da
    int ret = -1;
Packit Service e080da
Packit Service e080da
    if (!fs || !host) {
Packit Service e080da
        errno = EINVAL;
Packit Service e080da
        return ret;
Packit Service e080da
    }
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
    cmd_args = &fs->ctx->cmd_args;
Packit Service e080da
Packit Service e080da
    if (transport) {
Packit Service e080da
        transport_val = gf_strdup(transport);
Packit Service e080da
    } else {
Packit Service e080da
        transport_val = gf_strdup(GF_DEFAULT_VOLFILE_TRANSPORT);
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    if (!transport_val) {
Packit Service e080da
        errno = ENOMEM;
Packit Service e080da
        goto out;
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    if (port) {
Packit Service e080da
        port_val = port;
Packit Service e080da
    } else {
Packit Service e080da
        port_val = GF_DEFAULT_BASE_PORT;
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    list_for_each_entry_safe(server, tmp, &cmd_args->curr_server->list, list)
Packit Service e080da
    {
Packit Service e080da
        if ((!strcmp(server->volfile_server, host) &&
Packit Service e080da
             !strcmp(server->transport, transport_val) &&
Packit Service e080da
             (server->port == port_val))) {
Packit Service e080da
            list_del(&server->list);
Packit Service e080da
            ret = 0;
Packit Service e080da
            goto out;
Packit Service e080da
        }
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
out:
Packit Service e080da
    GF_FREE(transport_val);
Packit Service e080da
    __GLFS_EXIT_FS;
Packit Service e080da
Packit Service e080da
invalid_fs:
Packit Service e080da
    return ret;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_unset_volfile_server, 3.5.1);
Packit Service e080da
Packit Service e080da
int
Packit Service e080da
pub_glfs_set_volfile_server(struct glfs *fs, const char *transport,
Packit Service e080da
                            const char *host, int port)
Packit Service e080da
{
Packit Service e080da
    cmd_args_t *cmd_args = NULL;
Packit Service e080da
    int ret = -1;
Packit Service e080da
    char *server_host = NULL;
Packit Service e080da
    char *server_transport = NULL;
Packit Service e080da
Packit Service e080da
    if (!fs || !host) {
Packit Service e080da
        errno = EINVAL;
Packit Service e080da
        return ret;
Packit Service e080da
    }
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
    cmd_args = &fs->ctx->cmd_args;
Packit Service e080da
    cmd_args->max_connect_attempts = 1;
Packit Service e080da
Packit Service e080da
    server_host = gf_strdup(host);
Packit Service e080da
    if (!server_host) {
Packit Service e080da
        errno = ENOMEM;
Packit Service e080da
        goto out;
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    if (transport) {
Packit Service e080da
        /* volfile fetch support over tcp|unix only */
Packit Service e080da
        if (!strcmp(transport, "tcp") || !strcmp(transport, "unix")) {
Packit Service e080da
            server_transport = gf_strdup(transport);
Packit Service e080da
        } else if (!strcmp(transport, "rdma")) {
Packit Service e080da
            server_transport = gf_strdup(GF_DEFAULT_VOLFILE_TRANSPORT);
Packit Service e080da
            gf_msg("glfs", GF_LOG_WARNING, EINVAL, API_MSG_INVALID_ENTRY,
Packit Service e080da
                   "transport RDMA is deprecated, "
Packit Service e080da
                   "falling back to tcp");
Packit Service e080da
        } else {
Packit Service e080da
            gf_msg("glfs", GF_LOG_TRACE, EINVAL, API_MSG_INVALID_ENTRY,
Packit Service e080da
                   "transport %s is not supported, "
Packit Service e080da
                   "possible values tcp|unix",
Packit Service e080da
                   transport);
Packit Service e080da
            goto out;
Packit Service e080da
        }
Packit Service e080da
    } else {
Packit Service e080da
        server_transport = gf_strdup(GF_DEFAULT_VOLFILE_TRANSPORT);
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    if (!server_transport) {
Packit Service e080da
        errno = ENOMEM;
Packit Service e080da
        goto out;
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    if (!port) {
Packit Service e080da
        port = GF_DEFAULT_BASE_PORT;
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    if (!strcmp(server_transport, "unix")) {
Packit Service e080da
        port = 0;
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    ret = gf_set_volfile_server_common(cmd_args, server_host, server_transport,
Packit Service e080da
                                       port);
Packit Service e080da
    if (ret) {
Packit Service e080da
        gf_log("glfs", GF_LOG_ERROR, "failed to set volfile server: %s",
Packit Service e080da
               strerror(errno));
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
out:
Packit Service e080da
    if (server_host) {
Packit Service e080da
        GF_FREE(server_host);
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    if (server_transport) {
Packit Service e080da
        GF_FREE(server_transport);
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    __GLFS_EXIT_FS;
Packit Service e080da
Packit Service e080da
invalid_fs:
Packit Service e080da
    return ret;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_set_volfile_server, 3.4.0);
Packit Service e080da
Packit Service e080da
/* *
Packit Service e080da
 * Used to free the arguments allocated by glfs_set_volfile_server()
Packit Service e080da
 */
Packit Service e080da
static void
Packit Service e080da
glfs_free_volfile_servers(cmd_args_t *cmd_args)
Packit Service e080da
{
Packit Service e080da
    server_cmdline_t *server = NULL;
Packit Service e080da
    server_cmdline_t *tmp = NULL;
Packit Service e080da
Packit Service e080da
    GF_VALIDATE_OR_GOTO(THIS->name, cmd_args, out);
Packit Service e080da
Packit Service e080da
    list_for_each_entry_safe(server, tmp, &cmd_args->volfile_servers, list)
Packit Service e080da
    {
Packit Service e080da
        list_del_init(&server->list);
Packit Service e080da
        GF_FREE(server->volfile_server);
Packit Service e080da
        GF_FREE(server->transport);
Packit Service e080da
        GF_FREE(server);
Packit Service e080da
    }
Packit Service e080da
    cmd_args->curr_server = NULL;
Packit Service e080da
out:
Packit Service e080da
    return;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
static void
Packit Service e080da
glfs_free_xlator_options(cmd_args_t *cmd_args)
Packit Service e080da
{
Packit Service e080da
    xlator_cmdline_option_t *xo = NULL;
Packit Service e080da
    xlator_cmdline_option_t *tmp_xo = NULL;
Packit Service e080da
Packit Service e080da
    if (!&(cmd_args->xlator_options))
Packit Service e080da
        return;
Packit Service e080da
Packit Service e080da
    list_for_each_entry_safe(xo, tmp_xo, &cmd_args->xlator_options, cmd_args)
Packit Service e080da
    {
Packit Service e080da
        list_del_init(&xo->cmd_args);
Packit Service e080da
        GF_FREE(xo->volume);
Packit Service e080da
        GF_FREE(xo->key);
Packit Service e080da
        GF_FREE(xo->value);
Packit Service e080da
        GF_FREE(xo);
Packit Service e080da
    }
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
int
Packit Service e080da
pub_glfs_setfsuid(uid_t fsuid)
Packit Service e080da
{
Packit Service e080da
    /* TODO:
Packit Service e080da
     * - Set the THIS and restore it appropriately
Packit Service e080da
     */
Packit Service e080da
    return syncopctx_setfsuid(&fsuid);
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_setfsuid, 3.4.2);
Packit Service e080da
Packit Service e080da
int
Packit Service e080da
pub_glfs_setfsgid(gid_t fsgid)
Packit Service e080da
{
Packit Service e080da
    /* TODO:
Packit Service e080da
     * - Set the THIS and restore it appropriately
Packit Service e080da
     */
Packit Service e080da
    return syncopctx_setfsgid(&fsgid);
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_setfsgid, 3.4.2);
Packit Service e080da
Packit Service e080da
int
Packit Service e080da
pub_glfs_setfsgroups(size_t size, const gid_t *list)
Packit Service e080da
{
Packit Service e080da
    /* TODO:
Packit Service e080da
     * - Set the THIS and restore it appropriately
Packit Service e080da
     */
Packit Service e080da
    return syncopctx_setfsgroups(size, list);
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_setfsgroups, 3.4.2);
Packit Service e080da
Packit Service e080da
int
Packit Service e080da
pub_glfs_setfsleaseid(glfs_leaseid_t leaseid)
Packit Service e080da
{
Packit Service e080da
    int ret = -1;
Packit Service e080da
    char *gleaseid = NULL;
Packit Service e080da
Packit Service e080da
    gleaseid = gf_leaseid_get();
Packit Service e080da
    if (gleaseid) {
Packit Service e080da
        if (leaseid)
Packit Service e080da
            memcpy(gleaseid, leaseid, LEASE_ID_SIZE);
Packit Service e080da
        else /* reset leaseid */
Packit Service e080da
            memset(gleaseid, 0, LEASE_ID_SIZE);
Packit Service e080da
        ret = 0;
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    if (ret)
Packit Service e080da
        gf_log("glfs", GF_LOG_ERROR, "failed to set leaseid: %s",
Packit Service e080da
               strerror(errno));
Packit Service e080da
    return ret;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_setfsleaseid, 4.0.0);
Packit Service e080da
Packit Service e080da
int
Packit Service e080da
get_fop_attr_glfd(dict_t **fop_attr, struct glfs_fd *glfd)
Packit Service e080da
{
Packit Service e080da
    char *leaseid = NULL;
Packit Service e080da
    int ret = 0;
Packit Service e080da
    gf_boolean_t dict_create = _gf_false;
Packit Service e080da
Packit Service e080da
    leaseid = GF_MALLOC(LEASE_ID_SIZE, gf_common_mt_char);
Packit Service e080da
    GF_CHECK_ALLOC_AND_LOG("gfapi", leaseid, ret, "lease id alloc failed", out);
Packit Service e080da
    memcpy(leaseid, glfd->lease_id, LEASE_ID_SIZE);
Packit Service e080da
    if (*fop_attr == NULL) {
Packit Service e080da
        *fop_attr = dict_new();
Packit Service e080da
        dict_create = _gf_true;
Packit Service e080da
    }
Packit Service e080da
    GF_CHECK_ALLOC_AND_LOG("gfapi", *fop_attr, ret, "dict_new failed", out);
Packit Service e080da
    ret = dict_set_bin(*fop_attr, "lease-id", leaseid, LEASE_ID_SIZE);
Packit Service e080da
out:
Packit Service e080da
    if (ret) {
Packit Service e080da
        GF_FREE(leaseid);
Packit Service e080da
        if (dict_create) {
Packit Service e080da
            if (*fop_attr)
Packit Service e080da
                dict_unref(*fop_attr);
Packit Service e080da
            *fop_attr = NULL;
Packit Service e080da
        }
Packit Service e080da
    }
Packit Service e080da
    return ret;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
int
Packit Service e080da
set_fop_attr_glfd(struct glfs_fd *glfd)
Packit Service e080da
{
Packit Service e080da
    char *lease_id = NULL;
Packit Service e080da
    int ret = -1;
Packit Service e080da
Packit Service e080da
    lease_id = gf_existing_leaseid();
Packit Service e080da
    if (lease_id) {
Packit Service e080da
        memcpy(glfd->lease_id, lease_id, LEASE_ID_SIZE);
Packit Service e080da
        ret = 0;
Packit Service e080da
    }
Packit Service e080da
    return ret;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
int
Packit Service e080da
get_fop_attr_thrd_key(dict_t **fop_attr)
Packit Service e080da
{
Packit Service e080da
    char *existing_leaseid = NULL, *leaseid = NULL;
Packit Service e080da
    int ret = 0;
Packit Service e080da
    gf_boolean_t dict_create = _gf_false;
Packit Service e080da
Packit Service e080da
    existing_leaseid = gf_existing_leaseid();
Packit Service e080da
    if (existing_leaseid) {
Packit Service e080da
        leaseid = GF_MALLOC(LEASE_ID_SIZE, gf_common_mt_char);
Packit Service e080da
        GF_CHECK_ALLOC_AND_LOG("gfapi", leaseid, ret, "lease id alloc failed",
Packit Service e080da
                               out);
Packit Service e080da
        memcpy(leaseid, existing_leaseid, LEASE_ID_SIZE);
Packit Service e080da
        if (*fop_attr == NULL) {
Packit Service e080da
            *fop_attr = dict_new();
Packit Service e080da
            dict_create = _gf_true;
Packit Service e080da
        }
Packit Service e080da
        GF_CHECK_ALLOC_AND_LOG("gfapi", *fop_attr, ret, "dict_new failed", out);
Packit Service e080da
        ret = dict_set_bin(*fop_attr, "lease-id", leaseid, LEASE_ID_SIZE);
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
out:
Packit Service e080da
    if (ret) {
Packit Service e080da
        GF_FREE(leaseid);
Packit Service e080da
        if (dict_create) {
Packit Service e080da
            if (*fop_attr)
Packit Service e080da
                dict_unref(*fop_attr);
Packit Service e080da
            *fop_attr = NULL;
Packit Service e080da
        }
Packit Service e080da
    }
Packit Service e080da
    return ret;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
void
Packit Service e080da
unset_fop_attr(dict_t **fop_attr)
Packit Service e080da
{
Packit Service e080da
    char *lease_id = NULL;
Packit Service e080da
    lease_id = gf_existing_leaseid();
Packit Service e080da
    if (lease_id)
Packit Service e080da
        memset(lease_id, 0, LEASE_ID_SIZE);
Packit Service e080da
    if (*fop_attr) {
Packit Service e080da
        dict_unref(*fop_attr);
Packit Service e080da
        *fop_attr = NULL;
Packit Service e080da
    }
Packit Service e080da
}
Packit Service e080da
struct glfs *
Packit Service e080da
pub_glfs_from_glfd(struct glfs_fd *glfd)
Packit Service e080da
{
Packit Service e080da
    return glfd->fs;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_from_glfd, 3.4.0);
Packit Service e080da
Packit Service e080da
static void
Packit Service e080da
glfs_fd_destroy(struct glfs_fd *glfd)
Packit Service e080da
{
Packit Service e080da
    if (!glfd)
Packit Service e080da
        return;
Packit Service e080da
Packit Service e080da
    glfs_lock(glfd->fs, _gf_true);
Packit Service e080da
    {
Packit Service e080da
        list_del_init(&glfd->openfds);
Packit Service e080da
    }
Packit Service e080da
    glfs_unlock(glfd->fs);
Packit Service e080da
Packit Service e080da
    if (glfd->fd) {
Packit Service e080da
        fd_unref(glfd->fd);
Packit Service e080da
        glfd->fd = NULL;
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    GF_FREE(glfd->readdirbuf);
Packit Service e080da
Packit Service e080da
    GF_FREE(glfd);
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
struct glfs_fd *
Packit Service e080da
glfs_fd_new(struct glfs *fs)
Packit Service e080da
{
Packit Service e080da
    struct glfs_fd *glfd = NULL;
Packit Service e080da
Packit Service e080da
    glfd = GF_CALLOC(1, sizeof(*glfd), glfs_mt_glfs_fd_t);
Packit Service e080da
    if (!glfd)
Packit Service e080da
        return NULL;
Packit Service e080da
Packit Service e080da
    glfd->fs = fs;
Packit Service e080da
Packit Service e080da
    INIT_LIST_HEAD(&glfd->openfds);
Packit Service e080da
Packit Service e080da
    GF_REF_INIT(glfd, glfs_fd_destroy);
Packit Service e080da
Packit Service e080da
    return glfd;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
void
Packit Service e080da
glfs_fd_bind(struct glfs_fd *glfd)
Packit Service e080da
{
Packit Service e080da
    struct glfs *fs = NULL;
Packit Service e080da
Packit Service e080da
    fs = glfd->fs;
Packit Service e080da
Packit Service e080da
    glfs_lock(fs, _gf_true);
Packit Service e080da
    {
Packit Service e080da
        list_add_tail(&glfd->openfds, &fs->openfds);
Packit Service e080da
    }
Packit Service e080da
    glfs_unlock(fs);
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
static void *
Packit Service e080da
glfs_poller(void *data)
Packit Service e080da
{
Packit Service e080da
    struct glfs *fs = NULL;
Packit Service e080da
Packit Service e080da
    fs = data;
Packit Service e080da
Packit Service e080da
    event_dispatch(fs->ctx->event_pool);
Packit Service e080da
Packit Service e080da
    return NULL;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
static struct glfs *
Packit Service e080da
glfs_new_fs(const char *volname)
Packit Service e080da
{
Packit Service e080da
    struct glfs *fs = NULL;
Packit Service e080da
Packit Service e080da
    fs = CALLOC(1, sizeof(*fs));
Packit Service e080da
    if (!fs)
Packit Service e080da
        return NULL;
Packit Service e080da
Packit Service e080da
    INIT_LIST_HEAD(&fs->openfds);
Packit Service e080da
    INIT_LIST_HEAD(&fs->upcall_list);
Packit Service e080da
Packit Service e080da
    PTHREAD_MUTEX_INIT(&fs->mutex, NULL, fs->pthread_flags, GLFS_INIT_MUTEX,
Packit Service e080da
                       err);
Packit Service e080da
Packit Service e080da
    PTHREAD_COND_INIT(&fs->cond, NULL, fs->pthread_flags, GLFS_INIT_COND, err);
Packit Service e080da
Packit Service e080da
    PTHREAD_COND_INIT(&fs->child_down_cond, NULL, fs->pthread_flags,
Packit Service e080da
                      GLFS_INIT_COND_CHILD, err);
Packit Service e080da
Packit Service e080da
    PTHREAD_MUTEX_INIT(&fs->upcall_list_mutex, NULL, fs->pthread_flags,
Packit Service e080da
                       GLFS_INIT_MUTEX_UPCALL, err);
Packit Service e080da
Packit Service e080da
    fs->volname = strdup(volname);
Packit Service e080da
    if (!fs->volname)
Packit Service e080da
        goto err;
Packit Service e080da
Packit Service e080da
    fs->pin_refcnt = 0;
Packit Service e080da
    fs->upcall_events = 0;
Packit Service e080da
    fs->up_cbk = NULL;
Packit Service e080da
    fs->up_data = NULL;
Packit Service e080da
Packit Service e080da
    return fs;
Packit Service e080da
Packit Service e080da
err:
Packit Service e080da
    glfs_free_from_ctx(fs);
Packit Service e080da
    return NULL;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
extern xlator_t global_xlator;
Packit Service e080da
extern glusterfs_ctx_t *global_ctx;
Packit Service e080da
extern pthread_mutex_t global_ctx_mutex;
Packit Service e080da
Packit Service e080da
static int
Packit Service e080da
glfs_init_global_ctx()
Packit Service e080da
{
Packit Service e080da
    int ret = 0;
Packit Service e080da
    glusterfs_ctx_t *ctx = NULL;
Packit Service e080da
Packit Service e080da
    pthread_mutex_lock(&global_ctx_mutex);
Packit Service e080da
    {
Packit Service e080da
        if (global_xlator.ctx)
Packit Service e080da
            goto unlock;
Packit Service e080da
Packit Service e080da
        ctx = glusterfs_ctx_new();
Packit Service e080da
        if (!ctx) {
Packit Service e080da
            ret = -1;
Packit Service e080da
            goto unlock;
Packit Service e080da
        }
Packit Service e080da
Packit Service e080da
        gf_log_globals_init(ctx, GF_LOG_NONE);
Packit Service e080da
Packit Service e080da
        global_ctx = ctx;
Packit Service e080da
        global_xlator.ctx = global_ctx;
Packit Service e080da
Packit Service e080da
        ret = glusterfs_ctx_defaults_init(ctx);
Packit Service e080da
        if (ret) {
Packit Service e080da
            global_ctx = NULL;
Packit Service e080da
            global_xlator.ctx = NULL;
Packit Service e080da
            goto unlock;
Packit Service e080da
        }
Packit Service e080da
    }
Packit Service e080da
unlock:
Packit Service e080da
    pthread_mutex_unlock(&global_ctx_mutex);
Packit Service e080da
Packit Service e080da
    if (ret)
Packit Service e080da
        FREE(ctx);
Packit Service e080da
Packit Service e080da
    return ret;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
struct glfs *
Packit Service e080da
pub_glfs_new(const char *volname)
Packit Service e080da
{
Packit Service e080da
    struct glfs *fs = NULL;
Packit Service e080da
    int ret = -1;
Packit Service e080da
    glusterfs_ctx_t *ctx = NULL;
Packit Service e080da
    xlator_t *old_THIS = NULL;
Packit Service e080da
    char pname[16] = "";
Packit Service e080da
    char msg[32] = "";
Packit Service e080da
Packit Service e080da
    if (!volname) {
Packit Service e080da
        errno = EINVAL;
Packit Service e080da
        return NULL;
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    /*
Packit Service e080da
     * Do this as soon as possible in case something else depends on
Packit Service e080da
     * pool allocations.
Packit Service e080da
     */
Packit Service 35f350
    mem_pools_init_early();
Packit Service 35f350
    mem_pools_init_late();
Packit Service e080da
Packit Service e080da
    fs = glfs_new_fs(volname);
Packit Service e080da
    if (!fs)
Packit Service e080da
        goto out;
Packit Service e080da
Packit Service e080da
    ctx = glusterfs_ctx_new();
Packit Service e080da
    if (!ctx)
Packit Service e080da
        goto out;
Packit Service e080da
Packit Service e080da
    /* first globals init, for gf_mem_acct_enable_set () */
Packit Service e080da
Packit Service e080da
    ret = glusterfs_globals_init(ctx);
Packit Service e080da
    if (ret)
Packit Service e080da
        goto out;
Packit Service e080da
Packit Service e080da
    old_THIS = THIS;
Packit Service e080da
    ret = glfs_init_global_ctx();
Packit Service e080da
    if (ret)
Packit Service e080da
        goto out;
Packit Service e080da
Packit Service e080da
    /* then ctx_defaults_init, for xlator_mem_acct_init(THIS) */
Packit Service e080da
Packit Service e080da
    ret = glusterfs_ctx_defaults_init(ctx);
Packit Service e080da
    if (ret)
Packit Service e080da
        goto out;
Packit Service e080da
Packit Service e080da
    fs->ctx = ctx;
Packit Service e080da
    fs->ctx->process_mode = GF_CLIENT_PROCESS;
Packit Service e080da
Packit Service e080da
    ret = glfs_set_logging(fs, "/dev/null", 0);
Packit Service e080da
    if (ret)
Packit Service e080da
        goto out;
Packit Service e080da
Packit Service e080da
    fs->ctx->cmd_args.volfile_id = gf_strdup(volname);
Packit Service e080da
    if (!(fs->ctx->cmd_args.volfile_id)) {
Packit Service e080da
        ret = -1;
Packit Service e080da
        goto out;
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    ret = -1;
Packit Service e080da
#ifdef GF_LINUX_HOST_OS
Packit Service e080da
    ret = prctl(PR_GET_NAME, (unsigned long)pname, 0, 0, 0);
Packit Service e080da
#endif
Packit Service e080da
    if (ret)
Packit Service e080da
        fs->ctx->cmd_args.process_name = gf_strdup("gfapi");
Packit Service e080da
    else {
Packit Service e080da
        snprintf(msg, sizeof(msg), "gfapi.%s", pname);
Packit Service e080da
        fs->ctx->cmd_args.process_name = gf_strdup(msg);
Packit Service e080da
    }
Packit Service e080da
    ret = 0;
Packit Service e080da
Packit Service e080da
out:
Packit Service e080da
    if (ret) {
Packit Service e080da
        if (fs) {
Packit Service e080da
            glfs_fini(fs);
Packit Service e080da
            fs = NULL;
Packit Service e080da
        } else {
Packit Service e080da
            /* glfs_fini() calls mem_pools_fini() too */
Packit Service e080da
            mem_pools_fini();
Packit Service e080da
        }
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    if (old_THIS)
Packit Service e080da
        THIS = old_THIS;
Packit Service e080da
Packit Service e080da
    return fs;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_new, 3.4.0);
Packit Service e080da
Packit Service e080da
struct glfs *
Packit Service e080da
priv_glfs_new_from_ctx(glusterfs_ctx_t *ctx)
Packit Service e080da
{
Packit Service e080da
    struct glfs *fs = NULL;
Packit Service e080da
Packit Service e080da
    if (!ctx)
Packit Service e080da
        goto out;
Packit Service e080da
Packit Service e080da
    fs = glfs_new_fs("");
Packit Service e080da
    if (!fs)
Packit Service e080da
        goto out;
Packit Service e080da
Packit Service e080da
    fs->ctx = ctx;
Packit Service e080da
Packit Service e080da
out:
Packit Service e080da
    return fs;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_new_from_ctx, 3.7.0);
Packit Service e080da
Packit Service e080da
void
Packit Service e080da
priv_glfs_free_from_ctx(struct glfs *fs)
Packit Service e080da
{
Packit Service e080da
    upcall_entry *u_list = NULL;
Packit Service e080da
    upcall_entry *tmp = NULL;
Packit Service e080da
Packit Service e080da
    if (!fs)
Packit Service e080da
        return;
Packit Service e080da
Packit Service e080da
    /* cleanup upcall structures */
Packit Service e080da
    list_for_each_entry_safe(u_list, tmp, &fs->upcall_list, upcall_list)
Packit Service e080da
    {
Packit Service e080da
        list_del_init(&u_list->upcall_list);
Packit Service e080da
        GF_FREE(u_list->upcall_data.data);
Packit Service e080da
        GF_FREE(u_list);
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    PTHREAD_MUTEX_DESTROY(&fs->mutex, fs->pthread_flags, GLFS_INIT_MUTEX);
Packit Service e080da
Packit Service e080da
    PTHREAD_COND_DESTROY(&fs->cond, fs->pthread_flags, GLFS_INIT_COND);
Packit Service e080da
Packit Service e080da
    PTHREAD_COND_DESTROY(&fs->child_down_cond, fs->pthread_flags,
Packit Service e080da
                         GLFS_INIT_COND_CHILD);
Packit Service e080da
Packit Service e080da
    PTHREAD_MUTEX_DESTROY(&fs->upcall_list_mutex, fs->pthread_flags,
Packit Service e080da
                          GLFS_INIT_MUTEX_UPCALL);
Packit Service e080da
Packit Service e080da
    if (fs->oldvolfile)
Packit Service e080da
        FREE(fs->oldvolfile);
Packit Service e080da
Packit Service e080da
    FREE(fs->volname);
Packit Service e080da
Packit Service e080da
    FREE(fs);
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_free_from_ctx, 3.7.0);
Packit Service e080da
Packit Service e080da
int
Packit Service e080da
pub_glfs_set_volfile(struct glfs *fs, const char *volfile)
Packit Service e080da
{
Packit Service e080da
    cmd_args_t *cmd_args = NULL;
Packit Service e080da
Packit Service e080da
    cmd_args = &fs->ctx->cmd_args;
Packit Service e080da
Packit Service e080da
    if (vol_assigned(cmd_args))
Packit Service e080da
        return -1;
Packit Service e080da
Packit Service e080da
    cmd_args->volfile = gf_strdup(volfile);
Packit Service e080da
    if (!cmd_args->volfile)
Packit Service e080da
        return -1;
Packit Service e080da
    return 0;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_set_volfile, 3.4.0);
Packit Service e080da
Packit Service e080da
int
Packit Service e080da
pub_glfs_set_logging(struct glfs *fs, const char *logfile, int loglevel)
Packit Service e080da
{
Packit Service e080da
    int ret = -1;
Packit Service e080da
    char *tmplog = NULL;
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
    if (!logfile) {
Packit Service e080da
        ret = gf_set_log_file_path(&fs->ctx->cmd_args, fs->ctx);
Packit Service e080da
        if (ret)
Packit Service e080da
            goto out;
Packit Service e080da
        tmplog = fs->ctx->cmd_args.log_file;
Packit Service e080da
    } else {
Packit Service e080da
        tmplog = (char *)logfile;
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    /* finish log set parameters before init */
Packit Service e080da
    if (loglevel >= 0)
Packit Service e080da
        gf_log_set_loglevel(fs->ctx, loglevel);
Packit Service e080da
Packit Service e080da
    ret = gf_log_init(fs->ctx, tmplog, NULL);
Packit Service e080da
    if (ret)
Packit Service e080da
        goto out;
Packit Service e080da
Packit Service e080da
    ret = gf_log_inject_timer_event(fs->ctx);
Packit Service e080da
    if (ret)
Packit Service e080da
        goto out;
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 ret;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_set_logging, 3.4.0);
Packit Service e080da
Packit Service e080da
int
Packit Service e080da
glfs_init_wait(struct glfs *fs)
Packit Service e080da
{
Packit Service e080da
    int ret = -1;
Packit Service e080da
Packit Service e080da
    /* Always a top-down call, use glfs_lock() */
Packit Service e080da
    glfs_lock(fs, _gf_true);
Packit Service e080da
    {
Packit Service e080da
        while (!fs->init)
Packit Service e080da
            pthread_cond_wait(&fs->cond, &fs->mutex);
Packit Service e080da
        ret = fs->ret;
Packit Service e080da
        errno = fs->err;
Packit Service e080da
    }
Packit Service e080da
    glfs_unlock(fs);
Packit Service e080da
Packit Service e080da
    return ret;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
void
Packit Service e080da
priv_glfs_init_done(struct glfs *fs, int ret)
Packit Service e080da
{
Packit Service e080da
    glfs_init_cbk init_cbk;
Packit Service e080da
Packit Service e080da
    if (!fs) {
Packit Service e080da
        gf_msg("glfs", GF_LOG_ERROR, EINVAL, API_MSG_GLFS_FSOBJ_NULL,
Packit Service e080da
               "fs is NULL");
Packit Service e080da
        goto out;
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    init_cbk = fs->init_cbk;
Packit Service e080da
Packit Service e080da
    /* Always a bottom-up call, use mutex_lock() */
Packit Service e080da
    pthread_mutex_lock(&fs->mutex);
Packit Service e080da
    {
Packit Service e080da
        fs->init = 1;
Packit Service e080da
        fs->ret = ret;
Packit Service e080da
        fs->err = errno;
Packit Service e080da
Packit Service e080da
        if (!init_cbk)
Packit Service e080da
            pthread_cond_broadcast(&fs->cond);
Packit Service e080da
    }
Packit Service e080da
    pthread_mutex_unlock(&fs->mutex);
Packit Service e080da
Packit Service e080da
    if (init_cbk)
Packit Service e080da
        init_cbk(fs, ret);
Packit Service e080da
out:
Packit Service e080da
    return;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_init_done, 3.4.0);
Packit Service e080da
Packit Service e080da
int
Packit Service e080da
glfs_init_common(struct glfs *fs)
Packit Service e080da
{
Packit Service e080da
    int ret = -1;
Packit Service e080da
Packit Service e080da
    ret = create_master(fs);
Packit Service e080da
    if (ret)
Packit Service e080da
        return ret;
Packit Service e080da
Packit Service e080da
    ret = gf_thread_create(&fs->poller, NULL, glfs_poller, fs, "glfspoll");
Packit Service e080da
    if (ret)
Packit Service e080da
        return ret;
Packit Service e080da
Packit Service e080da
    ret = glfs_volumes_init(fs);
Packit Service e080da
    if (ret)
Packit Service e080da
        return ret;
Packit Service e080da
Packit Service e080da
    fs->dev_id = gf_dm_hashfn(fs->volname, strlen(fs->volname));
Packit Service e080da
    return ret;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
int
Packit Service e080da
glfs_init_async(struct glfs *fs, glfs_init_cbk cbk)
Packit Service e080da
{
Packit Service e080da
    int ret = -1;
Packit Service e080da
Packit Service e080da
    if (!fs || !fs->ctx) {
Packit Service e080da
        gf_msg("glfs", GF_LOG_ERROR, EINVAL, API_MSG_INVALID_ENTRY,
Packit Service e080da
               "fs is not properly initialized.");
Packit Service e080da
        errno = EINVAL;
Packit Service e080da
        return ret;
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    fs->init_cbk = cbk;
Packit Service e080da
Packit Service e080da
    ret = glfs_init_common(fs);
Packit Service e080da
Packit Service e080da
    return ret;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
int
Packit Service e080da
pub_glfs_init(struct glfs *fs)
Packit Service e080da
{
Packit Service e080da
    int ret = -1;
Packit Service e080da
Packit Service e080da
    DECLARE_OLD_THIS;
Packit Service e080da
Packit Service e080da
    if (!fs || !fs->ctx) {
Packit Service e080da
        gf_msg("glfs", GF_LOG_ERROR, EINVAL, API_MSG_INVALID_ENTRY,
Packit Service e080da
               "fs is not properly initialized.");
Packit Service e080da
        errno = EINVAL;
Packit Service e080da
        return ret;
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
Packit Service e080da
Packit Service e080da
    ret = glfs_init_common(fs);
Packit Service e080da
    if (ret)
Packit Service e080da
        goto out;
Packit Service e080da
Packit Service e080da
    ret = glfs_init_wait(fs);
Packit Service e080da
out:
Packit Service e080da
    __GLFS_EXIT_FS;
Packit Service e080da
Packit Service e080da
    /* Set the initial current working directory to "/" */
Packit Service e080da
    if (ret >= 0) {
Packit Service e080da
        ret = glfs_chdir(fs, "/");
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
invalid_fs:
Packit Service e080da
    return ret;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_init, 3.4.0);
Packit Service e080da
Packit Service e080da
static int
Packit Service e080da
glusterfs_ctx_destroy(glusterfs_ctx_t *ctx)
Packit Service e080da
{
Packit Service e080da
    call_pool_t *pool = NULL;
Packit Service e080da
    int ret = 0;
Packit Service e080da
    glusterfs_graph_t *trav_graph = NULL;
Packit Service e080da
    glusterfs_graph_t *tmp = NULL;
Packit Service e080da
Packit Service e080da
    if (ctx == NULL)
Packit Service e080da
        return 0;
Packit Service e080da
Packit Service e080da
    if (ctx->cmd_args.curr_server)
Packit Service e080da
        glfs_free_volfile_servers(&ctx->cmd_args);
Packit Service e080da
Packit Service e080da
    glfs_free_xlator_options(&ctx->cmd_args);
Packit Service e080da
Packit Service e080da
    /* For all the graphs, crawl through the xlator_t structs and free
Packit Service e080da
     * all its members except for the mem_acct member,
Packit Service e080da
     * as GF_FREE will be referencing it.
Packit Service e080da
     */
Packit Service e080da
    list_for_each_entry_safe(trav_graph, tmp, &ctx->graphs, list)
Packit Service e080da
    {
Packit Service e080da
        xlator_tree_free_members(trav_graph->first);
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    /* Free the memory pool */
Packit Service e080da
    if (ctx->stub_mem_pool)
Packit Service e080da
        mem_pool_destroy(ctx->stub_mem_pool);
Packit Service e080da
    if (ctx->dict_pool)
Packit Service e080da
        mem_pool_destroy(ctx->dict_pool);
Packit Service e080da
    if (ctx->dict_data_pool)
Packit Service e080da
        mem_pool_destroy(ctx->dict_data_pool);
Packit Service e080da
    if (ctx->dict_pair_pool)
Packit Service e080da
        mem_pool_destroy(ctx->dict_pair_pool);
Packit Service e080da
    if (ctx->logbuf_pool)
Packit Service e080da
        mem_pool_destroy(ctx->logbuf_pool);
Packit Service e080da
Packit Service e080da
    pool = ctx->pool;
Packit Service e080da
    if (pool) {
Packit Service e080da
        if (pool->frame_mem_pool)
Packit Service e080da
            mem_pool_destroy(pool->frame_mem_pool);
Packit Service e080da
        if (pool->stack_mem_pool)
Packit Service e080da
            mem_pool_destroy(pool->stack_mem_pool);
Packit Service e080da
        LOCK_DESTROY(&pool->lock);
Packit Service e080da
        GF_FREE(pool);
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    /* Free the event pool */
Packit Service e080da
    ret = event_pool_destroy(ctx->event_pool);
Packit Service e080da
Packit Service e080da
    /* Free the iobuf pool */
Packit Service e080da
    iobuf_pool_destroy(ctx->iobuf_pool);
Packit Service e080da
Packit Service e080da
    GF_FREE(ctx->process_uuid);
Packit Service e080da
    GF_FREE(ctx->cmd_args.volfile_id);
Packit Service e080da
    GF_FREE(ctx->cmd_args.process_name);
Packit Service e080da
Packit Service e080da
    LOCK_DESTROY(&ctx->lock);
Packit Service e080da
    pthread_mutex_destroy(&ctx->notify_lock);
Packit Service e080da
    pthread_cond_destroy(&ctx->notify_cond);
Packit Service e080da
Packit Service e080da
    /* Free all the graph structs and its containing xlator_t structs
Packit Service e080da
     * from this point there should be no reference to GF_FREE/GF_CALLOC
Packit Service e080da
     * as it will try to access mem_acct and the below function would
Packit Service e080da
     * have freed the same.
Packit Service e080da
     */
Packit Service e080da
    list_for_each_entry_safe(trav_graph, tmp, &ctx->graphs, list)
Packit Service e080da
    {
Packit Service e080da
        glusterfs_graph_destroy_residual(trav_graph);
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    FREE(ctx);
Packit Service e080da
Packit Service e080da
    return ret;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
int
Packit Service e080da
pub_glfs_fini(struct glfs *fs)
Packit Service e080da
{
Packit Service e080da
    int ret = -1;
Packit Service e080da
    int countdown = 100;
Packit Service e080da
    xlator_t *subvol = NULL;
Packit Service e080da
    glusterfs_ctx_t *ctx = NULL;
Packit Service e080da
    glusterfs_graph_t *graph = NULL;
Packit Service e080da
    call_pool_t *call_pool = NULL;
Packit Service e080da
    int fs_init = 0;
Packit Service e080da
    int err = -1;
Packit Service e080da
Packit Service e080da
    DECLARE_OLD_THIS;
Packit Service e080da
Packit Service e080da
    if (!fs) {
Packit Service e080da
        errno = EINVAL;
Packit Service e080da
        goto invalid_fs;
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    ctx = fs->ctx;
Packit Service e080da
    if (!ctx) {
Packit Service e080da
        goto free_fs;
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    THIS = fs->ctx->master;
Packit Service e080da
Packit Service e080da
    if (ctx->mgmt) {
Packit Service e080da
        rpc_clnt_disable(ctx->mgmt);
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    call_pool = fs->ctx->pool;
Packit Service e080da
Packit Service e080da
    while (countdown--) {
Packit Service e080da
        /* give some time for background frames to finish */
Packit Service e080da
        pthread_mutex_lock(&fs->mutex);
Packit Service e080da
        {
Packit Service e080da
            /* Do we need to increase countdown? */
Packit Service e080da
            if ((!call_pool->cnt) && (!fs->pin_refcnt)) {
Packit Service e080da
                gf_msg_trace("glfs", 0,
Packit Service e080da
                             "call_pool_cnt - %" PRId64
Packit Service e080da
                             ","
Packit Service e080da
                             "pin_refcnt - %d",
Packit Service e080da
                             call_pool->cnt, fs->pin_refcnt);
Packit Service e080da
Packit Service e080da
                ctx->cleanup_started = 1;
Packit Service e080da
                pthread_mutex_unlock(&fs->mutex);
Packit Service e080da
                break;
Packit Service e080da
            }
Packit Service e080da
        }
Packit Service e080da
        pthread_mutex_unlock(&fs->mutex);
Packit Service e080da
        usleep(100000);
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    /* leaked frames may exist, we ignore */
Packit Service e080da
Packit Service e080da
    /*We deem glfs_fini as successful if there are no pending frames in the call
Packit Service e080da
     *pool*/
Packit Service e080da
    ret = (call_pool->cnt == 0) ? 0 : -1;
Packit Service e080da
Packit Service e080da
    pthread_mutex_lock(&fs->mutex);
Packit Service e080da
    {
Packit Service e080da
        fs_init = fs->init;
Packit Service e080da
    }
Packit Service e080da
    pthread_mutex_unlock(&fs->mutex);
Packit Service e080da
Packit Service e080da
    if (fs_init != 0) {
Packit Service e080da
        subvol = glfs_active_subvol(fs);
Packit Service e080da
        if (subvol) {
Packit Service e080da
            /* PARENT_DOWN within glfs_subvol_done() is issued
Packit Service e080da
               only on graph switch (new graph should activiate
Packit Service e080da
               and decrement the extra @winds count taken in
Packit Service e080da
               glfs_graph_setup()
Packit Service e080da
Packit Service e080da
               Since we are explicitly destroying,
Packit Service e080da
               PARENT_DOWN is necessary
Packit Service e080da
            */
Packit Service e080da
            xlator_notify(subvol, GF_EVENT_PARENT_DOWN, subvol, 0);
Packit Service e080da
            /* Here we wait for GF_EVENT_CHILD_DOWN before exiting,
Packit Service e080da
               in case of asynchrnous cleanup
Packit Service e080da
            */
Packit Service e080da
            graph = subvol->graph;
Packit Service e080da
            err = pthread_mutex_lock(&fs->mutex);
Packit Service e080da
            if (err != 0) {
Packit Service e080da
                gf_msg("glfs", GF_LOG_ERROR, err, API_MSG_FSMUTEX_LOCK_FAILED,
Packit Service e080da
                       "pthread lock on glfs mutex, "
Packit Service e080da
                       "returned error: (%s)",
Packit Service e080da
                       strerror(err));
Packit Service e080da
                goto fail;
Packit Service e080da
            }
Packit Service e080da
            /* check and wait for CHILD_DOWN for active subvol*/
Packit Service e080da
            {
Packit Service e080da
                while (graph->used) {
Packit Service e080da
                    err = pthread_cond_wait(&fs->child_down_cond, &fs->mutex);
Packit Service e080da
                    if (err != 0)
Packit Service e080da
                        gf_msg("glfs", GF_LOG_INFO, err,
Packit Service e080da
                               API_MSG_COND_WAIT_FAILED,
Packit Service e080da
                               "%s cond wait failed %s", subvol->name,
Packit Service e080da
                               strerror(err));
Packit Service e080da
                }
Packit Service e080da
            }
Packit Service e080da
Packit Service e080da
            err = pthread_mutex_unlock(&fs->mutex);
Packit Service e080da
            if (err != 0) {
Packit Service e080da
                gf_msg("glfs", GF_LOG_ERROR, err, API_MSG_FSMUTEX_UNLOCK_FAILED,
Packit Service e080da
                       "pthread unlock on glfs mutex, "
Packit Service e080da
                       "returned error: (%s)",
Packit Service e080da
                       strerror(err));
Packit Service e080da
                goto fail;
Packit Service e080da
            }
Packit Service e080da
        }
Packit Service e080da
        glfs_subvol_done(fs, subvol);
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    ctx->cleanup_started = 1;
Packit Service e080da
Packit Service e080da
    if (fs_init != 0) {
Packit Service e080da
        /* Destroy all the inode tables of all the graphs.
Packit Service e080da
         * NOTE:
Packit Service e080da
         * - inode objects should be destroyed before calling fini()
Packit Service e080da
         *   of each xlator, as fini() and forget() of the xlators
Packit Service e080da
         *   can share few common locks or data structures, calling
Packit Service e080da
         *   fini first might destroy those required by forget
Packit Service e080da
         *   ( eg: in quick-read)
Packit Service e080da
         * - The call to inode_table_destroy_all is not required when
Packit Service e080da
         *   the cleanup during graph switch is implemented to perform
Packit Service e080da
         *   inode table destroy.
Packit Service e080da
         */
Packit Service e080da
        inode_table_destroy_all(ctx);
Packit Service e080da
Packit Service e080da
        /* Call fini() of all the xlators in the active graph
Packit Service e080da
         * NOTE:
Packit Service e080da
         * - xlator fini() should be called before destroying any of
Packit Service e080da
         *   the threads. (eg: fini() in protocol-client uses timer
Packit Service e080da
         *   thread) */
Packit Service e080da
        glusterfs_graph_deactivate(ctx->active);
Packit Service e080da
Packit Service e080da
        /* Join the syncenv_processor threads and cleanup
Packit Service e080da
         * syncenv resources*/
Packit Service e080da
        syncenv_destroy(ctx->env);
Packit Service e080da
Packit Service e080da
        /* Join the poller thread */
Packit Service e080da
        if (event_dispatch_destroy(ctx->event_pool) < 0)
Packit Service e080da
            ret = -1;
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    /* Avoid dispatching events to mgmt after freed,
Packit Service e080da
     * unreference mgmt after the event_dispatch_destroy */
Packit Service e080da
    if (ctx->mgmt) {
Packit Service e080da
        rpc_clnt_unref(ctx->mgmt);
Packit Service e080da
        ctx->mgmt = NULL;
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    /* log infra has to be brought down before destroying
Packit Service e080da
     * timer registry, as logging uses timer infra
Packit Service e080da
     */
Packit Service e080da
    if (gf_log_fini(ctx) != 0)
Packit Service e080da
        ret = -1;
Packit Service e080da
Packit Service e080da
    /* Join the timer thread */
Packit Service e080da
    if (fs_init != 0) {
Packit Service e080da
        gf_timer_registry_destroy(ctx);
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    /* Destroy the context and the global pools */
Packit Service e080da
    if (glusterfs_ctx_destroy(ctx) != 0)
Packit Service e080da
        ret = -1;
Packit Service e080da
Packit Service e080da
free_fs:
Packit Service e080da
    glfs_free_from_ctx(fs);
Packit Service e080da
Packit Service e080da
    /*
Packit Service e080da
     * Do this as late as possible in case anything else has (or
Packit Service e080da
     * grows) a dependency on mem-pool allocations.
Packit Service e080da
     */
Packit Service e080da
    mem_pools_fini();
Packit Service e080da
Packit Service e080da
fail:
Packit Service e080da
    if (!ret)
Packit Service e080da
        ret = err;
Packit Service e080da
Packit Service e080da
    __GLFS_EXIT_FS;
Packit Service e080da
Packit Service e080da
invalid_fs:
Packit Service e080da
    return ret;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fini, 3.4.0);
Packit Service e080da
Packit Service e080da
ssize_t
Packit Service e080da
pub_glfs_get_volfile(struct glfs *fs, void *buf, size_t len)
Packit Service e080da
{
Packit Service e080da
    ssize_t res = -1;
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
    glfs_lock(fs, _gf_true);
Packit Service e080da
    if (len >= fs->oldvollen) {
Packit Service e080da
        gf_msg_trace("glfs", 0, "copying %zu to %p", len, buf);
Packit Service e080da
        memcpy(buf, fs->oldvolfile, len);
Packit Service e080da
        res = len;
Packit Service e080da
    } else {
Packit Service e080da
        res = len - fs->oldvollen;
Packit Service e080da
        gf_msg_trace("glfs", 0, "buffer is %zd too short", -res);
Packit Service e080da
    }
Packit Service e080da
    glfs_unlock(fs);
Packit Service e080da
Packit Service e080da
    __GLFS_EXIT_FS;
Packit Service e080da
Packit Service e080da
invalid_fs:
Packit Service e080da
    return res;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_get_volfile, 3.6.0);
Packit Service e080da
Packit Service e080da
int
Packit Service e080da
priv_glfs_ipc(struct glfs *fs, int opcode, void *xd_in, void **xd_out)
Packit Service e080da
{
Packit Service e080da
    xlator_t *subvol = NULL;
Packit Service e080da
    int ret = -1;
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
    subvol = glfs_active_subvol(fs);
Packit Service e080da
    if (!subvol) {
Packit Service e080da
        ret = -1;
Packit Service e080da
        errno = EIO;
Packit Service e080da
        goto out;
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    ret = syncop_ipc(subvol, opcode, (dict_t *)xd_in, (dict_t **)xd_out);
Packit Service e080da
    DECODE_SYNCOP_ERR(ret);
Packit Service e080da
Packit Service e080da
out:
Packit Service e080da
    glfs_subvol_done(fs, subvol);
Packit Service e080da
    __GLFS_EXIT_FS;
Packit Service e080da
Packit Service e080da
invalid_fs:
Packit Service e080da
    return ret;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_ipc, 3.12.0);
Packit Service e080da
Packit Service e080da
void
Packit Service e080da
pub_glfs_free(void *ptr)
Packit Service e080da
{
Packit Service e080da
    GLFS_FREE(ptr);
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_free, 3.7.16);
Packit Service e080da
Packit Service e080da
struct glfs *
Packit Service e080da
pub_glfs_upcall_get_fs(struct glfs_upcall *arg)
Packit Service e080da
{
Packit Service e080da
    return arg->fs;
Packit Service e080da
}
Packit Service e080da
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_get_fs, 3.7.16);
Packit Service e080da
Packit Service e080da
enum glfs_upcall_reason
Packit Service e080da
pub_glfs_upcall_get_reason(struct glfs_upcall *arg)
Packit Service e080da
{
Packit Service e080da
    return arg->reason;
Packit Service e080da
}
Packit Service e080da
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_get_reason, 3.7.16);
Packit Service e080da
Packit Service e080da
void *
Packit Service e080da
pub_glfs_upcall_get_event(struct glfs_upcall *arg)
Packit Service e080da
{
Packit Service e080da
    return arg->event;
Packit Service e080da
}
Packit Service e080da
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_get_event, 3.7.16);
Packit Service e080da
Packit Service e080da
struct glfs_object *
Packit Service e080da
pub_glfs_upcall_inode_get_object(struct glfs_upcall_inode *arg)
Packit Service e080da
{
Packit Service e080da
    return arg->object;
Packit Service e080da
}
Packit Service e080da
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_object, 3.7.16);
Packit Service e080da
Packit Service e080da
uint64_t
Packit Service e080da
pub_glfs_upcall_inode_get_flags(struct glfs_upcall_inode *arg)
Packit Service e080da
{
Packit Service e080da
    return arg->flags;
Packit Service e080da
}
Packit Service e080da
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_flags, 3.7.16);
Packit Service e080da
Packit Service e080da
struct stat *
Packit Service e080da
pub_glfs_upcall_inode_get_stat(struct glfs_upcall_inode *arg)
Packit Service e080da
{
Packit Service e080da
    return &arg->buf;
Packit Service e080da
}
Packit Service e080da
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_stat, 3.7.16);
Packit Service e080da
Packit Service e080da
uint64_t
Packit Service e080da
pub_glfs_upcall_inode_get_expire(struct glfs_upcall_inode *arg)
Packit Service e080da
{
Packit Service e080da
    return arg->expire_time_attr;
Packit Service e080da
}
Packit Service e080da
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_expire, 3.7.16);
Packit Service e080da
Packit Service e080da
struct glfs_object *
Packit Service e080da
pub_glfs_upcall_inode_get_pobject(struct glfs_upcall_inode *arg)
Packit Service e080da
{
Packit Service e080da
    return arg->p_object;
Packit Service e080da
}
Packit Service e080da
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_pobject, 3.7.16);
Packit Service e080da
Packit Service e080da
struct stat *
Packit Service e080da
pub_glfs_upcall_inode_get_pstat(struct glfs_upcall_inode *arg)
Packit Service e080da
{
Packit Service e080da
    return &arg->p_buf;
Packit Service e080da
}
Packit Service e080da
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_pstat, 3.7.16);
Packit Service e080da
Packit Service e080da
struct glfs_object *
Packit Service e080da
pub_glfs_upcall_inode_get_oldpobject(struct glfs_upcall_inode *arg)
Packit Service e080da
{
Packit Service e080da
    return arg->oldp_object;
Packit Service e080da
}
Packit Service e080da
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_oldpobject, 3.7.16);
Packit Service e080da
Packit Service e080da
struct stat *
Packit Service e080da
pub_glfs_upcall_inode_get_oldpstat(struct glfs_upcall_inode *arg)
Packit Service e080da
{
Packit Service e080da
    return &arg->oldp_buf;
Packit Service e080da
}
Packit Service e080da
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_oldpstat, 3.7.16);
Packit Service e080da
Packit Service e080da
struct glfs_object *
Packit Service e080da
pub_glfs_upcall_lease_get_object(struct glfs_upcall_lease *arg)
Packit Service e080da
{
Packit Service e080da
    return arg->object;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_lease_get_object, 4.1.6);
Packit Service e080da
Packit Service e080da
uint32_t
Packit Service e080da
pub_glfs_upcall_lease_get_lease_type(struct glfs_upcall_lease *arg)
Packit Service e080da
{
Packit Service e080da
    return arg->lease_type;
Packit Service e080da
}
Packit Service e080da
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_lease_get_lease_type, 4.1.6);
Packit Service e080da
Packit Service e080da
/* definitions of the GLFS_SYSRQ_* chars are in glfs.h */
Packit Service e080da
static struct glfs_sysrq_help {
Packit Service e080da
    char sysrq;
Packit Service e080da
    char *msg;
Packit Service e080da
} glfs_sysrq_help[] = {{GLFS_SYSRQ_HELP, "(H)elp"},
Packit Service e080da
                       {GLFS_SYSRQ_STATEDUMP, "(S)tatedump"},
Packit Service e080da
                       {0, NULL}};
Packit Service e080da
Packit Service e080da
int
Packit Service e080da
pub_glfs_sysrq(struct glfs *fs, char sysrq)
Packit Service e080da
{
Packit Service e080da
    glusterfs_ctx_t *ctx = NULL;
Packit Service e080da
    int ret = 0;
Packit Service e080da
    int msg_len;
Packit Service e080da
    char msg[1024] = {
Packit Service e080da
        0,
Packit Service e080da
    }; /* should not exceed 1024 chars */
Packit Service e080da
Packit Service e080da
    if (!fs || !fs->ctx) {
Packit Service e080da
        ret = -1;
Packit Service e080da
        errno = EINVAL;
Packit Service e080da
        goto out;
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    ctx = fs->ctx;
Packit Service e080da
Packit Service e080da
    switch (sysrq) {
Packit Service e080da
        case GLFS_SYSRQ_HELP: {
Packit Service e080da
            struct glfs_sysrq_help *usage = NULL;
Packit Service e080da
Packit Service e080da
            for (usage = glfs_sysrq_help; usage->sysrq; usage++) {
Packit Service e080da
                msg_len = strlen(msg);
Packit Service e080da
                snprintf(msg + msg_len, /* append to msg */
Packit Service e080da
                         sizeof(msg) - msg_len - 2,
Packit Service e080da
                         /* - 2 for the " " + terminating \0 */
Packit Service e080da
                         " %s", usage->msg);
Packit Service e080da
            }
Packit Service e080da
Packit Service e080da
            /* not really an 'error', but make sure it gets logged */
Packit Service e080da
            gf_log("glfs", GF_LOG_ERROR, "available events: %s", msg);
Packit Service e080da
Packit Service e080da
            break;
Packit Service e080da
        }
Packit Service e080da
        case GLFS_SYSRQ_STATEDUMP:
Packit Service e080da
            gf_proc_dump_info(SIGUSR1, ctx);
Packit Service e080da
            break;
Packit Service e080da
        default:
Packit Service e080da
            gf_msg("glfs", GF_LOG_ERROR, ENOTSUP, API_MSG_INVALID_ENTRY,
Packit Service e080da
                   "'%c' is not a valid sysrq", sysrq);
Packit Service e080da
            errno = ENOTSUP;
Packit Service e080da
            ret = -1;
Packit Service e080da
    }
Packit Service e080da
out:
Packit Service e080da
    return ret;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_sysrq, 3.10.0);
Packit Service e080da
Packit Service e080da
int
Packit Service e080da
pub_glfs_upcall_register(struct glfs *fs, uint32_t event_list,
Packit Service e080da
                         glfs_upcall_cbk cbk, void *data)
Packit Service e080da
{
Packit Service e080da
    int ret = 0;
Packit Service e080da
Packit Service e080da
    /* list of supported upcall events */
Packit Service e080da
    uint32_t up_events = (GLFS_EVENT_INODE_INVALIDATE |
Packit Service e080da
                          GLFS_EVENT_RECALL_LEASE);
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
    GF_VALIDATE_OR_GOTO(THIS->name, cbk, out);
Packit Service e080da
Packit Service e080da
    /* Event list should be either GLFS_EVENT_ANY
Packit Service e080da
     * or list of supported individual events (up_events)
Packit Service e080da
     */
Packit Service e080da
    if ((event_list != GLFS_EVENT_ANY) && (event_list & ~up_events)) {
Packit Service e080da
        errno = EINVAL;
Packit Service e080da
        ret = -1;
Packit Service e080da
        gf_msg(THIS->name, GF_LOG_ERROR, errno, LG_MSG_INVALID_ARG,
Packit Service e080da
               "invalid event_list (0x%08x)", event_list);
Packit Service e080da
        goto out;
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    /* in case other thread does unregister */
Packit Service e080da
    pthread_mutex_lock(&fs->mutex);
Packit Service e080da
    {
Packit Service e080da
        if (event_list & GLFS_EVENT_INODE_INVALIDATE) {
Packit Service e080da
            /* @todo: Check if features.cache-invalidation is
Packit Service e080da
             * enabled.
Packit Service e080da
             */
Packit Service e080da
            fs->upcall_events |= GF_UPCALL_CACHE_INVALIDATION;
Packit Service e080da
            ret |= GLFS_EVENT_INODE_INVALIDATE;
Packit Service e080da
        }
Packit Service e080da
        if (event_list & GLFS_EVENT_RECALL_LEASE) {
Packit Service e080da
            /* @todo: Check if features.leases is enabled */
Packit Service e080da
            fs->upcall_events |= GF_UPCALL_RECALL_LEASE;
Packit Service e080da
            ret |= GLFS_EVENT_RECALL_LEASE;
Packit Service e080da
        }
Packit Service e080da
        /* Override cbk function if existing */
Packit Service e080da
        fs->up_cbk = cbk;
Packit Service e080da
        fs->up_data = data;
Packit Service e080da
        fs->cache_upcalls = _gf_true;
Packit Service e080da
    }
Packit Service e080da
    pthread_mutex_unlock(&fs->mutex);
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 ret;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_register, 3.13.0);
Packit Service e080da
Packit Service e080da
int
Packit Service e080da
pub_glfs_upcall_unregister(struct glfs *fs, uint32_t event_list)
Packit Service e080da
{
Packit Service e080da
    int ret = 0;
Packit Service e080da
    /* list of supported upcall events */
Packit Service e080da
    uint32_t up_events = (GLFS_EVENT_INODE_INVALIDATE |
Packit Service e080da
                          GLFS_EVENT_RECALL_LEASE);
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
    /* Event list should be either GLFS_EVENT_ANY
Packit Service e080da
     * or list of supported individual events (up_events)
Packit Service e080da
     */
Packit Service e080da
    if ((event_list != GLFS_EVENT_ANY) && (event_list & ~up_events)) {
Packit Service e080da
        errno = EINVAL;
Packit Service e080da
        ret = -1;
Packit Service e080da
        gf_msg(THIS->name, GF_LOG_ERROR, errno, LG_MSG_INVALID_ARG,
Packit Service e080da
               "invalid event_list (0x%08x)", event_list);
Packit Service e080da
        goto out;
Packit Service e080da
    }
Packit Service e080da
Packit Service e080da
    pthread_mutex_lock(&fs->mutex);
Packit Service e080da
    {
Packit Service e080da
        /* We already checked if event_list contains list of supported
Packit Service e080da
         * upcall events. No other specific checks needed as of now for
Packit Service e080da
         * unregister */
Packit Service e080da
        fs->upcall_events &= ~(event_list);
Packit Service e080da
        ret |= ((event_list == GLFS_EVENT_ANY) ? up_events : event_list);
Packit Service e080da
Packit Service e080da
        /* If there are no upcall events registered, reset cbk */
Packit Service e080da
        if (fs->upcall_events == 0) {
Packit Service e080da
            fs->up_cbk = NULL;
Packit Service e080da
            fs->up_data = NULL;
Packit Service e080da
            fs->cache_upcalls = _gf_false;
Packit Service e080da
        }
Packit Service e080da
    }
Packit Service e080da
    pthread_mutex_unlock(&fs->mutex);
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 ret;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_unregister, 3.13.0);