Blame xlators/features/changetimerecorder/src/ctr-helper.c

Packit Service a90fdc
/*
Packit Service a90fdc
   Copyright (c) 2015 Red Hat, Inc. <http://www.redhat.com>
Packit Service a90fdc
   This file is part of GlusterFS.
Packit Service a90fdc
Packit Service a90fdc
   This file is licensed to you under your choice of the GNU Lesser
Packit Service a90fdc
   General Public License, version 3 or any later version (LGPLv3 or
Packit Service a90fdc
   later), or the GNU General Public License, version 2 (GPLv2), in all
Packit Service a90fdc
   cases as published by the Free Software Foundation.
Packit Service a90fdc
*/
Packit Service a90fdc
Packit Service a90fdc
#include "gfdb_sqlite3.h"
Packit Service a90fdc
#include "ctr-helper.h"
Packit Service a90fdc
#include "ctr-messages.h"
Packit Service a90fdc
Packit Service a90fdc
/*******************************************************************************
Packit Service a90fdc
 *
Packit Service a90fdc
 *                      Fill unwind into db record
Packit Service a90fdc
 *
Packit Service a90fdc
 ******************************************************************************/
Packit Service a90fdc
int
Packit Service a90fdc
fill_db_record_for_unwind(xlator_t *this, gf_ctr_local_t *ctr_local,
Packit Service a90fdc
                          gfdb_fop_type_t fop_type, gfdb_fop_path_t fop_path)
Packit Service a90fdc
{
Packit Service a90fdc
    int ret = -1;
Packit Service a90fdc
    gfdb_time_t *ctr_uwtime = NULL;
Packit Service a90fdc
    gf_ctr_private_t *_priv = NULL;
Packit Service a90fdc
Packit Service a90fdc
    GF_ASSERT(this);
Packit Service a90fdc
    _priv = this->private;
Packit Service a90fdc
    GF_ASSERT(_priv);
Packit Service a90fdc
Packit Service a90fdc
    GF_ASSERT(ctr_local);
Packit Service a90fdc
Packit Service a90fdc
    /*If not unwind path error*/
Packit Service a90fdc
    if (!isunwindpath(fop_path)) {
Packit Service a90fdc
        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_WRONG_FOP_PATH,
Packit Service a90fdc
               "Wrong fop_path. Should be unwind");
Packit Service a90fdc
        goto out;
Packit Service a90fdc
    }
Packit Service a90fdc
Packit Service a90fdc
    ctr_uwtime = &CTR_DB_REC(ctr_local).gfdb_unwind_change_time;
Packit Service a90fdc
    CTR_DB_REC(ctr_local).gfdb_fop_path = fop_path;
Packit Service a90fdc
    CTR_DB_REC(ctr_local).gfdb_fop_type = fop_type;
Packit Service a90fdc
Packit Service a90fdc
    ret = gettimeofday(ctr_uwtime, NULL);
Packit Service a90fdc
    if (ret == -1) {
Packit Service a90fdc
        gf_msg(this->name, GF_LOG_ERROR, errno,
Packit Service a90fdc
               CTR_MSG_FILL_UNWIND_TIME_REC_ERROR,
Packit Service a90fdc
               "Error "
Packit Service a90fdc
               "filling unwind time record %s",
Packit Service a90fdc
               strerror(errno));
Packit Service a90fdc
        goto out;
Packit Service a90fdc
    }
Packit Service a90fdc
Packit Service a90fdc
    /* Special case i.e if its a tier rebalance
Packit Service a90fdc
     * + cold tier brick
Packit Service a90fdc
     * + its a create/mknod FOP
Packit Service a90fdc
     * we record unwind time as zero */
Packit Service a90fdc
    if (ctr_local->client_pid == GF_CLIENT_PID_TIER_DEFRAG &&
Packit Service a90fdc
        (!_priv->ctr_hot_brick) && isdentrycreatefop(fop_type)) {
Packit Service a90fdc
        memset(ctr_uwtime, 0, sizeof(*ctr_uwtime));
Packit Service a90fdc
    }
Packit Service a90fdc
    ret = 0;
Packit Service a90fdc
out:
Packit Service a90fdc
    return ret;
Packit Service a90fdc
}
Packit Service a90fdc
Packit Service a90fdc
/*******************************************************************************
Packit Service a90fdc
 *
Packit Service a90fdc
 *                      Fill wind into db record
Packit Service a90fdc
 *
Packit Service a90fdc
 ******************************************************************************/
Packit Service a90fdc
int
Packit Service a90fdc
fill_db_record_for_wind(xlator_t *this, gf_ctr_local_t *ctr_local,
Packit Service a90fdc
                        gf_ctr_inode_context_t *ctr_inode_cx)
Packit Service a90fdc
{
Packit Service a90fdc
    int ret = -1;
Packit Service a90fdc
    gfdb_time_t *ctr_wtime = NULL;
Packit Service a90fdc
    gf_ctr_private_t *_priv = NULL;
Packit Service a90fdc
Packit Service a90fdc
    GF_ASSERT(this);
Packit Service a90fdc
    _priv = this->private;
Packit Service a90fdc
    GF_ASSERT(_priv);
Packit Service a90fdc
    GF_ASSERT(ctr_local);
Packit Service a90fdc
    IS_CTR_INODE_CX_SANE(ctr_inode_cx);
Packit Service a90fdc
Packit Service a90fdc
    /*if not wind path error!*/
Packit Service a90fdc
    if (!iswindpath(ctr_inode_cx->fop_path)) {
Packit Service a90fdc
        gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_WRONG_FOP_PATH,
Packit Service a90fdc
               "Wrong fop_path. Should be wind");
Packit Service a90fdc
        goto out;
Packit Service a90fdc
    }
Packit Service a90fdc
Packit Service a90fdc
    ctr_wtime = &CTR_DB_REC(ctr_local).gfdb_wind_change_time;
Packit Service a90fdc
    CTR_DB_REC(ctr_local).gfdb_fop_path = ctr_inode_cx->fop_path;
Packit Service a90fdc
    CTR_DB_REC(ctr_local).gfdb_fop_type = ctr_inode_cx->fop_type;
Packit Service a90fdc
    CTR_DB_REC(ctr_local).link_consistency = _priv->ctr_link_consistency;
Packit Service a90fdc
Packit Service a90fdc
    ret = gettimeofday(ctr_wtime, NULL);
Packit Service a90fdc
    if (ret) {
Packit Service a90fdc
        gf_msg(this->name, GF_LOG_ERROR, errno,
Packit Service a90fdc
               CTR_MSG_FILL_UNWIND_TIME_REC_ERROR,
Packit Service a90fdc
               "Error filling wind time record %s", strerror(errno));
Packit Service a90fdc
        goto out;
Packit Service a90fdc
    }
Packit Service a90fdc
Packit Service a90fdc
    /* Special case i.e if its a tier rebalance
Packit Service a90fdc
     * + cold tier brick
Packit Service a90fdc
     * + its a create/mknod FOP
Packit Service a90fdc
     * we record wind time as zero */
Packit Service a90fdc
    if (ctr_local->client_pid == GF_CLIENT_PID_TIER_DEFRAG &&
Packit Service a90fdc
        (!_priv->ctr_hot_brick) && isdentrycreatefop(ctr_inode_cx->fop_type)) {
Packit Service a90fdc
        memset(ctr_wtime, 0, sizeof(*ctr_wtime));
Packit Service a90fdc
    }
Packit Service a90fdc
Packit Service a90fdc
    /* Copy gfid into db record */
Packit Service a90fdc
    gf_uuid_copy(CTR_DB_REC(ctr_local).gfid, *(ctr_inode_cx->gfid));
Packit Service a90fdc
Packit Service a90fdc
    /* Copy older gfid if any */
Packit Service a90fdc
    if (ctr_inode_cx->old_gfid &&
Packit Service a90fdc
        (!gf_uuid_is_null(*(ctr_inode_cx->old_gfid)))) {
Packit Service a90fdc
        gf_uuid_copy(CTR_DB_REC(ctr_local).old_gfid, *(ctr_inode_cx->old_gfid));
Packit Service a90fdc
    }
Packit Service a90fdc
Packit Service a90fdc
    /*Hard Links*/
Packit Service a90fdc
    if (isdentryfop(ctr_inode_cx->fop_type)) {
Packit Service a90fdc
        /*new link fop*/
Packit Service a90fdc
        if (NEW_LINK_CX(ctr_inode_cx)) {
Packit Service a90fdc
            gf_uuid_copy(CTR_DB_REC(ctr_local).pargfid,
Packit Service a90fdc
                         *((NEW_LINK_CX(ctr_inode_cx))->pargfid));
Packit Service a90fdc
            strcpy(CTR_DB_REC(ctr_local).file_name,
Packit Service a90fdc
                   NEW_LINK_CX(ctr_inode_cx)->basename);
Packit Service a90fdc
        }
Packit Service a90fdc
        /*rename fop*/
Packit Service a90fdc
        if (OLD_LINK_CX(ctr_inode_cx)) {
Packit Service a90fdc
            gf_uuid_copy(CTR_DB_REC(ctr_local).old_pargfid,
Packit Service a90fdc
                         *((OLD_LINK_CX(ctr_inode_cx))->pargfid));
Packit Service a90fdc
            strcpy(CTR_DB_REC(ctr_local).old_file_name,
Packit Service a90fdc
                   OLD_LINK_CX(ctr_inode_cx)->basename);
Packit Service a90fdc
        }
Packit Service a90fdc
    }
Packit Service a90fdc
Packit Service a90fdc
    ret = 0;
Packit Service a90fdc
out:
Packit Service a90fdc
    /*On error roll back and clean the record*/
Packit Service a90fdc
    if (ret == -1) {
Packit Service a90fdc
        CLEAR_CTR_DB_RECORD(ctr_local);
Packit Service a90fdc
    }
Packit Service a90fdc
    return ret;
Packit Service a90fdc
}
Packit Service a90fdc
Packit Service a90fdc
/******************************************************************************
Packit Service a90fdc
 *
Packit Service a90fdc
 *                      CTR xlator init related functions
Packit Service a90fdc
 *
Packit Service a90fdc
 *
Packit Service a90fdc
 * ****************************************************************************/
Packit Service a90fdc
static int
Packit Service a90fdc
extract_sql_params(xlator_t *this, dict_t *params_dict)
Packit Service a90fdc
{
Packit Service a90fdc
    int ret = -1;
Packit Service a90fdc
    char *db_path = NULL;
Packit Service a90fdc
    char *db_name = NULL;
Packit Service a90fdc
    char *db_full_path = NULL;
Packit Service a90fdc
Packit Service a90fdc
    GF_ASSERT(this);
Packit Service a90fdc
    GF_ASSERT(params_dict);
Packit Service a90fdc
Packit Service a90fdc
    /*Extract the path of the db*/
Packit Service a90fdc
    db_path = NULL;
Packit Service a90fdc
    GET_DB_PARAM_FROM_DICT_DEFAULT(this->name, this->options, "db-path",
Packit Service a90fdc
                                   db_path, "/var/run/gluster/");
Packit Service a90fdc
Packit Service a90fdc
    /*Extract the name of the db*/
Packit Service a90fdc
    db_name = NULL;
Packit Service a90fdc
    GET_DB_PARAM_FROM_DICT_DEFAULT(this->name, this->options, "db-name",
Packit Service a90fdc
                                   db_name, "gf_ctr_db.db");
Packit Service a90fdc
Packit Service a90fdc
    /*Construct full path of the db*/
Packit Service a90fdc
    ret = gf_asprintf(&db_full_path, "%s/%s", db_path, db_name);
Packit Service a90fdc
    if (ret < 0) {
Packit Service a90fdc
        gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, 0,
Packit Service a90fdc
               CTR_MSG_CONSTRUCT_DB_PATH_FAILED,
Packit Service a90fdc
               "Construction of full db path failed!");
Packit Service a90fdc
        goto out;
Packit Service a90fdc
    }
Packit Service a90fdc
Packit Service a90fdc
    /*Setting the SQL DB Path*/
Packit Service a90fdc
    SET_DB_PARAM_TO_DICT(this->name, params_dict, GFDB_SQL_PARAM_DBPATH,
Packit Service a90fdc
                         db_full_path, ret, out);
Packit Service a90fdc
Packit Service a90fdc
    /*Extract rest of the sql params*/
Packit Service a90fdc
    ret = gfdb_set_sql_params(this->name, this->options, params_dict);
Packit Service a90fdc
    if (ret) {
Packit Service a90fdc
        gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, 0,
Packit Service a90fdc
               CTR_MSG_SET_VALUE_TO_SQL_PARAM_FAILED,
Packit Service a90fdc
               "Failed setting values to sql param dict!");
Packit Service a90fdc
    }
Packit Service a90fdc
Packit Service a90fdc
    ret = 0;
Packit Service a90fdc
Packit Service a90fdc
out:
Packit Service a90fdc
    if (ret)
Packit Service a90fdc
        GF_FREE(db_full_path);
Packit Service a90fdc
    return ret;
Packit Service a90fdc
}
Packit Service a90fdc
Packit Service a90fdc
int
Packit Service a90fdc
extract_db_params(xlator_t *this, dict_t *params_dict, gfdb_db_type_t db_type)
Packit Service a90fdc
{
Packit Service a90fdc
    int ret = -1;
Packit Service a90fdc
Packit Service a90fdc
    GF_ASSERT(this);
Packit Service a90fdc
    GF_ASSERT(params_dict);
Packit Service a90fdc
Packit Service a90fdc
    switch (db_type) {
Packit Service a90fdc
        case GFDB_SQLITE3:
Packit Service a90fdc
            ret = extract_sql_params(this, params_dict);
Packit Service a90fdc
            if (ret)
Packit Service a90fdc
                goto out;
Packit Service a90fdc
            break;
Packit Service a90fdc
        case GFDB_ROCKS_DB:
Packit Service a90fdc
        case GFDB_HYPERDEX:
Packit Service a90fdc
        case GFDB_HASH_FILE_STORE:
Packit Service a90fdc
        case GFDB_INVALID_DB:
Packit Service a90fdc
        case GFDB_DB_END:
Packit Service a90fdc
            goto out;
Packit Service a90fdc
    }
Packit Service a90fdc
    ret = 0;
Packit Service a90fdc
out:
Packit Service a90fdc
    return ret;
Packit Service a90fdc
}
Packit Service a90fdc
Packit Service a90fdc
int
Packit Service a90fdc
extract_ctr_options(xlator_t *this, gf_ctr_private_t *_priv)
Packit Service a90fdc
{
Packit Service a90fdc
    int ret = -1;
Packit Service a90fdc
    char *_val_str = NULL;
Packit Service a90fdc
Packit Service a90fdc
    GF_ASSERT(this);
Packit Service a90fdc
    GF_ASSERT(_priv);
Packit Service a90fdc
Packit Service a90fdc
    /*Checking if the CTR Translator is enabled. By default its disabled*/
Packit Service a90fdc
    _priv->enabled = _gf_false;
Packit Service a90fdc
    GF_OPTION_INIT("ctr-enabled", _priv->enabled, bool, out);
Packit Service a90fdc
    if (!_priv->enabled) {
Packit Service a90fdc
        gf_msg(GFDB_DATA_STORE, GF_LOG_INFO, 0, CTR_MSG_XLATOR_DISABLED,
Packit Service a90fdc
               "CTR Xlator is disabled.");
Packit Service a90fdc
        ret = 0;
Packit Service a90fdc
        goto out;
Packit Service a90fdc
    }
Packit Service a90fdc
Packit Service a90fdc
    /*Extract db type*/
Packit Service a90fdc
    GF_OPTION_INIT("db-type", _val_str, str, out);
Packit Service a90fdc
    _priv->gfdb_db_type = gf_string2gfdbdbtype(_val_str);
Packit Service a90fdc
Packit Service a90fdc
    /*Extract flag for record on wind*/
Packit Service a90fdc
    GF_OPTION_INIT("record-entry", _priv->ctr_record_wind, bool, out);
Packit Service a90fdc
Packit Service a90fdc
    /*Extract flag for record on unwind*/
Packit Service a90fdc
    GF_OPTION_INIT("record-exit", _priv->ctr_record_unwind, bool, out);
Packit Service a90fdc
Packit Service a90fdc
    /*Extract flag for record on counters*/
Packit Service a90fdc
    GF_OPTION_INIT("record-counters", _priv->ctr_record_counter, bool, out);
Packit Service a90fdc
Packit Service a90fdc
    /* Extract flag for record metadata heat */
Packit Service a90fdc
    GF_OPTION_INIT("ctr-record-metadata-heat", _priv->ctr_record_metadata_heat,
Packit Service a90fdc
                   bool, out);
Packit Service a90fdc
Packit Service a90fdc
    /*Extract flag for link consistency*/
Packit Service a90fdc
    GF_OPTION_INIT("ctr_link_consistency", _priv->ctr_link_consistency, bool,
Packit Service a90fdc
                   out);
Packit Service a90fdc
Packit Service a90fdc
    /*Extract ctr_lookupheal_inode_timeout */
Packit Service a90fdc
    GF_OPTION_INIT("ctr_lookupheal_inode_timeout",
Packit Service a90fdc
                   _priv->ctr_lookupheal_inode_timeout, uint64, out);
Packit Service a90fdc
Packit Service a90fdc
    /*Extract ctr_lookupheal_link_timeout*/
Packit Service a90fdc
    GF_OPTION_INIT("ctr_lookupheal_link_timeout",
Packit Service a90fdc
                   _priv->ctr_lookupheal_link_timeout, uint64, out);
Packit Service a90fdc
Packit Service a90fdc
    /*Extract flag for hot tier brick*/
Packit Service a90fdc
    GF_OPTION_INIT("hot-brick", _priv->ctr_hot_brick, bool, out);
Packit Service a90fdc
Packit Service a90fdc
    /*Extract flag for sync mode*/
Packit Service a90fdc
    GF_OPTION_INIT("db-sync", _val_str, str, out);
Packit Service a90fdc
    _priv->gfdb_sync_type = gf_string2gfdbdbsync(_val_str);
Packit Service a90fdc
Packit Service a90fdc
    ret = 0;
Packit Service a90fdc
Packit Service a90fdc
out:
Packit Service a90fdc
    return ret;
Packit Service a90fdc
}