/* * 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; }
/** * 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, ×tamp, &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; }
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; }
/** * 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; }
/** * __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; }
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; }
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; }
/* * 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; }
/** * __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; }
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; }
/** * _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; }
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; }
/** * __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; }
/** * __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; }
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; }
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; }