Blame libglusterfs/src/globals.c

Packit Service e080da
/*
Packit Service e080da
  Copyright (c) 2008-2012 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 <pthread.h>
Packit Service e080da
Packit Service e080da
#include "glusterfs/glusterfs.h"
Packit Service e080da
#include "glusterfs/globals.h"
Packit Service e080da
#include "glusterfs/xlator.h"
Packit Service e080da
#include "glusterfs/mem-pool.h"
Packit Service e080da
#include "glusterfs/syncop.h"
Packit Service e080da
#include "glusterfs/libglusterfs-messages.h"
Packit Service e080da
#include "glusterfs/upcall-utils.h"
Packit Service e080da
Packit Service e080da
const char *gf_fop_list[GF_FOP_MAXVALUE] = {
Packit Service e080da
    [GF_FOP_NULL] = "NULL",
Packit Service e080da
    [GF_FOP_STAT] = "STAT",
Packit Service e080da
    [GF_FOP_READLINK] = "READLINK",
Packit Service e080da
    [GF_FOP_MKNOD] = "MKNOD",
Packit Service e080da
    [GF_FOP_MKDIR] = "MKDIR",
Packit Service e080da
    [GF_FOP_UNLINK] = "UNLINK",
Packit Service e080da
    [GF_FOP_RMDIR] = "RMDIR",
Packit Service e080da
    [GF_FOP_SYMLINK] = "SYMLINK",
Packit Service e080da
    [GF_FOP_RENAME] = "RENAME",
Packit Service e080da
    [GF_FOP_LINK] = "LINK",
Packit Service e080da
    [GF_FOP_TRUNCATE] = "TRUNCATE",
Packit Service e080da
    [GF_FOP_OPEN] = "OPEN",
Packit Service e080da
    [GF_FOP_READ] = "READ",
Packit Service e080da
    [GF_FOP_WRITE] = "WRITE",
Packit Service e080da
    [GF_FOP_STATFS] = "STATFS",
Packit Service e080da
    [GF_FOP_FLUSH] = "FLUSH",
Packit Service e080da
    [GF_FOP_FSYNC] = "FSYNC",
Packit Service e080da
    [GF_FOP_SETXATTR] = "SETXATTR",
Packit Service e080da
    [GF_FOP_GETXATTR] = "GETXATTR",
Packit Service e080da
    [GF_FOP_REMOVEXATTR] = "REMOVEXATTR",
Packit Service e080da
    [GF_FOP_OPENDIR] = "OPENDIR",
Packit Service e080da
    [GF_FOP_FSYNCDIR] = "FSYNCDIR",
Packit Service e080da
    [GF_FOP_ACCESS] = "ACCESS",
Packit Service e080da
    [GF_FOP_CREATE] = "CREATE",
Packit Service e080da
    [GF_FOP_FTRUNCATE] = "FTRUNCATE",
Packit Service e080da
    [GF_FOP_FSTAT] = "FSTAT",
Packit Service e080da
    [GF_FOP_LK] = "LK",
Packit Service e080da
    [GF_FOP_LOOKUP] = "LOOKUP",
Packit Service e080da
    [GF_FOP_READDIR] = "READDIR",
Packit Service e080da
    [GF_FOP_INODELK] = "INODELK",
Packit Service e080da
    [GF_FOP_FINODELK] = "FINODELK",
Packit Service e080da
    [GF_FOP_ENTRYLK] = "ENTRYLK",
Packit Service e080da
    [GF_FOP_FENTRYLK] = "FENTRYLK",
Packit Service e080da
    [GF_FOP_XATTROP] = "XATTROP",
Packit Service e080da
    [GF_FOP_FXATTROP] = "FXATTROP",
Packit Service e080da
    [GF_FOP_FSETXATTR] = "FSETXATTR",
Packit Service e080da
    [GF_FOP_FGETXATTR] = "FGETXATTR",
Packit Service e080da
    [GF_FOP_RCHECKSUM] = "RCHECKSUM",
Packit Service e080da
    [GF_FOP_SETATTR] = "SETATTR",
Packit Service e080da
    [GF_FOP_FSETATTR] = "FSETATTR",
Packit Service e080da
    [GF_FOP_READDIRP] = "READDIRP",
Packit Service e080da
    [GF_FOP_GETSPEC] = "GETSPEC",
Packit Service e080da
    [GF_FOP_FORGET] = "FORGET",
Packit Service e080da
    [GF_FOP_RELEASE] = "RELEASE",
Packit Service e080da
    [GF_FOP_RELEASEDIR] = "RELEASEDIR",
Packit Service e080da
    [GF_FOP_FREMOVEXATTR] = "FREMOVEXATTR",
Packit Service e080da
    [GF_FOP_FALLOCATE] = "FALLOCATE",
Packit Service e080da
    [GF_FOP_DISCARD] = "DISCARD",
Packit Service e080da
    [GF_FOP_ZEROFILL] = "ZEROFILL",
Packit Service e080da
    [GF_FOP_IPC] = "IPC",
Packit Service e080da
    [GF_FOP_SEEK] = "SEEK",
Packit Service e080da
    [GF_FOP_LEASE] = "LEASE",
Packit Service e080da
    [GF_FOP_COMPOUND] = "COMPOUND",
Packit Service e080da
    [GF_FOP_GETACTIVELK] = "GETACTIVELK",
Packit Service e080da
    [GF_FOP_SETACTIVELK] = "SETACTIVELK",
Packit Service e080da
    [GF_FOP_PUT] = "PUT",
Packit Service e080da
    [GF_FOP_ICREATE] = "ICREATE",
Packit Service e080da
    [GF_FOP_NAMELINK] = "NAMELINK",
Packit Service e080da
    [GF_FOP_COPY_FILE_RANGE] = "COPY_FILE_RANGE",
Packit Service e080da
};
Packit Service e080da
Packit Service e080da
const char *gf_upcall_list[GF_UPCALL_FLAGS_MAXVALUE] = {
Packit Service e080da
    [GF_UPCALL_NULL] = "NULL",
Packit Service e080da
    [GF_UPCALL] = "UPCALL",
Packit Service e080da
    [GF_UPCALL_CI_STAT] = "CI_IATT",
Packit Service e080da
    [GF_UPCALL_CI_XATTR] = "CI_XATTR",
Packit Service e080da
    [GF_UPCALL_CI_RENAME] = "CI_RENAME",
Packit Service e080da
    [GF_UPCALL_CI_NLINK] = "CI_UNLINK",
Packit Service e080da
    [GF_UPCALL_CI_FORGET] = "CI_FORGET",
Packit Service e080da
    [GF_UPCALL_LEASE_RECALL] = "LEASE_RECALL",
Packit Service e080da
};
Packit Service e080da
Packit Service e080da
/* THIS */
Packit Service e080da
Packit Service e080da
/* This global ctx is a bad hack to prevent some of the libgfapi crashes.
Packit Service e080da
 * This should be removed once the patch on resource pool is accepted
Packit Service e080da
 */
Packit Service e080da
glusterfs_ctx_t *global_ctx = NULL;
Packit Service e080da
pthread_mutex_t global_ctx_mutex = PTHREAD_MUTEX_INITIALIZER;
Packit Service e080da
xlator_t global_xlator;
Packit Service e080da
static int gf_global_mem_acct_enable = 1;
Packit Service e080da
static pthread_once_t globals_inited = PTHREAD_ONCE_INIT;
Packit Service e080da
Packit Service a90fdc
static pthread_key_t free_key;
Packit Service a90fdc
Packit Service a90fdc
static __thread xlator_t *thread_xlator = NULL;
Packit Service a90fdc
static __thread void *thread_synctask = NULL;
Packit Service a90fdc
static __thread void *thread_leaseid = NULL;
Packit Service a90fdc
static __thread struct syncopctx thread_syncopctx = {};
Packit Service a90fdc
static __thread char thread_uuid_buf[GF_UUID_BUF_SIZE] = {};
Packit Service a90fdc
static __thread char thread_lkowner_buf[GF_LKOWNER_BUF_SIZE] = {};
Packit Service a90fdc
static __thread char thread_leaseid_buf[GF_LEASE_ID_BUF_SIZE] = {};
Packit Service a90fdc
Packit Service e080da
int
Packit Service e080da
gf_global_mem_acct_enable_get(void)
Packit Service e080da
{
Packit Service e080da
    return gf_global_mem_acct_enable;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
int
Packit Service e080da
gf_global_mem_acct_enable_set(int val)
Packit Service e080da
{
Packit Service e080da
    gf_global_mem_acct_enable = val;
Packit Service e080da
    return 0;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
static struct xlator_cbks global_cbks = {
Packit Service e080da
    .forget = NULL,
Packit Service e080da
    .release = NULL,
Packit Service e080da
    .releasedir = NULL,
Packit Service e080da
    .invalidate = NULL,
Packit Service e080da
    .client_destroy = NULL,
Packit Service e080da
    .client_disconnect = NULL,
Packit Service e080da
    .ictxmerge = NULL,
Packit Service e080da
    .ictxsize = NULL,
Packit Service e080da
    .fdctxsize = NULL,
Packit Service e080da
};
Packit Service e080da
Packit Service e080da
/* This is required to get through the check in graph.c */
Packit Service e080da
static struct xlator_fops global_fops = {};
Packit Service e080da
Packit Service e080da
static int
Packit Service e080da
global_xl_reconfigure(xlator_t *this, dict_t *options)
Packit Service e080da
{
Packit Service e080da
    int ret = -1;
Packit Service e080da
    gf_boolean_t bool_opt = _gf_false;
Packit Service e080da
Packit Service e080da
    /* This is not added in volume dump, hence adding the options in log
Packit Service e080da
       would be helpful for debugging later */
Packit Service e080da
    dict_dump_to_log(options);
Packit Service e080da
Packit Service e080da
    GF_OPTION_RECONF("measure-latency", bool_opt, options, bool, out);
Packit Service e080da
    this->ctx->measure_latency = bool_opt;
Packit Service e080da
Packit Service e080da
    GF_OPTION_RECONF("metrics-dump-path", this->ctx->config.metrics_dumppath,
Packit Service e080da
                     options, str, out);
Packit Service e080da
Packit Service e080da
    /* TODO: add more things here */
Packit Service e080da
    ret = 0;
Packit Service e080da
out:
Packit Service e080da
    return ret;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
static int
Packit Service e080da
global_xl_init(xlator_t *this)
Packit Service e080da
{
Packit Service e080da
    int ret = -1;
Packit Service e080da
    gf_boolean_t bool_opt = false;
Packit Service e080da
Packit Service e080da
    GF_OPTION_INIT("measure-latency", bool_opt, bool, out);
Packit Service e080da
    this->ctx->measure_latency = bool_opt;
Packit Service e080da
Packit Service e080da
    GF_OPTION_INIT("metrics-dump-path", this->ctx->config.metrics_dumppath, str,
Packit Service e080da
                   out);
Packit Service e080da
Packit Service e080da
    ret = 0;
Packit Service e080da
Packit Service e080da
out:
Packit Service e080da
    return ret;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
static void
Packit Service e080da
global_xl_fini(xlator_t *this)
Packit Service e080da
{
Packit Service e080da
    return;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
struct volume_options global_xl_options[] = {
Packit Service e080da
    {.key = {"measure-latency"},
Packit Service e080da
     .type = GF_OPTION_TYPE_BOOL,
Packit Service e080da
     .default_value = "no",
Packit Service e080da
     .op_version = {GD_OP_VERSION_4_0_0},
Packit Service e080da
     .flags = OPT_FLAG_SETTABLE,
Packit Service e080da
     .tags = {"global", "context"},
Packit Service e080da
     .description = "Use this option to toggle measuring latency"},
Packit Service e080da
    {.key = {"metrics-dump-path"},
Packit Service e080da
     .type = GF_OPTION_TYPE_STR,
Packit Service e080da
     .default_value = "{{gluster_workdir}}/metrics",
Packit Service e080da
     .op_version = {GD_OP_VERSION_4_0_0},
Packit Service e080da
     .flags = OPT_FLAG_SETTABLE,
Packit Service e080da
     .tags = {"global", "context"},
Packit Service e080da
     .description = "Use this option to set the metrics dump path"},
Packit Service e080da
Packit Service e080da
    {
Packit Service e080da
        .key = {NULL},
Packit Service e080da
    },
Packit Service e080da
};
Packit Service e080da
Packit Service e080da
static volume_opt_list_t global_xl_opt_list;
Packit Service e080da
Packit Service a90fdc
void
Packit Service e080da
glusterfs_this_init()
Packit Service e080da
{
Packit Service e080da
    global_xlator.name = "glusterfs";
Packit Service e080da
    global_xlator.type = GF_GLOBAL_XLATOR_NAME;
Packit Service e080da
    global_xlator.cbks = &global_cbks;
Packit Service e080da
    global_xlator.fops = &global_fops;
Packit Service e080da
    global_xlator.reconfigure = global_xl_reconfigure;
Packit Service e080da
    global_xlator.init = global_xl_init;
Packit Service e080da
    global_xlator.fini = global_xl_fini;
Packit Service e080da
Packit Service e080da
    INIT_LIST_HEAD(&global_xlator.volume_options);
Packit Service e080da
    INIT_LIST_HEAD(&global_xl_opt_list.list);
Packit Service e080da
    global_xl_opt_list.given_opt = global_xl_options;
Packit Service e080da
Packit Service e080da
    list_add_tail(&global_xl_opt_list.list, &global_xlator.volume_options);
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
xlator_t **
Packit Service e080da
__glusterfs_this_location()
Packit Service e080da
{
Packit Service a90fdc
    xlator_t **this_location;
Packit Service 173fb3
Packit Service a90fdc
    this_location = &thread_xlator;
Packit Service a90fdc
    if (*this_location == NULL) {
Packit Service a90fdc
        thread_xlator = &global_xlator;
Packit Service 35f350
    }
Packit Service a90fdc
Packit Service e080da
    return this_location;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
xlator_t *
Packit Service e080da
glusterfs_this_get()
Packit Service e080da
{
Packit Service a90fdc
    return *__glusterfs_this_location();
Packit Service e080da
}
Packit Service e080da
Packit Service a90fdc
void
Packit Service e080da
glusterfs_this_set(xlator_t *this)
Packit Service e080da
{
Packit Service a90fdc
    thread_xlator = this;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
/* SYNCOPCTX */
Packit Service e080da
Packit Service e080da
void *
Packit Service e080da
syncopctx_getctx()
Packit Service e080da
{
Packit Service a90fdc
    return &thread_syncopctx;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
/* SYNCTASK */
Packit Service e080da
Packit Service e080da
void *
Packit Service e080da
synctask_get()
Packit Service e080da
{
Packit Service a90fdc
    return thread_synctask;
Packit Service e080da
}
Packit Service e080da
Packit Service a90fdc
void
Packit Service e080da
synctask_set(void *synctask)
Packit Service e080da
{
Packit Service a90fdc
    thread_synctask = synctask;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
// UUID_BUFFER
Packit Service e080da
Packit Service e080da
char *
Packit Service e080da
glusterfs_uuid_buf_get()
Packit Service e080da
{
Packit Service a90fdc
    return thread_uuid_buf;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
/* LKOWNER_BUFFER */
Packit Service e080da
Packit Service e080da
char *
Packit Service e080da
glusterfs_lkowner_buf_get()
Packit Service e080da
{
Packit Service a90fdc
    return thread_lkowner_buf;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
/* Leaseid buffer */
Packit Service e080da
Packit Service e080da
char *
Packit Service e080da
glusterfs_leaseid_buf_get()
Packit Service e080da
{
Packit Service e080da
    char *buf = NULL;
Packit Service e080da
Packit Service a90fdc
    buf = thread_leaseid;
Packit Service a90fdc
    if (buf == NULL) {
Packit Service a90fdc
        buf = thread_leaseid_buf;
Packit Service a90fdc
        thread_leaseid = buf;
Packit Service e080da
    }
Packit Service a90fdc
Packit Service e080da
    return buf;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
char *
Packit Service e080da
glusterfs_leaseid_exist()
Packit Service e080da
{
Packit Service a90fdc
    return thread_leaseid;
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
static void
Packit Service a90fdc
glusterfs_cleanup(void *ptr)
Packit Service e080da
{
Packit Service a90fdc
    if (thread_syncopctx.groups != NULL) {
Packit Service a90fdc
        GF_FREE(thread_syncopctx.groups);
Packit Service e080da
    }
Packit Service e080da
Packit Service a90fdc
    mem_pool_thread_destructor(NULL);
Packit Service a90fdc
}
Packit Service e080da
Packit Service a90fdc
void
Packit Service a90fdc
gf_thread_needs_cleanup(void)
Packit Service a90fdc
{
Packit Service a90fdc
    /* The value stored in free_key TLS is not really used for anything, but
Packit Service a90fdc
     * pthread implementation doesn't call the TLS destruction function unless
Packit Service a90fdc
     * it's != NULL. This function must be called whenever something is
Packit Service a90fdc
     * allocated for this thread so that glusterfs_cleanup() will be called
Packit Service a90fdc
     * and resources can be released. */
Packit Service a90fdc
    (void)pthread_setspecific(free_key, (void *)1);
Packit Service a90fdc
}
Packit Service e080da
Packit Service a90fdc
static void
Packit Service a90fdc
gf_globals_init_once()
Packit Service a90fdc
{
Packit Service a90fdc
    int ret = 0;
Packit Service e080da
Packit Service a90fdc
    glusterfs_this_init();
Packit Service e080da
Packit Service a90fdc
    /* This is needed only to cleanup the potential allocation of
Packit Service a90fdc
     * thread_syncopctx.groups. */
Packit Service a90fdc
    ret = pthread_key_create(&free_key, glusterfs_cleanup);
Packit Service a90fdc
    if (ret != 0) {
Packit Service a90fdc
        gf_msg("", GF_LOG_ERROR, ret, LG_MSG_PTHREAD_KEY_CREATE_FAILED,
Packit Service a90fdc
               "failed to create the pthread key");
Packit Service e080da
Packit Service e080da
        gf_msg("", GF_LOG_CRITICAL, 0, LG_MSG_GLOBAL_INIT_FAILED,
Packit Service e080da
               "Exiting as global initialization failed");
Packit Service a90fdc
Packit Service e080da
        exit(ret);
Packit Service e080da
    }
Packit Service e080da
}
Packit Service e080da
Packit Service e080da
int
Packit Service e080da
glusterfs_globals_init(glusterfs_ctx_t *ctx)
Packit Service e080da
{
Packit Service e080da
    int ret = 0;
Packit Service e080da
Packit Service e080da
    gf_log_globals_init(ctx, GF_LOG_INFO);
Packit Service e080da
Packit Service e080da
    ret = pthread_once(&globals_inited, gf_globals_init_once);
Packit Service e080da
Packit Service e080da
    if (ret)
Packit Service e080da
        gf_msg("", GF_LOG_CRITICAL, ret, LG_MSG_PTHREAD_FAILED,
Packit Service e080da
               "pthread_once failed");
Packit Service e080da
Packit Service e080da
    return ret;
Packit Service e080da
}