Beispiel #1
0
/*
 * Find unchanged files from a specified time from the DB
 * Input:
 *      query_callback  :       query callback fuction to handle
 *                              result records from the query
 *      for_time        :        Time from where the file/s are not changed
 * */
int
gf_sqlite3_find_unchanged_for_time (void *db_conn,
                                        gf_query_callback_t query_callback,
                                        void *query_cbk_args,
                                        gfdb_time_t *for_time)
{
        int ret                                 =       -1;
        char *query_str                         =       NULL;
        gf_sql_connection_t *sql_conn           =       db_conn;
        sqlite3_stmt *prep_stmt                 =       NULL;
        uint64_t  for_time_usec                 =       0;
        char *base_query_str                    =       NULL;

        CHECK_SQL_CONN (sql_conn, out);
        GF_VALIDATE_OR_GOTO(GFDB_STR_SQLITE3, query_callback, out);

        ret = gf_get_basic_query_stmt (&base_query_str);
        if (ret <= 0) {
                goto out;
        }

        ret = gf_asprintf (&query_str, "%s AND "
                /*First condition: For writes*/
                "( ((" GF_COL_TB_WSEC " * " TOSTRING(GFDB_MICROSEC) " + "
                GF_COL_TB_WMSEC ") <= ? )"
                " AND "
                /*Second condition: For reads*/
                "((" GF_COL_TB_RWSEC " * " TOSTRING(GFDB_MICROSEC) " + "
                GF_COL_TB_RWMSEC ") <= ?) )", base_query_str);

        if (ret < 0) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_QUERY_FAILED,
                        "Failed to create query statement");
                query_str = NULL;
                goto out;
        }

        for_time_usec = gfdb_time_2_usec (for_time);

        ret = sqlite3_prepare (sql_conn->sqlite3_db_conn, query_str, -1,
                               &prep_stmt, 0);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_PREPARE_FAILED, "Failed to prepare statment %s :"
                        " %s", query_str,
                        sqlite3_errmsg (sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

        /*Bind write wind time*/
        ret = sqlite3_bind_int64 (prep_stmt, 1, for_time_usec);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_BINDING_FAILED, "Failed to bind for_time_usec "
                        "%"PRIu64" : %s", for_time_usec,
                        sqlite3_errmsg (sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

        /*Bind read wind time*/
        ret = sqlite3_bind_int64 (prep_stmt, 2, for_time_usec);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_BINDING_FAILED, "Failed to bind for_time_usec "
                        "%"PRIu64" : %s", for_time_usec,
                        sqlite3_errmsg (sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

        /*Execute the query*/
        ret = gf_sql_query_function (prep_stmt, query_callback, query_cbk_args);
        if (ret) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_QUERY_FAILED,
                        "Failed Query %s", query_str);
                goto out;
        }

        ret = 0;
out:
        sqlite3_finalize (prep_stmt);
        GF_FREE (base_query_str);
        GF_FREE (query_str);
        return ret;
}
/******************************************************************************
 *
 *                      Find/Query helper functions
 *
 * ****************************************************************************/
int
gf_sql_query_function (sqlite3_stmt              *prep_stmt,
                      gf_query_callback_t       query_callback,
                      void                      *_query_cbk_args)
{
        int ret = -1;
        gfdb_query_record_t *gfdb_query_record = NULL;
        char *text_column = NULL;
        sqlite3 *db_conn = NULL;

        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, prep_stmt, out);
        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, query_callback, out);

        db_conn = sqlite3_db_handle(prep_stmt);

        gfdb_query_record = gfdb_query_record_init ();
        if (!gfdb_query_record) {
                        gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                                LG_MSG_CREATE_FAILED, "Failed to create "
                                "gfdb_query_record");
                                goto out;
        }

        /*Loop to access queried rows*/
        while ((ret = sqlite3_step (prep_stmt)) == SQLITE_ROW) {

                /*Clear the query record*/
                memset (gfdb_query_record, 0, sizeof(*gfdb_query_record));

                if (sqlite3_column_count(prep_stmt) > 0) {

                        /*Retriving GFID - column index is 0*/
                        text_column = (char *)sqlite3_column_text
                                                        (prep_stmt, 0);
                        if (!text_column) {
                                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                                        LG_MSG_GET_ID_FAILED, "Failed "
                                        "retriving GF_ID");
                                goto out;
                        }
                        ret = gf_uuid_parse (text_column, gfdb_query_record->gfid);
                        if (ret) {
                                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                                        LG_MSG_PARSE_FAILED, "Failed parsing "
                                        "GF_ID");
                                goto out;
                        }

                        /*Retrive Link Buffer - column index 1*/
                        text_column = (char *)sqlite3_column_text
                                                (prep_stmt, 1);
                        /* Get link string. Do shallow copy here
                         * query_callback function should do a
                         * deep copy and then do operations on this field*/
                        gfdb_query_record->_link_info_str = text_column;
                        gfdb_query_record->link_info_size = strlen
                                                                (text_column);

                        /* Call the call back function provided*/
                        ret = query_callback (gfdb_query_record,
                                                        _query_cbk_args);
                        if (ret) {
                                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                                        LG_MSG_QUERY_CALL_BACK_FAILED,
                                        "Query Call back failed!");
                                goto out;
                        }

                }

        }

        if (ret != SQLITE_DONE) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_GET_RECORD_FAILED, "Failed retriving records "
                        "from db : %s", sqlite3_errmsg (db_conn));
                ret = -1;
                goto out;
        }

        ret = 0;
out:
        gfdb_query_record_fini (&gfdb_query_record);
        return ret;
}
static inline int
gf_sql_update_link_flags (gf_sql_connection_t  *sql_conn,
                   char                 *gfid,
                   char                 *pargfid,
                   char                 *basename,
                   int                  update_flag,
                   gf_boolean_t         is_update_or_delete)
{
        int ret = -1;
        sqlite3_stmt *update_stmt = NULL;
        char *update_column = NULL;
        char update_str[1024] = "";


        CHECK_SQL_CONN (sql_conn, out);
        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, gfid, out);
        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, pargfid, out);
        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, basename, out);

        update_column = (is_update_or_delete) ? "LINK_UPDATE" : "W_DEL_FLAG";

        sprintf (update_str, "UPDATE "
                            GF_FILE_LINK_TABLE
                            " SET %s = ?"
                            " WHERE GF_ID = ? AND GF_PID = ? AND FNAME = ?;",
                            update_column);

        /*Prepare statement*/
        ret = sqlite3_prepare (sql_conn->sqlite3_db_conn, update_str, -1,
                                &update_stmt, 0);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_PREPARE_FAILED, "Failed preparing update "
                        "statment %s : %s", update_str,
                        sqlite3_errmsg (sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }


        /*Bind link_update*/
        ret = sqlite3_bind_int (update_stmt, 1, update_flag);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_BINDING_FAILED, "Failed binding update_flag %d "
                        ": %s", update_flag,
                        sqlite3_errmsg (sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

        /*Bind gfid*/
        ret = sqlite3_bind_text (update_stmt, 2, gfid, -1, NULL);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_BINDING_FAILED, "Failed binding gfid %s : %s",
                        gfid, sqlite3_errmsg (sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

        /*Bind pargfid*/
        ret = sqlite3_bind_text (update_stmt, 3, pargfid, -1, NULL);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_BINDING_FAILED, "Failed binding parent gfid %s "
                        ": %s", pargfid,
                        sqlite3_errmsg (sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

        /*Bind basename*/
        ret = sqlite3_bind_text (update_stmt, 4, basename, -1, NULL);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_BINDING_FAILED, "Failed binding basename %s : "
                        "%s", basename,
                        sqlite3_errmsg (sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }


        /*Execute the prepare statement*/
        if (sqlite3_step(update_stmt) != SQLITE_DONE) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_EXEC_FAILED,
                        "Failed executing the prepared stmt %s : %s",
                        update_str,
                        sqlite3_errmsg (sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

        ret = 0;
out:
        /*Free prepared statement*/
        sqlite3_finalize (update_stmt);
        return ret;
}
Beispiel #4
0
/**
 * cache_nfs_fh -- Places the nfs file handle in the underlying dict as we are
 *                 using as our cache. The key is "exportid:gfid:host_addr", the
 *                 value is an entry struct containing the export item that
 *                 was authorized for the operation and the file handle that was
 *                 authorized.
 *
 * @cache: The cache to place fh's in
 * @fh   : The fh to cache
 * @host_addr: The address of the host
 * @export_item: The export item that was authorized
 *
 */
int
cache_nfs_fh (struct auth_cache *cache, struct nfs3_fh *fh,
              const char *host_addr, struct export_item *export_item)
{
        int                      ret        = -EINVAL;
        char                    *hashkey    = NULL;
        data_t                  *entry_data = NULL;
        time_t                   timestamp  = 0;
        gf_boolean_t             can_write  = _gf_false;
        struct auth_cache_entry *entry      = NULL;

        GF_VALIDATE_OR_GOTO (GF_NFS, host_addr, out);
        GF_VALIDATE_OR_GOTO (GF_NFS, cache, out);
        GF_VALIDATE_OR_GOTO (GF_NFS, fh, out);

        /* If a dict has not been allocated already, allocate it. */
        if (!cache->cache_dict) {
                cache->cache_dict = dict_new ();
                if (!cache->cache_dict) {
                        ret = -ENOMEM;
                        goto out;
                }
        }

        /* If we could already find it in the cache, just return */
        ret = auth_cache_lookup (cache, fh, host_addr, &timestamp, &can_write);
        if (ret == 0) {
                gf_msg_trace (GF_NFS, 0, "found cached auth/fh for host "
                              "%s", host_addr);
                goto out;
        }

        make_hashkey (hashkey, fh, host_addr);

        entry = auth_cache_entry_init ();
        if (!entry) {
                ret = -ENOMEM;
                goto out;
        }

        entry->timestamp = time (NULL);
        entry->item = export_item;

        /* The cache entry will simply be the time that the entry
         * was cached.
         */
        entry_data = bin_to_data (entry, sizeof (*entry));
        if (!entry_data) {
                GF_FREE (entry);
                goto out;
        }

        ret = dict_set (cache->cache_dict, hashkey, entry_data);
        if (ret == -1) {
                GF_FREE (entry);
                goto out;
        }
        gf_msg_trace (GF_NFS, 0, "Caching file-handle (%s)", host_addr);
        ret = 0;
out:
        return ret;
}
Beispiel #5
0
int
xlator_dynload (xlator_t *xl)
{
        int                ret = -1;
        char              *name = NULL;
        void              *handle = NULL;
        volume_opt_list_t *vol_opt = NULL;
        class_methods_t   *vtbl = NULL;

        GF_VALIDATE_OR_GOTO ("xlator", xl, out);

        INIT_LIST_HEAD (&xl->volume_options);

        ret = gf_asprintf (&name, "%s/%s.so", XLATORDIR, xl->type);
        if (-1 == ret) {
                gf_log ("xlator", GF_LOG_ERROR, "asprintf failed");
                goto out;
        }

        ret = -1;

        gf_log ("xlator", GF_LOG_TRACE, "attempt to load file %s", name);

        handle = dlopen (name, RTLD_NOW|RTLD_GLOBAL);
        if (!handle) {
                gf_log ("xlator", GF_LOG_WARNING, "%s", dlerror ());
                goto out;
        }
        xl->dlhandle = handle;

        if (!(xl->fops = dlsym (handle, "fops"))) {
                gf_log ("xlator", GF_LOG_WARNING, "dlsym(fops) on %s",
                        dlerror ());
                goto out;
        }

        if (!(xl->cbks = dlsym (handle, "cbks"))) {
                gf_log ("xlator", GF_LOG_WARNING, "dlsym(cbks) on %s",
                        dlerror ());
                goto out;
        }

        /*
         * If class_methods exists, its contents override any definitions of
         * init or fini for that translator.  Otherwise, we fall back to the
         * older method of looking for init and fini directly.
         */
        vtbl = dlsym(handle,"class_methods");
        if (vtbl) {
                xl->init        = vtbl->init;
                xl->fini        = vtbl->fini;
                xl->reconfigure = vtbl->reconfigure;
                xl->notify      = vtbl->notify;
        }
        else {
                if (!(*VOID(&xl->init) = dlsym (handle, "init"))) {
                        gf_log ("xlator", GF_LOG_WARNING, "dlsym(init) on %s",
                                dlerror ());
                        goto out;
                }

                if (!(*VOID(&(xl->fini)) = dlsym (handle, "fini"))) {
                        gf_log ("xlator", GF_LOG_WARNING, "dlsym(fini) on %s",
                                dlerror ());
                        goto out;
                }
                if (!(*VOID(&(xl->reconfigure)) = dlsym (handle,
                                                         "reconfigure"))) {
                        gf_log ("xlator", GF_LOG_TRACE,
                                "dlsym(reconfigure) on %s -- neglecting",
                                dlerror());
                }
                if (!(*VOID(&(xl->notify)) = dlsym (handle, "notify"))) {
                        gf_log ("xlator", GF_LOG_TRACE,
                                "dlsym(notify) on %s -- neglecting",
                                dlerror ());
                }

        }

        if (!(xl->dumpops = dlsym (handle, "dumpops"))) {
                gf_log ("xlator", GF_LOG_TRACE,
                        "dlsym(dumpops) on %s -- neglecting", dlerror ());
        }

        if (!(*VOID(&(xl->mem_acct_init)) = dlsym (handle, "mem_acct_init"))) {
                gf_log (xl->name, GF_LOG_TRACE,
                        "dlsym(mem_acct_init) on %s -- neglecting",
                        dlerror ());
        }

        vol_opt = GF_CALLOC (1, sizeof (volume_opt_list_t),
                         gf_common_mt_volume_opt_list_t);

        if (!vol_opt) {
                goto out;
        }

        if (!(vol_opt->given_opt = dlsym (handle, "options"))) {
                dlerror ();
                gf_log (xl->name, GF_LOG_TRACE,
                        "Strict option validation not enforced -- neglecting");
        }
        INIT_LIST_HEAD (&vol_opt->list);
        list_add_tail (&vol_opt->list, &xl->volume_options);

        fill_defaults (xl);

        ret = 0;

out:
        GF_FREE (name);
        return ret;
}
Beispiel #6
0
/**
 * exp_file_parse -- Parse an exports file into a structure
 *                   that can be looked up through simple
 *                   function calls.
 *
 * @filepath: Path to the exports file
 * @ms      : Current mount state (useful to match with gluster vol files)
 *
 * @return  : success: 0
 *            failure: -1 on parsing failure, -EINVAL on bad arguments,
 *                     -ENOMEM on allocation failures.
 *
 * The caller is responsible for freeing memory allocated by this function.
 * The caller should free this memory using the exp_file_deinit () function.
 * Calling GF_FREE ( ) on the pointer will NOT free all the allocated memory.
 *
 * Externally usable.
 */
int
exp_file_parse(const char *filepath, struct exports_file **expfile,
               struct mount3_state *ms)
{
    FILE *fp = NULL;
    struct exports_file *file = NULL;
    size_t len = 0;
    int ret = -EINVAL;
    unsigned long line_number = 0;
    char *line = NULL;
    struct export_dir *expdir = NULL;

    /* Sets whether we we should parse the entire file or just that which
     * is present in the mount state */
    gf_boolean_t parse_complete_file = _gf_false;

    GF_VALIDATE_OR_GOTO(GF_EXP, expfile, parse_done);

    if (!ms) {
        /* If mount state is null that means that we
         * should go through and parse the whole file
         * since we don't have anything to compare against.
         */
        parse_complete_file = _gf_true;
    }

    fp = fopen(filepath, "r");
    if (!fp) {
        ret = -errno;
        goto parse_done;
    }

    ret = _exp_init_parsers();
    if (ret < 0)
        goto parse_done;

    /* Process the file line by line, with each line being parsed into
     * an struct export_dir struct. If 'parse_complete_file' is set to TRUE
     * then
     */
    while (getline(&line, &len, fp) != -1) {
        line_number++;      /* Keeping track of line number allows us to
                             * to log which line numbers were wrong
                             */
        strtok(line, "\n"); /* removes the newline character from
                             * the line
                             */

        /* Parse the line from the file into an struct export_dir
         * structure. The process is as follows:
         * Given a line like :
         * "/vol @test(sec=sys,rw,anonuid=0) 10.35.11.31(sec=sys,rw)"
         *
         * This function will allocate an export dir and set its name
         * to '/vol', using the function _exp_line_dir_parse ().
         *
         * Then it will extract the netgroups from the line, in this
         * case it would be '@test(sec=sys,rw,anonuid=0)', and set the
         * item structure's name to '@test'.
         * It will also extract the options from that string and parse
         * them into an struct export_options which will be pointed
         * to by the item structure. This will be put into a dict
         * which will be pointed to by the export directory structure.
         *
         * The same process happens above for the host string
         * '10.35.11.32(sec=sys,rw)'
         */
        ret = _exp_line_parse(line, &expdir, parse_complete_file, ms);
        if (ret == -ENOMEM) {
            /* If we get memory allocation errors, we really should
             * not continue parsing, so just free the allocated
             * memory and exit.
             */
            goto free_and_done;
        }

        if (ret < 0) {
            gf_msg(GF_EXP, GF_LOG_ERROR, -ret, NFS_MSG_PARSE_FAIL,
                   "Failed to parse line #%lu", line_number);
            continue; /* Skip entering this line and continue */
        }

        if (ret == GF_EXP_PARSE_LINE_IGNORING) {
            /* This just means the line was empty or started with a
             * '#' or a ' ' and we are ignoring it.
             */
            gf_msg_debug(GF_EXP, 0,
                         "Ignoring line #%lu because it started "
                         "with a %c",
                         line_number, *line);
            continue;
        }

        if (!file) {
            file = _exports_file_init();
            GF_CHECK_ALLOC_AND_LOG(GF_EXP, file, ret,
                                   "Allocation error while "
                                   "allocating file struct",
                                   parse_done);

            file->filename = gf_strdup(filepath);
            GF_CHECK_ALLOC_AND_LOG(GF_EXP, file, ret,
                                   "Allocation error while "
                                   "duping filepath",
                                   free_and_done);
        }

        /* If the parsing is successful store the export directory
         * in the file structure.
         */
        _exp_file_insert(file, expdir);
    }

    /* line got allocated through getline(), don't use GF_FREE() for it */
    free(line);

    *expfile = file;
    goto parse_done;

free_and_done:
    exp_file_deinit(file);
    _export_dir_deinit(expdir);

parse_done:
    if (fp)
        fclose(fp);
    _exp_deinit_parsers();
    return ret;
}
Beispiel #7
0
/**
 * __exp_line_ng_parse -- Extract the netgroups in the line
 *                        and call helper functions to parse
 *                        the string.
 *
 * The call chain goes like this:
 *
 * 1) __exp_line_ng_parse ("/test  @test(sec=sys,rw,anonuid=0)")
 * 2) __exp_line_ng_str_parse ("@test(sec=sys,rw,anonuid=0)");
 * 3) __exp_line_opt_parse("(sec=sys,rw,anonuid=0)");
 *
 *
 * @line    : The line to parse
 * @ng_dict : Double pointer to the dict we want to
 *            insert netgroups into.
 *
 * Allocates the dict, extracts netgroup strings from the line,
 * parses them into a struct export_item structure and inserts
 * them in the dict.
 *
 * @return: success: GF_EXP_PARSE_SUCCESS
 *          failure: GF_EXP_PARSE_ITEM_FAILURE on parse failure,
 *                   GF_EXP_PARSE_ITEM_NOT_FOUND if the netgroup was not found
 *                   -EINVAL on bad args, -ENOMEM on allocation errors.
 *
 * Not for external use.
 */
static int
__exp_line_ng_parse(const char *line, dict_t **ng_dict)
{
    dict_t *netgroups = NULL;
    char *strmatch = NULL;
    int ret = -EINVAL;
    struct export_item *exp_ng = NULL;
    data_t *ngdata = NULL;

    GF_VALIDATE_OR_GOTO(GF_EXP, line, out);
    GF_VALIDATE_OR_GOTO(GF_EXP, ng_dict, out);

    *ng_dict = NULL; /* Will be set if parse is successful */

    /* Initialize a parser with the line to parse
     * and the regex used to parse it.
     */
    ret = parser_set_string(netgroup_parser, line);
    if (ret < 0) {
        goto out;
    }

    gf_msg_trace(GF_EXP, 0, "parsing line: %s", line);

    while ((strmatch = parser_get_next_match(netgroup_parser))) {
        if (!netgroups) {
            /* Allocate a new dict to store the netgroups. */
            netgroups = dict_new();
            if (!netgroups) {
                ret = -ENOMEM;
                goto free_and_out;
            }
        }

        gf_msg_trace(GF_EXP, 0, "parsing netgroup: %s", strmatch);

        ret = __exp_line_ng_host_str_parse(strmatch, &exp_ng);

        if (ret != 0) {
            /* Parsing or other critical errors.
             * caller will handle return value.
             */
            _exp_dict_destroy(netgroups);
            goto free_and_out;
        }

        ngdata = bin_to_data(exp_ng, sizeof(*exp_ng));
        dict_set(netgroups, exp_ng->name, ngdata);

        /* Free this matched string and continue parsing. */
        GF_FREE(strmatch);
    }

    /* If the netgroups dict was not allocated, then we know that
     * no matches were found.
     */
    if (!netgroups) {
        ret = GF_EXP_PARSE_ITEM_NOT_FOUND;
        parser_unset_string(netgroup_parser);
        goto out;
    }

    ret = GF_EXP_PARSE_SUCCESS;
    *ng_dict = netgroups;

free_and_out:
    parser_unset_string(netgroup_parser);
    GF_FREE(strmatch);
out:
    return ret;
}
Beispiel #8
0
int
event_register_epoll (struct event_pool *event_pool, int fd,
                      event_handler_t handler,
                      void *data, int poll_in, int poll_out)
{
        int                 idx = -1;
        int                 ret = -1;
        int             destroy = 0;
        struct epoll_event  epoll_event = {0, };
        struct event_data  *ev_data = (void *)&epoll_event.data;
	struct event_slot_epoll *slot = NULL;


        GF_VALIDATE_OR_GOTO ("event", event_pool, out);

        /* TODO: Even with the below check, there is a possiblity of race,
         * What if the destroy mode is set after the check is done.
         * Not sure of the best way to prevent this race, ref counting
         * is one possibility.
         * There is no harm in registering and unregistering the fd
         * even after destroy mode is set, just that such fds will remain
         * open until unregister is called, also the events on that fd will be
         * notified, until one of the poller thread is alive.
         */
        pthread_mutex_lock (&event_pool->mutex);
        {
                destroy = event_pool->destroy;
        }
        pthread_mutex_unlock (&event_pool->mutex);

        if (destroy == 1)
               goto out;

	idx = event_slot_alloc (event_pool, fd);
	if (idx == -1) {
		gf_log ("epoll", GF_LOG_ERROR,
			"could not find slot for fd=%d", fd);
		return -1;
	}

	slot = event_slot_get (event_pool, idx);

	assert (slot->fd == fd);

	LOCK (&slot->lock);
	{
		/* make epoll 'singleshot', which
		   means we need to re-add the fd with
		   epoll_ctl(EPOLL_CTL_MOD) after delivery of every
		   single event. This assures us that while a poller
		   thread has picked up and is processing an event,
		   another poller will not try to pick this at the same
		   time as well.
		*/

		slot->events = EPOLLPRI | EPOLLONESHOT;
		slot->handler = handler;
		slot->data = data;

		__slot_update_events (slot, poll_in, poll_out);

		epoll_event.events = slot->events;
		ev_data->idx = idx;
		ev_data->gen = slot->gen;

		ret = epoll_ctl (event_pool->fd, EPOLL_CTL_ADD, fd,
				 &epoll_event);
		/* check ret after UNLOCK() to avoid deadlock in
		   event_slot_unref()
		*/
	}
	UNLOCK (&slot->lock);

	if (ret == -1) {
		gf_log ("epoll", GF_LOG_ERROR,
			"failed to add fd(=%d) to epoll fd(=%d) (%s)",
			fd, event_pool->fd, strerror (errno));

		event_slot_unref (event_pool, slot, idx);
		idx = -1;
	}

	/* keep slot->ref (do not event_slot_unref) if successful */
out:
        return idx;
}
Beispiel #9
0
static void *
event_dispatch_epoll_worker (void *data)
{
        struct epoll_event  event;
        int                 ret = -1;
        struct event_thread_data *ev_data = data;
	struct event_pool  *event_pool;
        int                 myindex = -1;
        int                 timetodie = 0;

        GF_VALIDATE_OR_GOTO ("event", ev_data, out);

        event_pool = ev_data->event_pool;
        myindex = ev_data->event_index;

        GF_VALIDATE_OR_GOTO ("event", event_pool, out);

        gf_log ("epoll", GF_LOG_INFO, "Started thread with index %d", myindex);

        pthread_mutex_lock (&event_pool->mutex);
        {
                event_pool->activethreadcount++;
        }
        pthread_mutex_unlock (&event_pool->mutex);

	for (;;) {
                if (event_pool->eventthreadcount < myindex) {
                        /* ...time to die, thread count was decreased below
                         * this threads index */
                        /* Start with extra safety at this point, reducing
                         * lock conention in normal case when threads are not
                         * reconfigured always */
                        pthread_mutex_lock (&event_pool->mutex);
                        {
                                if (event_pool->eventthreadcount <
                                    myindex) {
                                        /* if found true in critical section,
                                         * die */
                                        event_pool->pollers[myindex - 1] = 0;
                                        event_pool->activethreadcount--;
                                        timetodie = 1;
                                        pthread_cond_broadcast (&event_pool->cond);
                                }
                        }
                        pthread_mutex_unlock (&event_pool->mutex);
                        if (timetodie) {
                                gf_log ("epoll", GF_LOG_INFO,
                                        "Exited thread with index %d", myindex);
                                goto out;
                        }
                }

                ret = epoll_wait (event_pool->fd, &event, 1, -1);

                if (ret == 0)
                        /* timeout */
                        continue;

                if (ret == -1 && errno == EINTR)
                        /* sys call */
                        continue;

		ret = event_dispatch_epoll_handler (event_pool, &event);
        }
out:
        if (ev_data)
                GF_FREE (ev_data);
        return NULL;
}
/*
 * Find unchanged files from a specified time, w.r.t to frequency, from the DB
 * Input:
 *      query_callback  :       query callback fuction to handle
 *                              result records from the query
 *      for_time       :        Time from where the file/s are not changed
 *      freq_write_cnt  :       Frequency thresold for write
 *      freq_read_cnt   :       Frequency thresold for read
 *      clear_counters  :       Clear counters (r/w) for all inodes in DB
 * */
int
gf_sqlite3_find_unchanged_for_time_freq (void *db_conn,
                                        gf_query_callback_t query_callback,
                                        void *query_cbk_args,
                                        gfdb_time_t *for_time,
                                        int freq_write_cnt,
                                        int freq_read_cnt,
                                        gf_boolean_t clear_counters)
{
        int ret                                 =       -1;
        char *query_str                         =       NULL;
        gf_sql_connection_t *sql_conn           =       db_conn;
        sqlite3_stmt *prep_stmt                 =       NULL;
        uint64_t  for_time_usec                 =       0;

        CHECK_SQL_CONN (sql_conn, out);
        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, query_callback, out);

        query_str = "select GF_FILE_TB.GF_ID,"
                " (select group_concat( GF_PID || ',' || FNAME || ','"
                " || FPATH || ',' || W_DEL_FLAG ||',' || LINK_UPDATE , '::')"
                " from GF_FLINK_TB where GF_FILE_TB.GF_ID = GF_FLINK_TB.GF_ID)"
                "  from GF_FILE_TB where "
                /*First condition: For Writes
                 * Files that have write wind time smaller than for_time
                 * OR
                 * File that have write wind time greater than for_time,
                 * but write_frequency less than freq_write_cnt*/
                "( ((" GF_COL_TB_WSEC " * " TOSTRING(GFDB_MICROSEC) " + "
                GF_COL_TB_WMSEC ") < ? )"
                " OR "
                "( (" GF_COL_TB_WFC " < ? ) AND"
                "((" GF_COL_TB_WSEC " * " TOSTRING(GFDB_MICROSEC) " + "
                GF_COL_TB_WMSEC ") >= ? ) ) )"
                " AND "
                /*Second condition: For Reads
                 * Files that have read wind time smaller than for_time
                 * OR
                 * File that have read wind time greater than for_time,
                 * but write_frequency less than freq_write_cnt*/
                "( ((" GF_COL_TB_RWSEC " * " TOSTRING(GFDB_MICROSEC) " + "
                GF_COL_TB_RWMSEC ") < ? )"
                " OR "
                "( (" GF_COL_TB_RFC " < ? ) AND"
                "((" GF_COL_TB_RWSEC " * " TOSTRING(GFDB_MICROSEC) " + "
                GF_COL_TB_RWMSEC ") >= ? ) ) )";


        for_time_usec = gfdb_time_2_usec(for_time);

        ret = sqlite3_prepare (sql_conn->sqlite3_db_conn, query_str, -1,
                                &prep_stmt, 0);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_PREPARE_FAILED, "Failed preparing delete "
                        "statment %s : %s", query_str,
                        sqlite3_errmsg(sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

        /*Bind write wind time*/
        ret = sqlite3_bind_int64 (prep_stmt, 1, for_time_usec);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_BINDING_FAILED, "Failed binding for_time_usec "
                        "%"PRIu64" : %s", for_time_usec,
                        sqlite3_errmsg(sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

        /*Bind write frequency thresold*/
        ret = sqlite3_bind_int (prep_stmt, 2, freq_write_cnt);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_BINDING_FAILED, "Failed binding freq_write_cnt"
                        " %d : %s", freq_write_cnt,
                        sqlite3_errmsg(sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

        /*Bind write wind time*/
        ret = sqlite3_bind_int64 (prep_stmt, 3, for_time_usec);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_BINDING_FAILED, "Failed binding for_time_usec "
                        "%"PRIu64" : %s", for_time_usec,
                        sqlite3_errmsg(sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }



        /*Bind read wind time*/
        ret = sqlite3_bind_int64 (prep_stmt, 4, for_time_usec);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_BINDING_FAILED, "Failed binding for_time_usec "
                        "%"PRIu64" : %s", for_time_usec,
                        sqlite3_errmsg(sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

        /*Bind read frequency thresold*/
        ret = sqlite3_bind_int (prep_stmt, 5, freq_read_cnt);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_BINDING_FAILED, "Failed binding freq_read_cnt "
                        "%d : %s", freq_read_cnt,
                        sqlite3_errmsg(sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

        /*Bind read wind time*/
        ret = sqlite3_bind_int64 (prep_stmt, 6, for_time_usec);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_BINDING_FAILED, "Failed binding for_time_usec "
                        "%"PRIu64" : %s", for_time_usec,
                        sqlite3_errmsg(sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

        /*Execute the query*/
        ret = gf_sql_query_function (prep_stmt, query_callback, query_cbk_args);
        if (ret) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_QUERY_FAILED,
                        "Failed Query %s", query_str);
                goto out;
        }


        /*Clear counters*/
        if (clear_counters) {
                ret = gf_sql_clear_counters (sql_conn);
                if (ret) {
                        gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                                LG_MSG_CLEAR_COUNTER_FAILED, "Failed clearing "
                                "counters!");
                        goto out;
                }
        }

        ret = 0;
out:
        sqlite3_finalize(prep_stmt);
        return ret;
}
int
quotad_aggregator_getlimit (rpcsvc_request_t *req)
{
        call_frame_t              *frame = NULL;
        gf_cli_req                 cli_req = {{0}, };
        gf_cli_rsp                 cli_rsp = {0};
        gfs3_lookup_req            args  = {{0,},};
        gfs3_lookup_rsp            rsp   = {0,};
        quotad_aggregator_state_t *state = NULL;
        xlator_t                  *this  = NULL;
        dict_t                    *dict  = NULL;
        int                        ret   = -1, op_errno = 0;
        char                      *gfid_str = NULL;
        uuid_t                     gfid = {0};

        GF_VALIDATE_OR_GOTO ("quotad-aggregator", req, err);

        this = THIS;

        ret = xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req);
        if (ret < 0)  {
                //failed to decode msg;
                gf_log ("", GF_LOG_ERROR, "xdr decoding error");
                req->rpc_err = GARBAGE_ARGS;
                goto err;
        }

        if (cli_req.dict.dict_len) {
                dict = dict_new ();
                ret = dict_unserialize (cli_req.dict.dict_val,
                                        cli_req.dict.dict_len, &dict);
                if (ret < 0) {
                        gf_log (this->name, GF_LOG_ERROR, "Failed to "
                                "unserialize req-buffer to dictionary");
                        goto err;
                }
        }

        ret = dict_get_str (dict, "gfid", &gfid_str);
        if (ret) {
                goto err;
        }

        uuid_parse ((const char*)gfid_str, gfid);

        frame = quotad_aggregator_get_frame_from_req (req);
        if (frame == NULL) {
                rsp.op_errno = ENOMEM;
                goto err;
        }
        state = frame->root->state;
        state->xdata = dict;
        ret = dict_set_int32 (state->xdata, QUOTA_LIMIT_KEY, 42);
        if (ret)
                goto err;

        ret = dict_set_int32 (state->xdata, QUOTA_SIZE_KEY, 42);
        if (ret)
                goto err;

        ret = dict_set_int32 (state->xdata, GET_ANCESTRY_PATH_KEY,42);
        if (ret)
                goto err;

        memcpy (&args.gfid, &gfid, 16);

        args.bname           = alloca (req->msg[0].iov_len);
        args.xdata.xdata_val = alloca (req->msg[0].iov_len);

        ret = qd_nameless_lookup (this, frame, &args, state->xdata,
                                  quotad_aggregator_getlimit_cbk);
        if (ret) {
                rsp.op_errno = ret;
                goto err;
        }

        return ret;

err:
        cli_rsp.op_ret = -1;
        cli_rsp.op_errno = op_errno;
        cli_rsp.op_errstr = "";

        quotad_aggregator_getlimit_cbk (this, frame, &cli_rsp);
        dict_unref (dict);

        return ret;
}
/*
 * Find unchanged files from a specified time from the DB
 * Input:
 *      query_callback  :       query callback fuction to handle
 *                              result records from the query
 *      for_time        :        Time from where the file/s are not changed
 * */
int
gf_sqlite3_find_unchanged_for_time (void *db_conn,
                                        gf_query_callback_t query_callback,
                                        void *query_cbk_args,
                                        gfdb_time_t *for_time)
{
        int ret                                 =       -1;
        char *query_str                         =       NULL;
        gf_sql_connection_t *sql_conn           =       db_conn;
        sqlite3_stmt *prep_stmt                 =       NULL;
        uint64_t  for_time_usec                 =       0;

        CHECK_SQL_CONN (sql_conn, out);
        GF_VALIDATE_OR_GOTO(GFDB_STR_SQLITE3, query_callback, out);

        query_str = "select GF_FILE_TB.GF_ID,"
                " (select group_concat( GF_PID || ',' || FNAME || ','"
                " || FPATH || ',' || W_DEL_FLAG ||',' || LINK_UPDATE , '::')"
                " from GF_FLINK_TB where GF_FILE_TB.GF_ID = GF_FLINK_TB.GF_ID)"
                "  from GF_FILE_TB where "
                /*First condition: For writes*/
                "((" GF_COL_TB_WSEC " * " TOSTRING(GFDB_MICROSEC) " + "
                GF_COL_TB_WMSEC ") <= ? )"
                " AND "
                /*Second condition: For reads*/
                "((" GF_COL_TB_RWSEC " * " TOSTRING(GFDB_MICROSEC) " + "
                GF_COL_TB_RWMSEC ") <= ?)";

        for_time_usec = gfdb_time_2_usec(for_time);

        ret = sqlite3_prepare(sql_conn->sqlite3_db_conn, query_str, -1,
                                &prep_stmt, 0);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_PREPARE_FAILED, "Failed preparing statment %s :"
                        " %s", query_str,
                        sqlite3_errmsg(sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

        /*Bind write wind time*/
        ret = sqlite3_bind_int64(prep_stmt, 1, for_time_usec);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_BINDING_FAILED, "Failed binding for_time_usec "
                        "%"PRIu64" : %s", for_time_usec,
                        sqlite3_errmsg(sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

        /*Bind read wind time*/
        ret = sqlite3_bind_int64(prep_stmt, 2, for_time_usec);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_BINDING_FAILED, "Failed binding for_time_usec "
                        "%"PRIu64" : %s", for_time_usec,
                        sqlite3_errmsg(sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

        /*Execute the query*/
        ret = gf_sql_query_function(prep_stmt, query_callback, query_cbk_args);
        if (ret) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_QUERY_FAILED,
                        "Failed Query %s", query_str);
                goto out;
        }

        ret = 0;
out:
        sqlite3_finalize(prep_stmt);
        return ret;
}
int gf_sqlite3_insert(void *db_conn, gfdb_db_record_t *gfdb_db_record)
{
        int ret                         =       -1;
        gf_sql_connection_t *sql_conn   =       db_conn;

        CHECK_SQL_CONN(sql_conn, out);
        GF_VALIDATE_OR_GOTO(GFDB_STR_SQLITE3, gfdb_db_record, out);


        /*This is for debugging bug. Will be removed with a bug fix*/
        if ((GFDB_FOP_WIND == gfdb_db_record->gfdb_fop_path) &&
            (strncmp(gfdb_db_record->file_path, "<gfid", 5) == 0)) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_SKIP_PATH,
                        "Skip path <gfid fop=%d",
                        gfdb_db_record->gfdb_fop_type);
                goto out;
        }

        switch (gfdb_db_record->gfdb_fop_path) {
        case GFDB_FOP_WIND:
                ret = gf_sql_insert_wind(sql_conn, gfdb_db_record);
                if (ret) {
                        gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                                LG_MSG_INSERT_FAILED, "Failed wind insert");
                        goto out;
                }
                break;
        case GFDB_FOP_UNWIND:
                ret = gf_sql_insert_unwind (sql_conn, gfdb_db_record);
                if (ret) {
                        gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                                LG_MSG_INSERT_FAILED, "Failed unwind insert");
                        goto out;
                }
                break;

        case GFDB_FOP_WDEL:
                ret = gf_sql_update_delete_wind(sql_conn, gfdb_db_record);
                if (ret) {
                        gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                                LG_MSG_UPDATE_FAILED, "Failed updating delete "
                                "during wind");
                        goto out;
                }
                break;
        case GFDB_FOP_UNDEL:
        case GFDB_FOP_UNDEL_ALL:
                ret = gf_sql_delete_unwind(sql_conn, gfdb_db_record);
                if (ret) {
                        gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                                LG_MSG_DELETE_FAILED, "Failed deleting");
                        goto out;
                }
                break;
        case GFDB_FOP_INVALID:
        default:
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_INVALID_FOP,
                        "Cannot record to DB: Invalid FOP");
                goto out;
        }

        ret = 0;
out:
        return ret;
}
Beispiel #14
0
/*
 * Find recently changed files with a specific frequency from the DB
 * Input:
 *      db_conn         :       db connection object
 *      query_callback  :       query callback fuction to handle
 *                              result records from the query
 *      from_time       :       Time to define what is recent
 *      freq_write_cnt  :       Frequency thresold for write
 *      freq_read_cnt   :       Frequency thresold for read
 *      clear_counters  :       Clear counters (r/w) for all inodes in DB
 * */
int
gf_sqlite3_find_recently_changed_files_freq (void *db_conn,
                                        gf_query_callback_t query_callback,
                                        void *query_cbk_args,
                                        gfdb_time_t *from_time,
                                        int freq_write_cnt,
                                        int freq_read_cnt,
                                        gf_boolean_t clear_counters)
{
        int ret                                 =       -1;
        char *query_str                         =       NULL;
        gf_sql_connection_t *sql_conn           =       db_conn;
        sqlite3_stmt *prep_stmt                 =       NULL;
        uint64_t  from_time_usec                =       0;
        char *base_query_str                    =       NULL;

        CHECK_SQL_CONN (sql_conn, out);
        GF_VALIDATE_OR_GOTO(GFDB_STR_SQLITE3, query_callback, out);

        ret = gf_get_basic_query_stmt (&base_query_str);
        if (ret <= 0) {
                goto out;
        }
        ret = gf_asprintf (&query_str, "%s AND "
                /*First condition: For Writes*/
                "( ( ((" GF_COL_TB_WSEC " * " TOSTRING(GFDB_MICROSEC) " + "
                GF_COL_TB_WMSEC ") >= ? )"
                " AND "" (" GF_COL_TB_WFC " >= ? ) )"
                " OR "
                /*Second condition: For Reads */
                "( ((" GF_COL_TB_RWSEC " * " TOSTRING(GFDB_MICROSEC) " + "
                GF_COL_TB_RWMSEC ") >= ?)"
                " AND "" (" GF_COL_TB_RFC " >= ? ) ) )", base_query_str);

        if (ret < 0) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_QUERY_FAILED,
                        "Failed to create query statement");
                query_str = NULL;
                goto out;
        }

        from_time_usec = gfdb_time_2_usec (from_time);

        ret = sqlite3_prepare (sql_conn->sqlite3_db_conn, query_str, -1,
                                &prep_stmt, 0);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_PREPARE_FAILED, "Failed to prepare statment %s :"
                        " %s", query_str,
                        sqlite3_errmsg (sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

        /*Bind write wind time*/
        ret = sqlite3_bind_int64 (prep_stmt, 1, from_time_usec);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_BINDING_FAILED, "Failed to bind from_time_usec "
                        "%"PRIu64" : %s", from_time_usec,
                        sqlite3_errmsg (sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

        /*Bind write frequency thresold*/
        ret = sqlite3_bind_int (prep_stmt, 2, freq_write_cnt);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_BINDING_FAILED, "Failed to bind freq_write_cnt "
                        "%d : %s", freq_write_cnt,
                        sqlite3_errmsg (sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }


        /*Bind read wind time*/
        ret = sqlite3_bind_int64 (prep_stmt, 3, from_time_usec);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_BINDING_FAILED, "Failed to bind from_time_usec "
                        "%"PRIu64" : %s", from_time_usec,
                        sqlite3_errmsg (sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

        /*Bind read frequency thresold*/
        ret = sqlite3_bind_int (prep_stmt, 4, freq_read_cnt);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_BINDING_FAILED, "Failed to bind freq_read_cnt "
                        "%d : %s", freq_read_cnt,
                        sqlite3_errmsg (sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

        /*Execute the query*/
        ret = gf_sql_query_function (prep_stmt, query_callback, query_cbk_args);
        if (ret) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_QUERY_FAILED,
                        "Failed Query %s", query_str);
                goto out;
        }



        /*Clear counters*/
        if (clear_counters) {
                ret = gf_sql_clear_counters (sql_conn);
                if (ret) {
                        gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                                LG_MSG_CLEAR_COUNTER_FAILED, "Failed to clear"
                                " counters!");
                        goto out;
                }
        }
        ret = 0;
out:
        sqlite3_finalize (prep_stmt);
        GF_FREE (base_query_str);
        GF_FREE (query_str);
        return ret;
}
Beispiel #15
0
/**
 * __exp_line_dir_parse -- Extract directory name from a line in the exports
 *                         file.
 *
 * @line    : The line to parse
 * @dirname : Double pointer to the string we need to hold the directory name.
 *            If the parsing failed, the string will point to NULL, otherwise
 *            it will point to a valid memory region that is allocated by
 *            this function.
 * @check_ms: If this variable is set then we cross check the directory line
 *            with what's in gluster's vol files and reject them if they don't
 *            match.
 *
 * @return : success: GF_EXP_PARSE_SUCCESS
 *           failure: GF_EXP_PARSE_ITEM_FAILURE on parse failure,
 *           -EINVAL on bad arguments, -ENOMEM on allocation failures,
 *           GF_EXP_PARSE_ITEM_NOT_IN_MOUNT_STATE if we failed to match
 *           with gluster's mountstate.
 *
 * The caller is responsible for freeing memory allocated by this function
 *
 * Not for external use.
 */
static int
__exp_line_dir_parse(const char *line, char **dirname, struct mount3_state *ms)
{
    char *dir = NULL;
    char *delim = NULL;
    int ret = -EINVAL;
    char *linedup = NULL;
    struct mnt3_export *mnt3export = NULL;
    size_t dirlen = 0;

    GF_VALIDATE_OR_GOTO(GF_EXP, line, out);
    GF_VALIDATE_OR_GOTO(GF_EXP, dirname, out);

    /* Duplicate the line because we don't
     * want to modify the original string.
     */
    linedup = strdupa(line);

    /* We use strtok_r () here to split the string by space/tab and get the
     * the result. We only need the first result of the split.
     * a simple task. It is worth noting that dirnames always have to be
     * validated against gluster's vol files so if they don't
     * match it will be rejected.
     */
    dir = linedup;
    delim = linedup + strcspn(linedup, " \t");
    *delim = 0;

    if (ms) {
        /* Match the directory name with an existing
         * export in the mount state.
         */
        mnt3export = mnt3_mntpath_to_export(ms, dir, _gf_true);
        if (!mnt3export) {
            gf_msg_debug(GF_EXP, 0,
                         "%s not in mount state, "
                         "ignoring!",
                         dir);
            ret = GF_EXP_PARSE_ITEM_NOT_IN_MOUNT_STATE;
            goto out;
        }
    }

    /* Directories can be 1024 bytes in length, check
     * that the argument provided adheres to
     * that restriction.
     */
    if (strlen(dir) > DIR_MAX_LEN) {
        ret = -EINVAL;
        goto out;
    }

    /* Copy the result of the split */
    dir = gf_strdup(dir);
    GF_CHECK_ALLOC(dir, ret, out);

    /* Ensure that trailing slashes are stripped before storing the name */
    dirlen = strlen(dir);
    if (dirlen > 0 && dir[dirlen - 1] == '/')
        dir[dirlen - 1] = '\0';

    /* Set the argument to point to the allocated string */
    *dirname = dir;
    ret = GF_EXP_PARSE_SUCCESS;
out:
    return ret;
}
Beispiel #16
0
int
xlator_dynload (xlator_t *xl)
{
        int                ret = -1;
        char              *name = NULL;
        void              *handle = NULL;
        volume_opt_list_t *vol_opt = NULL;


        GF_VALIDATE_OR_GOTO ("xlator", xl, out);

        INIT_LIST_HEAD (&xl->volume_options);

        ret = gf_asprintf (&name, "%s/%s.so", XLATORDIR, xl->type);
        if (-1 == ret) {
                gf_log ("xlator", GF_LOG_ERROR, "asprintf failed");
                goto out;
        }

        ret = -1;

        gf_log ("xlator", GF_LOG_TRACE, "attempt to load file %s", name);

        handle = dlopen (name, RTLD_NOW|RTLD_GLOBAL);
        if (!handle) {
                gf_log ("xlator", GF_LOG_WARNING, "%s", dlerror ());
                goto out;
        }
        xl->dlhandle = handle;

        if (!(xl->fops = dlsym (handle, "fops"))) {
                gf_log ("xlator", GF_LOG_WARNING, "dlsym(fops) on %s",
                        dlerror ());
                goto out;
        }

        if (!(xl->cbks = dlsym (handle, "cbks"))) {
                gf_log ("xlator", GF_LOG_WARNING, "dlsym(cbks) on %s",
                        dlerror ());
                goto out;
        }

        if (!(xl->init = dlsym (handle, "init"))) {
                gf_log ("xlator", GF_LOG_WARNING, "dlsym(init) on %s",
                        dlerror ());
                goto out;
        }

        if (!(xl->fini = dlsym (handle, "fini"))) {
                gf_log ("xlator", GF_LOG_WARNING, "dlsym(fini) on %s",
                        dlerror ());
                goto out;
        }

        if (!(xl->notify = dlsym (handle, "notify"))) {
                gf_log ("xlator", GF_LOG_DEBUG,
                        "dlsym(notify) on %s -- neglecting", dlerror ());
        }

        if (!(xl->dumpops = dlsym (handle, "dumpops"))) {
                gf_log ("xlator", GF_LOG_DEBUG,
                        "dlsym(dumpops) on %s -- neglecting", dlerror ());
        }

        if (!(xl->mem_acct_init = dlsym (handle, "mem_acct_init"))) {
                gf_log (xl->name, GF_LOG_DEBUG,
                        "dlsym(mem_acct_init) on %s -- neglecting",
                        dlerror ());
        }

        if (!(xl->reconfigure = dlsym (handle, "reconfigure"))) {
                gf_log ("xlator", GF_LOG_DEBUG,
                        "dlsym(reconfigure) on %s -- neglecting",
                        dlerror());
        }

        vol_opt = GF_CALLOC (1, sizeof (volume_opt_list_t),
                         gf_common_mt_volume_opt_list_t);

        if (!vol_opt) {
                goto out;
        }

        if (!(vol_opt->given_opt = dlsym (handle, "options"))) {
                dlerror ();
                gf_log (xl->name, GF_LOG_DEBUG,
                        "Strict option validation not enforced -- neglecting");
        }
        list_add_tail (&vol_opt->list, &xl->volume_options);

        fill_defaults (xl);

        ret = 0;

out:
        if (name)
                GF_FREE (name);
        return ret;
}
Beispiel #17
0
/**
 * _exp_line_parse -- Parse a line in an exports file into a structure
 *                    that holds all the parts of the line. An exports
 *                    structure has a dict of netgroups and a dict of hosts.
 *
 * An export line looks something like this /test  @test(sec=sys,rw,anonuid=0)
 * or /test  @test(sec=sys,rw,anonuid=0) hostA(sec=sys,rw,anonuid=0), etc.
 *
 * We use regexes to parse the line into three separate pieces:
 * 1) The directory (exports.h -- DIRECTORY_REGEX_PATTERN)
 * 2) The netgroup if it exists (exports.h -- NETGROUP_REGEX_PATTERN)
 * 3) The host if it exists (exports.h -- HOST_REGEX_PATTERN)
 *
 * In this case, the netgroup would be @test(sec=sys,rw,anonuid=0)
 * and the host would be hostA(sec=sys,rw,anonuid=0).
 *
 * @line        : The line to parse
 * @dir         : Double pointer to the struct we need to parse the line into.
 *                If the parsing failed, the struct will point to NULL,
 *                otherwise it will point to a valid memory region that is
 *                allocated by this function.
 * @parse_full  : This parameter tells us whether we should parse all the lines
 *                in the file, even if they are not present in gluster's config.
 *                The gluster config holds the volumes that it exports so
 *                if parse_full is set to FALSE then we will ensure that
 *                the export file structure holds only those volumes
 *                that gluster has exported. It is important to note that
 *                If gluster exports a volume named '/test', '/test' and all
 *                of its subdirectories that may be in the exports file
 *                are valid exports.
 *  @ms         : The mount state that holds the list of volumes that gluster
 *                currently exports.
 *
 * @return : success: GF_EXP_PARSE_SUCCESS on success, -EINVAL on bad arguments,
 *                    -ENOMEM on memory allocation errors,
 *                    GF_EXP_PARSE_LINE_IGNORING if we ignored the line,
 *                    GF_EXP_PARSE_ITEM_FAILURE if there was error parsing
 *           failure: NULL
 *
 * The caller is responsible for freeing memory allocated by this function
 * The caller should free this memory using the _exp_dir_deinit () function.
 *
 * Not for external use.
 */
static int
_exp_line_parse(const char *line, struct export_dir **dir,
                gf_boolean_t parse_full, struct mount3_state *ms)
{
    struct export_dir *expdir = NULL;
    char *dirstr = NULL;
    dict_t *netgroups = NULL;
    dict_t *hosts = NULL;
    int ret = -EINVAL;
    gf_boolean_t netgroups_failed = _gf_false;

    GF_VALIDATE_OR_GOTO(GF_EXP, line, out);
    GF_VALIDATE_OR_GOTO(GF_EXP, dir, out);

    if (*line == '#' || *line == ' ' || *line == '\t' || *line == '\0' ||
        *line == '\n') {
        ret = GF_EXP_PARSE_LINE_IGNORING;
        goto out;
    }

    expdir = _export_dir_init();
    if (!expdir) {
        *dir = NULL;
        ret = -ENOMEM;
        goto out;
    }

    /* Get the directory string from the line */
    ret = __exp_line_dir_parse(line, &dirstr, ms);
    if (ret < 0) {
        gf_msg(GF_EXP, GF_LOG_ERROR, 0, NFS_MSG_PARSE_DIR_FAIL,
               "Parsing directory failed: %s", strerror(-ret));
        /* If parsing the directory failed,
         * we should simply fail because there's
         * nothing else we can extract from the string to make
         * the data valuable.
         */
        goto free_and_out;
    }

    /* Set the dir str */
    expdir->dir_name = dirstr;

    /* Parse the netgroup part of the string */
    ret = __exp_line_ng_parse(line, &netgroups);
    if (ret < 0) {
        gf_msg(GF_EXP, GF_LOG_ERROR, -ret, NFS_MSG_PARSE_FAIL,
               "Critical error: %s", strerror(-ret));
        /* Return values less than 0
         * indicate critical failures (null parameters,
         * failure to allocate memory, etc).
         */
        goto free_and_out;
    }
    if (ret != 0) {
        if (ret == GF_EXP_PARSE_ITEM_FAILURE)
            /* Cannot change to gf_msg.
             * gf_msg not giving output to STDOUT
             * Bug id : BZ1215017
             */
            gf_log(GF_EXP, GF_LOG_WARNING, "Error parsing netgroups for: %s",
                   line);
        /* Even though parsing failed for the netgroups we should let
         * host parsing proceed.
         */
        netgroups_failed = _gf_true;
    }

    /* Parse the host part of the string */
    ret = __exp_line_host_parse(line, &hosts);
    if (ret < 0) {
        gf_msg(GF_EXP, GF_LOG_ERROR, -ret, NFS_MSG_PARSE_FAIL,
               "Critical error: %s", strerror(-ret));
        goto free_and_out;
    }
    if (ret != 0) {
        if (ret == GF_EXP_PARSE_ITEM_FAILURE)
            gf_msg(GF_EXP, GF_LOG_WARNING, 0, NFS_MSG_PARSE_FAIL,
                   "Error parsing hosts for: %s", line);
        /* If netgroups parsing failed, AND
         * host parsing failed, then there's something really
         * wrong with this line, so we're just going to
         * log it and fail out.
         */
        if (netgroups_failed)
            goto free_and_out;
    }

    expdir->hosts = hosts;
    expdir->netgroups = netgroups;
    *dir = expdir;
    goto out;

free_and_out:
    _export_dir_deinit(expdir);
out:
    return ret;
}
Beispiel #18
0
static int
event_register_poll (struct event_pool *event_pool, int fd,
                     event_handler_t handler,
                     void *data, int poll_in, int poll_out)
{
        int idx = -1;

        GF_VALIDATE_OR_GOTO ("event", event_pool, out);

        pthread_mutex_lock (&event_pool->mutex);
        {
                if (event_pool->count == event_pool->used)
                {
                        event_pool->count += 256;

                        event_pool->reg = GF_REALLOC (event_pool->reg,
                                                      event_pool->count *
                                                      sizeof (*event_pool->reg));
                        if (!event_pool->reg)
                                goto unlock;
                }

                idx = event_pool->used++;

                event_pool->reg[idx].fd = fd;
                event_pool->reg[idx].events = POLLPRI;
                event_pool->reg[idx].handler = handler;
                event_pool->reg[idx].data = data;

                switch (poll_in) {
                case 1:
                        event_pool->reg[idx].events |= POLLIN;
                        break;
                case 0:
                        event_pool->reg[idx].events &= ~POLLIN;
                        break;
                case -1:
                        /* do nothing */
                        break;
                default:
                        gf_msg ("poll", GF_LOG_ERROR, 0,
                                LG_MSG_INVALID_POLL_IN,
                                "invalid poll_in value %d", poll_in);
                        break;
                }

                switch (poll_out) {
                case 1:
                        event_pool->reg[idx].events |= POLLOUT;
                        break;
                case 0:
                        event_pool->reg[idx].events &= ~POLLOUT;
                        break;
                case -1:
                        /* do nothing */
                        break;
                default:
                        gf_msg ("poll", GF_LOG_ERROR, 0,
                                LG_MSG_INVALID_POLL_OUT,
                                "invalid poll_out value %d", poll_out);
                        break;
                }

                event_pool->changed = 1;

        }
unlock:
        pthread_mutex_unlock (&event_pool->mutex);

out:
        return idx;
}
Beispiel #19
0
/**
 * __exp_line_ng_host_str_parse -- Parse the netgroup or host string
 *
 *      e.g. @mygroup(<options>), parsing @mygroup and (<options>)
 *      or   myhost001.dom(<options>), parsing myhost001.dom and (<options>)
 *
 * @line      : The line to parse
 * @exp_item  : Double pointer to a struct export_item
 *
 * @return: success: GF_PARSE_SUCCESS
 *          failure: GF_EXP_PARSE_ITEM_FAILURE on parse failure,
 *                   -EINVAL on bad args, -ENOMEM on allocation errors.
 *
 * Not for external use.
 */
static int
__exp_line_ng_host_str_parse(char *str, struct export_item **exp_item)
{
    struct export_item *item = NULL;
    int ret = -EINVAL;
    char *parens = NULL;
    char *optstr = NULL;
    struct export_options *exp_opts = NULL;
    char *item_name = NULL;

    GF_VALIDATE_OR_GOTO(GF_EXP, str, out);
    GF_VALIDATE_OR_GOTO(GF_EXP, exp_item, out);

    /* A netgroup/host string looks like this:
     * @test(sec=sys,rw,anonuid=0) or host(sec=sys,rw,anonuid=0)
     * We want to extract the name, 'test' or 'host'
     * Again, we could setup a regex and use it here,
     * but its simpler to find the '(' and copy until
     * there.
     */
    parens = strchr(str, '(');
    if (!parens) {
        /* Parse error if there are no parens. */
        ret = GF_EXP_PARSE_ITEM_FAILURE;
        goto out;
    }

    *parens = '\0'; /* Temporarily terminate it so we can do a copy */

    if (strlen(str) > FQDN_MAX_LEN) {
        ret = GF_EXP_PARSE_ITEM_FAILURE;
        goto out;
    }

    /* Strip leading whitespaces */
    while (*str == ' ' || *str == '\t')
        str++;

    item_name = gf_strdup(str);
    GF_CHECK_ALLOC(item_name, ret, out);

    gf_msg_trace(GF_EXP, 0, "found hostname/netgroup: %s", item_name);

    /* Initialize an export item for this */
    item = _export_item_init();
    GF_CHECK_ALLOC(item, ret, free_and_out);
    item->name = item_name;

    *parens = '('; /* Restore the string */

    /* Options start at the parentheses */
    optstr = parens;

    ret = __exp_line_opt_parse(optstr, &exp_opts);
    if (ret != 0) {
        /* Bubble up the error to the caller */
        GF_REF_PUT(item);
        goto out;
    }

    item->opts = exp_opts;

    *exp_item = item;

    ret = GF_EXP_PARSE_SUCCESS;
    goto out;

free_and_out:
    GF_FREE(item_name);
out:
    return ret;
}
static int
gf_sql_update_link (gf_sql_connection_t  *sql_conn,
                   char                 *gfid,
                   char                 *pargfid,
                   char                 *basename,
                   char                 *basepath,
                   char                 *old_pargfid,
                   char                 *old_basename,
                   gf_boolean_t         link_consistency)
{
        int ret = -1;
        sqlite3_stmt *insert_stmt = NULL;
        char insert_str[GFDB_SQL_STMT_SIZE] = "";

        sprintf (insert_str, "INSERT INTO "
                            GF_FILE_LINK_TABLE
                            " (GF_ID, GF_PID, FNAME, FPATH,"
                            " W_DEL_FLAG, LINK_UPDATE) "
                            " VALUES (? , ?, ?, ?, 0, %d);",
                            link_consistency);

        CHECK_SQL_CONN (sql_conn, out);
        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, gfid, out);
        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, pargfid, out);
        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, basename, out);
        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, basepath, out);
        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, old_pargfid, out);
        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, old_basename, out);

        /*
         *
         * Delete the old link
         *
         * */
         ret = gf_sql_delete_link (sql_conn, gfid, old_pargfid,
                                old_basename);
        if (ret) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_DELETE_FAILED, "Failed deleting old link");
                goto out;
        }

        /*
         *
         * insert new link
         *
         * */
        /*Prepare statement*/
        ret = sqlite3_prepare (sql_conn->sqlite3_db_conn, insert_str, -1,
                                &insert_stmt, 0);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_PREPARE_FAILED, "Failed preparing insert "
                        "statment %s : %s", insert_str,
                        sqlite3_errmsg (sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

        /*Bind gfid*/
        ret = sqlite3_bind_text (insert_stmt, 1, gfid, -1, NULL);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_BINDING_FAILED, "Failed binding gfid %s : %s",
                        gfid, sqlite3_errmsg (sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

        /*Bind new pargfid*/
        ret = sqlite3_bind_text (insert_stmt, 2, pargfid, -1, NULL);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_BINDING_FAILED, "Failed binding parent gfid %s "
                        ": %s", pargfid,
                        sqlite3_errmsg (sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

        /*Bind new basename*/
        ret = sqlite3_bind_text (insert_stmt, 3, basename, -1, NULL);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_BINDING_FAILED, "Failed binding basename %s : "
                        "%s", basename,
                        sqlite3_errmsg (sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

        /*Bind new basepath*/
        ret = sqlite3_bind_text (insert_stmt, 4, basepath, -1, NULL);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_BINDING_FAILED, "Failed binding basename %s : "
                        "%s", basepath,
                        sqlite3_errmsg (sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

        /*Execute the prepare statement*/
        if (sqlite3_step (insert_stmt) != SQLITE_DONE) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_EXEC_FAILED,
                        "Failed executing the prepared stmt %s : %s",
                        insert_str,
                        sqlite3_errmsg (sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }



        ret = 0;
out:
        /*Free prepared statement*/
        sqlite3_finalize (insert_stmt);
        return ret;
}
Beispiel #21
0
/**
 * __exp_line_host_parse -- Extract the hosts in the line
 *                          and call helper functions to parse
 *                          the string.
 *
 * The call chain goes like this:
 *
 * 1) __exp_line_host_parse ("/test  hostip(sec=sys,rw,anonuid=0)")
 * 2) __exp_line_ng_host_str_parse ("hostip(sec=sys,rw,anonuid=0)");
 * 3) __exp_line_opt_parse("(sec=sys,rw,anonuid=0)");
 *
 *
 * @line    : The line to parse
 * @ng_dict : Double pointer to the dict we want to
 *            insert hosts into.
 *
 * Allocates the dict, extracts host strings from the line,
 * parses them into a struct export_item structure and inserts
 * them in the dict.
 *
 * @return: success: GF_EXP_PARSE_SUCCESS
 *          failure: GF_EXP_PARSE_ITEM_FAILURE on parse failure,
 *                   GF_EXP_PARSE_ITEM_NOT_FOUND if the host was not found,
 *                   -EINVAL on bad args, -ENOMEM on allocation errors.
 *
 * Not for external use.
 */
static int
__exp_line_host_parse(const char *line, dict_t **host_dict)
{
    dict_t *hosts = NULL;
    char *strmatch = NULL;
    int ret = -EINVAL;
    struct export_item *exp_host = NULL;
    data_t *hostdata = NULL;

    GF_VALIDATE_OR_GOTO(GF_EXP, line, out);
    GF_VALIDATE_OR_GOTO(GF_EXP, host_dict, out);

    *host_dict = NULL;

    /* Initialize a parser with the line to parse and the regex used to
     * parse it.
     */
    ret = parser_set_string(hostname_parser, line);
    if (ret < 0) {
        goto out;
    }

    gf_msg_trace(GF_EXP, 0, "parsing line: %s", line);

    while ((strmatch = parser_get_next_match(hostname_parser))) {
        if (!hosts) {
            /* Allocate a new dictto store the netgroups. */
            hosts = dict_new();
            GF_CHECK_ALLOC(hosts, ret, free_and_out);
        }

        gf_msg_trace(GF_EXP, 0, "parsing hostname: %s", strmatch);

        ret = __exp_line_ng_host_str_parse(strmatch, &exp_host);

        if (ret != 0) {
            /* Parsing or other critical error, free allocated
             * memory and exit. The caller will handle the errors.
             */
            _exp_dict_destroy(hosts);
            goto free_and_out;
        }

        /* Insert export item structure into the hosts dict. */
        hostdata = bin_to_data(exp_host, sizeof(*exp_host));
        dict_set(hosts, exp_host->name, hostdata);

        /* Free this matched string and continue parsing.*/
        GF_FREE(strmatch);
    }

    /* If the hosts dict was not allocated, then we know that
     * no matches were found.
     */
    if (!exp_host) {
        ret = GF_EXP_PARSE_ITEM_NOT_FOUND;
        parser_unset_string(hostname_parser);
        goto out;
    }

    ret = GF_EXP_PARSE_SUCCESS;
    *host_dict = hosts;

free_and_out:
    parser_unset_string(hostname_parser);
    GF_FREE(strmatch);
out:
    return ret;
}
static int
gf_sql_insert_write_wind_time (gf_sql_connection_t  *sql_conn,
                                char                 *gfid,
                                gfdb_time_t          *wind_time)
{
        int ret = -1;
        sqlite3_stmt *insert_stmt = NULL;
        char *insert_str = "INSERT INTO "
                           GF_FILE_TABLE
                           "(GF_ID, W_SEC, W_MSEC, UW_SEC, UW_MSEC)"
                           " VALUES (?, ?, ?, 0, 0);";

        CHECK_SQL_CONN (sql_conn, out);
        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, gfid, out);
        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, wind_time, out);


        /*Prepare statement*/
        ret = sqlite3_prepare (sql_conn->sqlite3_db_conn, insert_str, -1,
                        &insert_stmt, 0);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_PREPARE_FAILED, "Failed preparing insert "
                        "statment %s : %s", insert_str,
                        sqlite3_errmsg (sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

        /*Bind gfid*/
        ret = sqlite3_bind_text (insert_stmt, 1, gfid, -1, NULL);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_BINDING_FAILED, "Failed binding gfid %s : %s",
                        gfid, sqlite3_errmsg (sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

        /*Bind wind secs*/
        ret = sqlite3_bind_int (insert_stmt, 2, wind_time->tv_sec);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_BINDING_FAILED, "Failed binding parent wind "
                        "secs %ld : %s", wind_time->tv_sec,
                        sqlite3_errmsg (sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

        /*Bind wind msecs*/
        ret = sqlite3_bind_int (insert_stmt, 3, wind_time->tv_usec);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_BINDING_FAILED, "Failed binding parent wind "
                        "msecs %ld : %s", wind_time->tv_usec,
                        sqlite3_errmsg (sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

        /*Execute the prepare statement*/
        if (sqlite3_step (insert_stmt) != SQLITE_DONE) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_EXEC_FAILED,
                        "Failed executing the prepared stmt GFID:%s %s : %s",
                        gfid, insert_str,
                        sqlite3_errmsg (sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

        ret = 0;
out:
        /*Free prepared statement*/
        sqlite3_finalize (insert_stmt);
        return ret;
}
Beispiel #23
0
transport_t *
transport_load (dict_t *options,
		xlator_t *xl)
{
	struct transport *trans = NULL, *return_trans = NULL;
	char *name = NULL;
	void *handle = NULL;
	char *type = NULL;
	char str[] = "ERROR";
	int32_t ret = -1;
	int8_t is_tcp = 0, is_unix = 0, is_ibsdp = 0;
	volume_opt_list_t *vol_opt = NULL;

	GF_VALIDATE_OR_GOTO("transport", options, fail);
	GF_VALIDATE_OR_GOTO("transport", xl, fail);
  
	trans = GF_CALLOC (1, sizeof (struct transport),
                           gf_common_mt_transport);
	GF_VALIDATE_OR_GOTO("transport", trans, fail);

	trans->xl = xl;
	type = str;

	/* Backward compatibility */
	ret = dict_get_str (options, "transport-type", &type);
	if (ret < 0) {
		ret = dict_set_str (options, "transport-type", "socket");
		if (ret < 0)
			gf_log ("dict", GF_LOG_DEBUG,
				"setting transport-type failed");
		gf_log ("transport", GF_LOG_WARNING,
			"missing 'option transport-type'. defaulting to "
			"\"socket\"");
	} else {
		{
			/* Backword compatibility to handle * /client,
			 * * /server. 
			 */
			char *tmp = strchr (type, '/');
			if (tmp)
				*tmp = '\0';
		}
		
		is_tcp = strcmp (type, "tcp");
		is_unix = strcmp (type, "unix");
		is_ibsdp = strcmp (type, "ib-sdp");
		if ((is_tcp == 0) ||
		    (is_unix == 0) ||
		    (is_ibsdp == 0)) {
			if (is_unix == 0)
				ret = dict_set_str (options, 
						    "transport.address-family",
						    "unix");
			if (is_ibsdp == 0)
				ret = dict_set_str (options, 
						    "transport.address-family",
						    "inet-sdp");

			if (ret < 0)
				gf_log ("dict", GF_LOG_DEBUG,
					"setting address-family failed");

			ret = dict_set_str (options, 
					    "transport-type", "socket");
			if (ret < 0)
				gf_log ("dict", GF_LOG_DEBUG,
					"setting transport-type failed");
		}
	}

	ret = dict_get_str (options, "transport-type", &type);
	if (ret < 0) {
		GF_FREE (trans);
		gf_log ("transport", GF_LOG_ERROR,
			"'option transport-type <xx>' missing in volume '%s'",
			xl->name);
		goto fail;
	}

	ret = gf_asprintf (&name, "%s/%s.so", TRANSPORTDIR, type);
        if (-1 == ret) {
                gf_log ("transport", GF_LOG_ERROR, "asprintf failed");
                goto fail;
        }
	gf_log ("transport", GF_LOG_DEBUG,
		"attempt to load file %s", name);

	handle = dlopen (name, RTLD_NOW|RTLD_GLOBAL);
	if (handle == NULL) {
		gf_log ("transport", GF_LOG_ERROR, "%s", dlerror ());
		gf_log ("transport", GF_LOG_ERROR,
			"volume '%s': transport-type '%s' is not valid or "
			"not found on this machine", 
			xl->name, type);
		GF_FREE (name);
		GF_FREE (trans);
		goto fail;
	}
	GF_FREE (name);
	
	trans->ops = dlsym (handle, "tops");
	if (trans->ops == NULL) {
		gf_log ("transport", GF_LOG_ERROR,
			"dlsym (transport_ops) on %s", dlerror ());
		GF_FREE (trans);
		goto fail;
	}

	trans->init = dlsym (handle, "init");
	if (trans->init == NULL) {
		gf_log ("transport", GF_LOG_ERROR,
			"dlsym (gf_transport_init) on %s", dlerror ());
		GF_FREE (trans);
		goto fail;
	}

	trans->fini = dlsym (handle, "fini");
	if (trans->fini == NULL) {
		gf_log ("transport", GF_LOG_ERROR,
			"dlsym (gf_transport_fini) on %s", dlerror ());
		GF_FREE (trans);
		goto fail;
	}
	
	vol_opt = GF_CALLOC (1, sizeof (volume_opt_list_t),
                             gf_common_mt_volume_opt_list_t);
	vol_opt->given_opt = dlsym (handle, "options");
	if (vol_opt->given_opt == NULL) {
		gf_log ("transport", GF_LOG_DEBUG,
			"volume option validation not specified");
	} else {
		list_add_tail (&vol_opt->list, &xl->volume_options);
		if (-1 == 
		    validate_xlator_volume_options (xl, 
						    vol_opt->given_opt)) {
			gf_log ("transport", GF_LOG_ERROR,
				"volume option validation failed");
			GF_FREE (trans);
			goto fail;
		}
	}
	
	ret = trans->init (trans);
	if (ret != 0) {
		gf_log ("transport", GF_LOG_ERROR,
			"'%s' initialization failed", type);
		GF_FREE (trans);
		goto fail;
	}

	pthread_mutex_init (&trans->lock, NULL);
	return_trans = trans;
fail:
	return return_trans;
}
/*Update write/read times for both wind and unwind*/
static int
gf_update_time (gf_sql_connection_t    *sql_conn,
                char                    *gfid,
                gfdb_time_t             *update_time,
                gf_boolean_t            record_counter,
                gf_boolean_t            is_wind,
                gf_boolean_t            is_read)
{
        int ret = -1;
        sqlite3_stmt *update_stmt = NULL;
        char update_str[1024] = "";
        char *freq_cntr_str = NULL;

        CHECK_SQL_CONN (sql_conn, out);
        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, gfid, out);
        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, update_time, out);

        /*
         * Constructing the prepare statment string.
         *
         * */
        /*For write time*/
        if (!is_read) {
                if (is_wind) {
                        /*if record counter is on*/
                        freq_cntr_str = (record_counter) ?
                        ", WRITE_FREQ_CNTR = WRITE_FREQ_CNTR + 1" : "";

                        /*Prefectly safe as we will not go array of bound*/
                        sprintf (update_str, "UPDATE "
                                GF_FILE_TABLE
                                " SET W_SEC = ?, W_MSEC = ? "
                                " %s"/*place for read freq counters*/
                                " WHERE GF_ID = ? ;", freq_cntr_str);
                } else {
                        /*Prefectly safe as we will not go array of bound*/
                        sprintf (update_str, "UPDATE "
                                GF_FILE_TABLE
                                " SET UW_SEC = ?, UW_MSEC = ? ;");
                }
        }
        /*For Read Time update*/
        else {
                if (is_wind) {
                        /*if record counter is on*/
                        freq_cntr_str = (record_counter) ?
                        ", READ_FREQ_CNTR = READ_FREQ_CNTR + 1" : "";

                        /*Prefectly safe as we will not go array of bound*/
                        sprintf (update_str, "UPDATE "
                                GF_FILE_TABLE
                                " SET W_READ_SEC = ?, W_READ_MSEC = ? "
                                " %s"/*place for read freq counters*/
                                " WHERE GF_ID = ? ;", freq_cntr_str);
                } else {
                        /*Prefectly safe as we will not go array of bound*/
                        sprintf (update_str, "UPDATE "
                                GF_FILE_TABLE
                                " SET UW_READ_SEC = ?, UW_READ_MSEC = ? ;");
                }
        }

        /*Prepare statement*/
        ret = sqlite3_prepare (sql_conn->sqlite3_db_conn, update_str, -1,
                                &update_stmt, 0);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_PREPARE_FAILED, "Failed preparing insert "
                        "statment %s : %s", update_str,
                        sqlite3_errmsg (sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

        /*Bind time secs*/
        ret = sqlite3_bind_int (update_stmt, 1, update_time->tv_sec);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_BINDING_FAILED, "Failed binding parent wind "
                        "secs %ld : %s", update_time->tv_sec,
                        sqlite3_errmsg (sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

        /*Bind time msecs*/
        ret = sqlite3_bind_int (update_stmt, 2, update_time->tv_usec);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_BINDING_FAILED, "Failed binding parent wind "
                        "msecs %ld : %s", update_time->tv_usec,
                        sqlite3_errmsg (sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

        /*Bind gfid*/
        ret = sqlite3_bind_text (update_stmt, 3, gfid, -1, NULL);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_BINDING_FAILED, "Failed binding gfid %s : %s",
                        gfid, sqlite3_errmsg (sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

        /*Execute the prepare statement*/
        if (sqlite3_step (update_stmt) != SQLITE_DONE) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_EXEC_FAILED,
                        "Failed executing the prepared stmt %s : %s",
                        update_str,
                        sqlite3_errmsg (sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

        ret = 0;
out:
        /*Free prepared statement*/
        sqlite3_finalize (update_stmt);
        return ret;
}
int
gf_sql_delete_unwind (gf_sql_connection_t  *sql_conn,
                          gfdb_db_record_t     *gfdb_db_record)
{
        int ret = -1;
        char *gfid_str = NULL;
        char *pargfid_str = NULL;
        gfdb_time_t *modtime    = NULL;

        CHECK_SQL_CONN (sql_conn, out);
        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, gfdb_db_record, out);

        gfid_str = gf_strdup (uuid_utoa(gfdb_db_record->gfid));
        if (!gfid_str) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_CREATE_FAILED, "Creating gfid string failed.");
                goto out;
        }

        /*Nuke all the entries for this GFID from DB*/
        if (gfdb_db_record->gfdb_fop_path == GFDB_FOP_UNDEL_ALL) {
                gf_sql_delete_all(sql_conn, gfid_str);
        }
        /*Remove link entries only*/
        else if (gfdb_db_record->gfdb_fop_path == GFDB_FOP_UNDEL) {

                pargfid_str = gf_strdup(uuid_utoa(gfdb_db_record->pargfid));
                if (!pargfid_str) {
                        gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                                LG_MSG_CREATE_FAILED, "Creating pargfid_str "
                                "string failed.");
                        goto out;
                }

                /* Special performance case:
                 * Updating wind time in unwind for delete. This is done here
                 * as in the wind path we will not know whether its the last
                 * link or not. For a last link there is not use to update any
                 * wind or unwind time!*/
                if (gfdb_db_record->do_record_times) {
                        /*Update the wind write times*/
                        modtime = &gfdb_db_record->gfdb_wind_change_time;
                        ret = gf_update_time (sql_conn, gfid_str, modtime,
                                gfdb_db_record->do_record_counters,
                                _gf_true,
                                isreadfop (gfdb_db_record->gfdb_fop_type));
                        if (ret) {
                                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                                        LG_MSG_UPDATE_FAILED,
                                        "Failed update wind time in DB");
                                goto out;
                        }
                }

                modtime = &gfdb_db_record->gfdb_unwind_change_time;

                ret = gf_sql_delete_link(sql_conn, gfid_str, pargfid_str,
                                        gfdb_db_record->file_name);
                if (ret) {
                        gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                                LG_MSG_DELETE_FAILED, "Failed deleting link");
                        goto out;
                }

                if (gfdb_db_record->do_record_times &&
                        gfdb_db_record->do_record_uwind_time) {
                        ret = gf_update_time (sql_conn, gfid_str, modtime,
                                gfdb_db_record->do_record_counters,
                                _gf_false,
                                isreadfop(gfdb_db_record->gfdb_fop_type));
                        if (ret) {
                                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                                        LG_MSG_UPDATE_FAILED, "Failed update "
                                        "unwind time in DB");
                                goto out;
                        }
                }
        } else {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_INVALID_UPLINK, "Invalid unlink option");
                goto out;
        }
        ret = 0;
out:
        GF_FREE (gfid_str);
        GF_FREE (pargfid_str);
        return ret;
}
int
gf_sql_insert_wind (gf_sql_connection_t  *sql_conn,
                   gfdb_db_record_t     *gfdb_db_record)
{
        int ret                 = -1;
        gfdb_time_t *modtime    = NULL;
        char *pargfid_str       = NULL;
        char *gfid_str          = NULL;
        char *old_pargfid_str   = NULL;
        gf_boolean_t its_wind   = _gf_true;/*remains true for this function*/



        CHECK_SQL_CONN (sql_conn, out);
        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, gfdb_db_record, out);


        gfid_str = gf_strdup (uuid_utoa (gfdb_db_record->gfid));
        if (!gfid_str) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_CREATE_FAILED, "Creating gfid string failed.");
                goto out;
        }

        modtime = &gfdb_db_record->gfdb_wind_change_time;

        /* handle all dentry based operations */
        if (isdentryfop (gfdb_db_record->gfdb_fop_type)) {
                /*Parent GFID is always set*/
                pargfid_str = gf_strdup (uuid_utoa (gfdb_db_record->pargfid));
                if (!pargfid_str) {
                        gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                                LG_MSG_CREATE_FAILED, "Creating gfid string "
                                "failed.");
                        goto out;
                }

                /* handle create, mknod */
                if (isdentrycreatefop (gfdb_db_record->gfdb_fop_type)) {
                        /*insert link*/
                        ret = gf_sql_insert_link(sql_conn,
                                        gfid_str, pargfid_str,
                                        gfdb_db_record->file_name,
                                        gfdb_db_record->file_path,
                                        gfdb_db_record->link_consistency,
                                        gfdb_db_record->ignore_errors);
                        if (ret) {
                                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                                        LG_MSG_INSERT_FAILED, "Failed "
                                        "inserting link in DB");
                                goto out;
                        }
                        gfdb_db_record->islinkupdate = gfdb_db_record->
                                                        link_consistency;

                        /*
                         * Only for create/mknod insert wind time
                         * for the first time
                         * */
                        ret = gf_sql_insert_write_wind_time (sql_conn, gfid_str,
                                                                modtime);
                        if (ret) {
                                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                                        LG_MSG_INSERT_FAILED, "Failed "
                                        "inserting wind time in DB");
                                goto out;
                        }
                        goto out;
                }
                /*handle rename, link */
                else {
                        /*rename*/
                        if (strlen (gfdb_db_record->old_file_name) != 0) {
                                old_pargfid_str = gf_strdup (uuid_utoa (
                                                gfdb_db_record->old_pargfid));
                                if (!old_pargfid_str) {
                                        gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR,
                                                0, LG_MSG_CREATE_FAILED,
                                                "Creating gfid string failed.");
                                        goto out;
                                }
                                ret = gf_sql_update_link (sql_conn, gfid_str,
                                                pargfid_str,
                                                gfdb_db_record->file_name,
                                                gfdb_db_record->file_path,
                                                old_pargfid_str,
                                                gfdb_db_record->old_file_name,
                                                gfdb_db_record->
                                                        link_consistency);
                                if (ret) {
                                        gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR,
                                                0, LG_MSG_UPDATE_FAILED,
                                                "Failed updating link");
                                        goto out;
                                }
                                gfdb_db_record->islinkupdate = gfdb_db_record->
                                                        link_consistency;
                        }
                        /*link*/
                        else {
                                ret = gf_sql_insert_link (sql_conn,
                                        gfid_str, pargfid_str,
                                        gfdb_db_record->file_name,
                                        gfdb_db_record->file_path,
                                        gfdb_db_record->link_consistency,
                                        gfdb_db_record->ignore_errors);
                                if (ret) {
                                        gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR,
                                                0, LG_MSG_INSERT_FAILED,
                                                "Failed inserting link in DB");
                                        goto out;
                                }
                                gfdb_db_record->islinkupdate = gfdb_db_record->
                                                        link_consistency;
                        }
                }
        }

        /* update times only when said!*/
        if (gfdb_db_record->do_record_times) {
                /*All fops update times read or write*/
                ret = gf_update_time (sql_conn, gfid_str, modtime,
                        gfdb_db_record->do_record_counters,
                        its_wind,
                        isreadfop (gfdb_db_record->gfdb_fop_type));
                if (ret) {
                        gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                                LG_MSG_UPDATE_FAILED, "Failed update wind time"
                                " in DB");
                        goto out;
                }
        }

        ret = 0;
out:
        GF_FREE (gfid_str);
        GF_FREE (pargfid_str);
        GF_FREE (old_pargfid_str);
        return ret;
}
static inline int
gf_sql_delete_link (gf_sql_connection_t  *sql_conn,
                   char                 *gfid,
                   char                 *pargfid,
                   char                 *basename)
{
        int ret = -1;
        sqlite3_stmt *delete_stmt = NULL;
        char *delete_str = "DELETE FROM "
                           GF_FILE_LINK_TABLE
                           " WHERE GF_ID = ? AND GF_PID = ?"
                           " AND FNAME = ?;";

        CHECK_SQL_CONN (sql_conn, out);
        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, gfid, out);
        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, pargfid, out);
        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, basename, out);

        /*Prepare statement*/
        ret = sqlite3_prepare (sql_conn->sqlite3_db_conn, delete_str, -1,
                                &delete_stmt, 0);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_PREPARE_FAILED, "Failed preparing delete "
                        "statment %s : %s", delete_str,
                        sqlite3_errmsg (sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

        /*Bind gfid*/
        ret = sqlite3_bind_text (delete_stmt, 1, gfid, -1, NULL);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_BINDING_FAILED,
                        "Failed binding gfid %s : %s", gfid,
                        sqlite3_errmsg (sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

        /*Bind pargfid*/
        ret = sqlite3_bind_text (delete_stmt, 2, pargfid, -1, NULL);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_BINDING_FAILED, "Failed binding parent gfid %s "
                        ": %s", pargfid,
                        sqlite3_errmsg (sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

        /*Bind basename*/
        ret = sqlite3_bind_text (delete_stmt, 3, basename, -1, NULL);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_BINDING_FAILED, "Failed binding basename %s : "
                        "%s", basename,
                        sqlite3_errmsg (sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

        /*Execute the prepare statement*/
        if (sqlite3_step(delete_stmt) != SQLITE_DONE) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_EXEC_FAILED,
                        "Failed executing the prepared stmt %s : %s",
                        delete_str,
                        sqlite3_errmsg (sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }


        ret = 0;
out:
        /*Free prepared statement*/
        sqlite3_finalize (delete_stmt);
        return ret;
}
int
gf_sql_insert_unwind (gf_sql_connection_t  *sql_conn,
                     gfdb_db_record_t     *gfdb_db_record)
{

        int ret = -1;
        gfdb_time_t *modtime    = NULL;
        gf_boolean_t its_wind   = _gf_true;/*remains true for this function*/
        char *gfid_str = NULL;
        char *pargfid_str = NULL;

        CHECK_SQL_CONN (sql_conn, out);
        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, gfdb_db_record, out);

        gfid_str = gf_strdup (uuid_utoa(gfdb_db_record->gfid));
        if (!gfid_str) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_CREATE_FAILED, "Creating gfid string failed.");
                goto out;
        }

        /*Only update if recording unwind is set*/
        if (gfdb_db_record->do_record_times &&
                gfdb_db_record->do_record_uwind_time) {
                modtime = &gfdb_db_record->gfdb_unwind_change_time;
                ret = gf_update_time (sql_conn, gfid_str, modtime,
                        gfdb_db_record->do_record_counters,
                        (!its_wind),
                        isreadfop (gfdb_db_record->gfdb_fop_type));
                if (ret) {
                        gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                                LG_MSG_UPDATE_FAILED, "Failed update unwind "
                                "time in DB");
                        goto out;
                }
        }

        /*For link creation and changes we use link updated*/
        if (gfdb_db_record->islinkupdate &&
                isdentryfop(gfdb_db_record->gfdb_fop_type)) {

                pargfid_str = gf_strdup(uuid_utoa(gfdb_db_record->pargfid));
                if (!pargfid_str) {
                        gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                                LG_MSG_CREATE_FAILED,
                                "Creating pargfid_str string failed.");
                        goto out;
                }

                ret = gf_sql_update_link_flags (sql_conn, gfid_str, pargfid_str,
                                        gfdb_db_record->file_name, 0, _gf_true);
                if (ret) {
                        gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                                LG_MSG_UPDATE_FAILED, "Failed updating link "
                                "flags in unwind");
                        goto out;
                }
        }

        ret = 0;
out:
        GF_FREE (gfid_str);
        GF_FREE (pargfid_str);
        return ret;
}
static inline int
gf_sql_delete_all (gf_sql_connection_t *sql_conn,
                  char              *gfid)
{
        int ret = -1;
        sqlite3_stmt *delete_file_stmt = NULL;
        sqlite3_stmt *delete_link_stmt = NULL;
        char *delete_link_str = "DELETE FROM "
                           GF_FILE_LINK_TABLE
                           " WHERE GF_ID = ? ;";
        char *delete_file_str = "DELETE FROM "
                           GF_FILE_TABLE
                           " WHERE GF_ID = ? ;";

        CHECK_SQL_CONN (sql_conn, out);
        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, gfid, out);

        /*
         * Delete all links associated with this GFID
         *
         * */
        /*Prepare statement for delete all links*/
        ret = sqlite3_prepare(sql_conn->sqlite3_db_conn, delete_link_str, -1,
                                &delete_link_stmt, 0);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_PREPARE_FAILED, "Failed preparing delete "
                        "statment %s : %s", delete_link_str,
                        sqlite3_errmsg (sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

        /*Bind gfid*/
        ret = sqlite3_bind_text (delete_link_stmt, 1, gfid, -1, NULL);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_BINDING_FAILED, "Failed binding gfid %s : %s",
                        gfid, sqlite3_errmsg (sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }


        /*Execute the prepare statement*/
        if (sqlite3_step (delete_link_stmt) != SQLITE_DONE) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_EXEC_FAILED,
                        "Failed executing the prepared stmt %s : %s",
                        delete_link_str,
                        sqlite3_errmsg (sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }


        /*
         * Delete entry from file table associated with this GFID
         *
         * */
        /*Prepare statement for delete all links*/
        ret = sqlite3_prepare (sql_conn->sqlite3_db_conn, delete_file_str, -1,
                                &delete_file_stmt, 0);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_PREPARE_FAILED, "Failed preparing delete "
                        "statment %s : %s", delete_file_str,
                        sqlite3_errmsg (sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

        /*Bind gfid*/
        ret = sqlite3_bind_text (delete_file_stmt, 1, gfid, -1, NULL);
        if (ret != SQLITE_OK) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_BINDING_FAILED, "Failed binding gfid %s : %s",
                        gfid, sqlite3_errmsg (sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

        /*Execute the prepare statement*/
        if (sqlite3_step (delete_file_stmt) != SQLITE_DONE) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_EXEC_FAILED,
                        "Failed executing the prepared stmt %s : %s",
                        delete_file_str,
                        sqlite3_errmsg (sql_conn->sqlite3_db_conn));
                ret = -1;
                goto out;
        }

out:
        /*Free prepared statement*/
        sqlite3_finalize (delete_file_stmt);
        sqlite3_finalize (delete_link_stmt);
        return ret;
}
Beispiel #30
0
int
xlator_volopt_dynload (char *xlator_type, void **dl_handle,
                       volume_opt_list_t *opt_list)
{
        int                     ret = -1;
        char                    *name = NULL;
        void                    *handle = NULL;
        volume_opt_list_t       *vol_opt = NULL;

        GF_VALIDATE_OR_GOTO ("xlator", xlator_type, out);

        GF_ASSERT (dl_handle);

        if (*dl_handle)
                if (dlclose (*dl_handle))
                        gf_log ("xlator", GF_LOG_WARNING, "Unable to close "
                                  "previously opened handle( may be stale)."
                                  "Ignoring the invalid handle");

        ret = gf_asprintf (&name, "%s/%s.so", XLATORDIR, xlator_type);
        if (-1 == ret) {
                gf_log ("xlator", GF_LOG_ERROR, "asprintf failed");
                goto out;
        }

        ret = -1;

        gf_log ("xlator", GF_LOG_TRACE, "attempt to load file %s", name);

        handle = dlopen (name, RTLD_NOW|RTLD_GLOBAL);
        if (!handle) {
                gf_log ("xlator", GF_LOG_WARNING, "%s", dlerror ());
                goto out;
        }
        *dl_handle = handle;


        vol_opt = GF_CALLOC (1, sizeof (volume_opt_list_t),
                         gf_common_mt_volume_opt_list_t);

        if (!vol_opt) {
                goto out;
        }

        if (!(vol_opt->given_opt = dlsym (handle, "options"))) {
                dlerror ();
                gf_log ("xlator", GF_LOG_DEBUG,
                         "Strict option validation not enforced -- neglecting");
        }
        opt_list->given_opt = vol_opt->given_opt;

        INIT_LIST_HEAD (&vol_opt->list);
        list_add_tail (&vol_opt->list, &opt_list->list);

        ret = 0;
 out:
        GF_FREE (name);

        gf_log ("xlator", GF_LOG_DEBUG, "Returning %d", ret);
        return ret;

}