int File_CreateSetStripe( const char * path, const stripe_info_t * old_stripe ) { int rc; /* try to restripe using previous pool name */ if ( !EMPTY_STRING( old_stripe->pool_name ) ) { rc = llapi_file_create_pool( path, old_stripe->stripe_size, -1, old_stripe->stripe_count, 0, (char *)old_stripe->pool_name ); if ( rc == 0 || rc == -EEXIST ) return rc; else { DisplayLog( LVL_MAJOR, TAG_CR_STRIPE, "Error %d creating '%s' in pool '%s': %s", rc, path, old_stripe->pool_name, strerror(-rc) ); DisplayLog( LVL_MAJOR, TAG_CR_STRIPE, "Trying to create it without pool information..." ); } } rc = llapi_file_create( path, old_stripe->stripe_size, -1, old_stripe->stripe_count, 0 ); if ( rc != 0 || rc == -EEXIST ) DisplayLog( LVL_MAJOR, TAG_CR_STRIPE, "Error %d creating '%s' with stripe. Trying to create it without specific stripe...", rc, path ); return rc; }
/** * Get status of entry regarding 'shook' system * and convert it to robinhood status. * @return 0 on success, <0 on error. */ int ShookGetStatus(const char *path, file_status_t *p_status) { shook_state st; int rc; if (shook_get_status(path, &st, FALSE) != 0) { rc = -errno; DisplayLog(LVL_CRIT, SHOOK_TAG, "ERROR getting state of %s: %s", path, strerror(-rc)); return rc; } if (st != SS_ONLINE) DisplayLog(LVL_FULL, SHOOK_TAG, "shook indicates '%s' status is '%s'", path, shook_attr_val[st]); *p_status = shook2rbh_status(st); if (*p_status == (file_status_t)-1) { DisplayLog(LVL_CRIT, SHOOK_TAG, "ERROR getting state of %s: unknown status %d", path, (int)st); return -EINVAL; } return 0; }
void *enqueue_thread( void *arg ) { int rc, i; entry_proc_op_t *new_op; for ( i = 0; i < NB_OP_ENQUEUE; i++ ) { new_op = EntryProcessor_Get( ); if ( !new_op ) { printf( "Error in EntryProcessor_Get\n"); return NULL; } /* initial stage */ new_op->pipeline_stage = entry_proc_pipeline[0].stage_index; #ifdef _LUSTRE_HSM new_op->extra_info.log_record.record_id = i; DisplayLog( LVL_FULL, "EnqueueThr", "Enqueuing record #%u", i ); #else sprintf( ATTR( &new_op->entry_attr, fullpath ), "/dir%u/file%d", ( unsigned int ) time( NULL ), i ); DisplayLog( LVL_FULL, "EnqueueThr", "Enqueuing file %s", ATTR( &new_op->entry_attr, fullpath ) ); #endif EntryProcessor_Push( new_op ); } }
int CreateStriped( const char * path, const stripe_info_t * old_stripe, int overwrite ) { int rc; /* try to restripe using previous pool name */ if ( !EMPTY_STRING( old_stripe->pool_name ) ) rc = llapi_file_create_pool( path, old_stripe->stripe_size, -1, old_stripe->stripe_count, 0, (char *)old_stripe->pool_name ); else rc = llapi_file_create( path, old_stripe->stripe_size, -1, old_stripe->stripe_count, 0 ); if ((rc == -EEXIST) && overwrite) { if (unlink(path)) { rc = -errno; DisplayLog( LVL_MAJOR, TAG_CR_STRIPE, "Can't remove previous entry %s: %s", path, strerror(-rc)); return rc; } return CreateStriped(path, old_stripe, false /*target not expected to exist*/); } else if ( rc != 0 && rc != -EEXIST ) { DisplayLog( LVL_MAJOR, TAG_CR_STRIPE, "Error %d creating '%s' with stripe.", rc, path ); } return rc; }
int File_GetStripeByDirFd( int dirfd, const char *fname, stripe_info_t * p_stripe_info, stripe_items_t * p_stripe_items ) { int rc = 0; char lum_buffer[4096]; struct lov_user_md *p_lum = ( struct lov_user_md * ) lum_buffer; if ( !fname|| !fname[0] ) return -EFAULT; memset( lum_buffer, 0, sizeof( lum_buffer ) ); strcpy((char *)p_lum, fname); if (ioctl(dirfd, IOC_MDC_GETFILESTRIPE, (void *)p_lum) == -1) rc = -errno; if ( rc != 0 ) { if ( rc == -ENODATA ) DisplayLog( LVL_DEBUG, TAG_STRIPE, "File %s has no stripe information", fname ); else if ( ( rc != -ENOENT ) && ( rc != -ESTALE ) ) DisplayLog( LVL_CRIT, TAG_STRIPE, "Error %d getting stripe info for %s", rc, fname ); return rc; } return fill_stripe_info(p_lum, p_stripe_info, p_stripe_items); }
/** * This removes the current reference to an id when the operation is removed. */ int id_constraint_unregister( entry_proc_op_t * p_op ) { unsigned int hash_index; id_constraint_item_t *p_curr; id_constraint_item_t *p_prev; if ( !p_op->entry_id_is_set ) return ID_MISSING; if ( !p_op->id_is_referenced ) return ID_NOT_EXISTS; /* compute id hash value */ hash_index = hash_id( &p_op->entry_id, ID_HASH_SIZE ); /* check if the entry id exists and is a stage >= pipeline_stage */ P( id_hash[hash_index].lock ); for ( p_curr = id_hash[hash_index].id_list_first, p_prev = NULL; p_curr != NULL; p_prev = p_curr, p_curr = p_curr->p_next ) { if ( p_curr->op_ptr == p_op ) { /* found */ if ( p_prev == NULL ) id_hash[hash_index].id_list_first = p_curr->p_next; else p_prev->p_next = p_curr->p_next; /* was it the last ? */ if ( id_hash[hash_index].id_list_last == p_curr ) id_hash[hash_index].id_list_last = p_prev; p_curr->op_ptr->id_is_referenced = FALSE; id_hash[hash_index].count--; V( id_hash[hash_index].lock ); /* free the slot */ MemFree( p_curr ); return ID_OK; } } V( id_hash[hash_index].lock ); #ifdef _HAVE_FID DisplayLog( LVL_MAJOR, ENTRYPROC_TAG, "id_constraint_unregister: op not found (list %u): id [%llu, %u] record %u", hash_index, p_op->entry_id.f_seq, p_op->entry_id.f_oid, p_op->entry_id.f_ver ); #else DisplayLog( LVL_MAJOR, ENTRYPROC_TAG, "id_constraint_unregister: op not found (list %u): id [dev %llu, ino %llu]", hash_index, ( unsigned long long ) p_op->entry_id.device, ( unsigned long long ) p_op->entry_id.inode ); #endif return ID_NOT_EXISTS; }
int File_GetStripeByPath( const char *entry_path, stripe_info_t * p_stripe_info, stripe_items_t * p_stripe_items ) { int rc; struct lov_user_md *p_lum; if ( !entry_path || !entry_path[0] ) return -EFAULT; p_lum = (struct lov_user_md *)MemAlloc(LUM_SIZE_MAX); if (!p_lum) return -ENOMEM; memset(p_lum, 0, LUM_SIZE_MAX); rc = llapi_file_get_stripe(entry_path, p_lum); if ( rc != 0 ) { if ( rc == -ENODATA ) DisplayLog( LVL_DEBUG, TAG_STRIPE, "File %s has no stripe information", entry_path ); else if ( ( rc != -ENOENT ) && ( rc != -ESTALE ) ) DisplayLog( LVL_CRIT, TAG_STRIPE, "Error %d getting stripe info for %s", rc, entry_path ); goto out_free; } rc = fill_stripe_info(p_lum, p_stripe_info, p_stripe_items); out_free: MemFree(p_lum); return rc; }
int Reload_Rmdir_Config( void *module_config ) { rmdir_config_t *conf = ( rmdir_config_t * ) module_config; /* parameters that can't be modified dynamically */ if (rmdir_config.nb_threads_rmdir != conf->nb_threads_rmdir ) DisplayLog( LVL_MAJOR, "RmdirConfig", RMDIR_PARAM_BLOCK "::nb_threads_rmdir changed in config file, but cannot be modified dynamically" ); if (rmdir_config.rmdir_queue_size != conf->rmdir_queue_size ) DisplayLog( LVL_MAJOR, "RmdirConfig", RMDIR_PARAM_BLOCK "::rmdir_queue_size changed in config file, but cannot be modified dynamically" ); /* dynamic parameters */ if (rmdir_config.runtime_interval != conf->runtime_interval ) { DisplayLog( LVL_EVENT, "RmdirConfig", RMDIR_PARAM_BLOCK "::runtime_interval updated: %"PRI_TT"->%"PRI_TT, rmdir_config.runtime_interval, conf->runtime_interval ); rmdir_config.runtime_interval = conf->runtime_interval; } return 0; }
/* Scan starter thread */ static void *scan_starter( void *arg ) { int rc; DisplayLog( LVL_VERB, FSSCAN_TAG, "Launching FS Scan starter thread" ); if ( fsscan_flags & FLAG_ONCE ) { rc = Robinhood_CheckScanDeadlines( ); if ( rc ) DisplayLog( LVL_CRIT, FSSCAN_TAG, "Error %d checking FS Scan status", rc ); pthread_exit( NULL ); return NULL; } /* not a one-shot mode */ while ( !terminate ) { rc = Robinhood_CheckScanDeadlines( ); if ( rc ) DisplayLog( LVL_CRIT, FSSCAN_TAG, "Error %d checking FS Scan status", rc ); /* attente de la boucle suivante */ rh_sleep( fs_scan_config.spooler_check_interval ); } return NULL; }
/* create client connection */ int db_connect( db_conn_t * conn ) { int rc; /* Connect to database */ rc = sqlite3_open( lmgr_config.db_config.filepath, conn ); if ( rc != 0 ) { if ( *conn ) { DisplayLog( LVL_CRIT, LISTMGR_TAG, "Failed to connect to SQLite DB (file %s): Error: %s", lmgr_config.db_config.filepath, sqlite3_errmsg( *conn ) ); } else { DisplayLog( LVL_CRIT, LISTMGR_TAG, "Failed to connect to SQLite DB (file %s): Error: %d", lmgr_config.db_config.filepath, rc ); } return DB_CONNECT_FAILED; } DisplayLog( LVL_FULL, LISTMGR_TAG, "Logged on to database successfully" ); set_cache_size( *conn ); return DB_SUCCESS; }
/** generate fields */ void generate_fields( attr_set_t * p_set ) { int i; int mask = 1; for ( i = 0; i < ATTR_COUNT; i++, mask <<= 1 ) { if ( ( p_set->attr_mask & mask) && (field_infos[i].flags & GENERATED) ) { void * src_data; void * tgt_data; if ( field_infos[i].gen_func == NULL ) { /* cannot generate a field without a function */ DisplayLog( LVL_DEBUG, LISTMGR_TAG, "generated field without generation function: %s", field_infos[i].field_name ); p_set->attr_mask &= ~mask; continue; } /* is it generated from another field ? */ if ( field_infos[i].gen_index != -1 ) { int src_mask = 1 << field_infos[i].gen_index; /* is source set? */ if ( (p_set->attr_mask & src_mask) == 0 ) { DisplayLog( LVL_FULL, LISTMGR_TAG, "Source info '%s' of generated field '%s' is not set " "in the database", field_infos[field_infos[i].gen_index].field_name, field_infos[i].field_name ); p_set->attr_mask &= ~mask; continue; } src_data = ( char * ) &p_set->attr_values + field_infos[field_infos[i].gen_index].offset; } else { /* nothing needed to generate it */ src_data = NULL; } tgt_data = ( char * ) &p_set->attr_values + field_infos[i].offset; if ( field_infos[i].gen_func( tgt_data, src_data ) != 0 ) p_set->attr_mask &= ~mask; else DisplayLog( LVL_FULL, LISTMGR_TAG, "Field '%s' auto-generated", field_infos[i].field_name ); } /* end if generated */ } /* end for attr list */ }
static int alerter_executor(struct sm_instance *smi, const char *implements, const policy_action_t *action, /* arguments for the action : */ const entry_id_t *p_id, attr_set_t *p_attrs, const action_params_t *params, post_action_e *what_after, db_cb_func_t db_cb_fn, void *db_cb_arg) { const char *val; const char *status_str = NULL; int rc = 0; bool alert = false; if (params == NULL) { DisplayLog(LVL_MAJOR, TAG, "Missing action parameters for 'alerter' status manager"); return -EINVAL; } val = rbh_param_get(params, "alert"); if (val == NULL) { DisplayLog(LVL_MAJOR, TAG, "Missing action parameter 'alert = yes/clear' for 'alerter' status manager"); return -EINVAL; } if (!strcasecmp(val, "clear")) { /* if the action succeed new status will be: clear */ status_str = alerter_status2str(STATUS_CLEAR); } else if (!strcasecmp(val, "raise")) { /* if the action succeed new status will be: alert */ status_str = alerter_status2str(STATUS_ALERT); alert = true; } else { DisplayLog(LVL_MAJOR, TAG, "Invalid value for 'alert' action parameter: 'raise' or 'clear' expected"); return -EINVAL; } /* set it now, at it may be modified by the specified function */ *what_after = PA_UPDATE; rc = action_helper(action, "alert", p_id, p_attrs, params, smi, NULL, what_after, db_cb_fn, db_cb_arg); if (rc) return rc; set_uint_info(smi, p_attrs, ATTR_LAST_CHECK, (unsigned int)time(NULL)); if (alert) set_uint_info(smi, p_attrs, ATTR_LAST_ALERT, (unsigned int)time(NULL)); return set_status_attr(smi, p_attrs, status_str); }
int execute_shell_command( const char * cmd, int argc, ... ) { #define SHCMD "ShCmd" va_list arglist; char cmdline[4096]; char argbuf[1024]; char * curr = cmdline; int rc, i; int exrc; curr += sprintf( cmdline, "%s", cmd ); va_start(arglist, argc); for (i = 0; i < argc; i++) curr += sprintf( curr, " %s", escape_shell_arg( va_arg(arglist, char *), argbuf )); va_end(arglist); curr += sprintf( curr, " %s", " >/dev/null 2>/dev/null"); DisplayLog(LVL_DEBUG, SHCMD, "Executing command: %s", cmdline); rc = system(cmdline); if ( WIFEXITED(rc) ) { const char * str_error; exrc = WEXITSTATUS(rc); if (exrc == 0) { DisplayLog(LVL_DEBUG, SHCMD, "Command successful"); return 0; } /* shell special return values */ if (exrc == 126) str_error = "permission problem or command is not an executable"; else if (exrc == 127) str_error = "command not found"; else if (exrc == 128) str_error = "invalid argument to exit"; else str_error = "external command exited"; DisplayLog( LVL_MAJOR, SHCMD, "ERROR: %s, error %d (cmdline=%s)", str_error, exrc, cmdline ); rc = -exrc; } else if (WIFSIGNALED(rc)) { DisplayLog( LVL_MAJOR, SHCMD, "ERROR: command terminated by signal %d. cmdline=%s", WTERMSIG(rc), cmdline ); rc = -EINTR; } return rc; }
/** * Insert a batch of entries into the database. * All entries must have the same attr mask. */ int ListMgr_BatchInsert(lmgr_t * p_mgr, entry_id_t ** p_ids, attr_set_t ** p_attrs, unsigned int count, int update_if_exists) { int rc; char buff[4096]; if (count == 0) return DB_SUCCESS; else if (p_ids == NULL || p_attrs == NULL) RBH_BUG("NULL pointer argument"); /* read only fields in info mask? */ if (readonly_attr_set & p_attrs[0]->attr_mask) { DisplayLog(LVL_MAJOR, LISTMGR_TAG, "Error: trying to insert read only values: attr_mask=%#x", readonly_attr_set & p_attrs[0]->attr_mask); return DB_INVALID_ARG; } /* retry the whole transaction when the error is retryable */ retry: /* We want insert operation set to be atomic */ rc = lmgr_begin(p_mgr); if (lmgr_delayed_retry(p_mgr, rc)) goto retry; else if (rc) return rc; rc = listmgr_batch_insert_no_tx(p_mgr, p_ids, p_attrs, count, update_if_exists); if (lmgr_delayed_retry(p_mgr, rc)) goto retry; else if (rc) { lmgr_rollback(p_mgr); DisplayLog(LVL_CRIT, LISTMGR_TAG, "DB query failed in %s line %d: code=%d: %s", __FUNCTION__, __LINE__, rc, db_errmsg(&p_mgr->conn, buff, 4096)); return rc; } rc = lmgr_commit(p_mgr); if (lmgr_delayed_retry(p_mgr, rc)) goto retry; /* success, count it */ if (!rc) { if (update_if_exists) p_mgr->nbop[OPIDX_UPDATE] += count; else p_mgr->nbop[OPIDX_INSERT] += count; } return rc; }
/* This code is an adaptation of llapi_mds_getfileinfo() in liblustreapi. * It is unused for now, but could be useful when SOM will be implemented. */ int lustre_mds_stat(char *fullpath, int parentfd, struct stat *inode) { /* this buffer must be large enough for handling filename */ char buffer[1024]; struct lov_user_mds_data *lmd = ( struct lov_user_mds_data * ) buffer; char *filename; int rc; /* sanity checks */ if ((fullpath == NULL) || (inode == NULL)) return EINVAL; filename = basename( fullpath ); if ( filename == NULL ) filename = fullpath; memset(lmd, 0, sizeof(buffer)); rh_strncpy(buffer, filename, strlen(filename) + 1); rc = ioctl(parentfd, IOC_MDC_GETFILEINFO, (void *)lmd); if ( rc ) { if ( errno == ENOTTY ) { /* ioctl is not supported, it is not a lustre fs. * Do the regular lstat(2) instead. */ rc = lstat( fullpath, inode ); if ( rc ) { DisplayLog( LVL_CRIT, TAG_MDSSTAT, "Error: %s: lstat failed for %s", __FUNCTION__, fullpath ); return rc; } } else if ( ( errno == ENOENT ) || ( errno == ESTALE ) ) { DisplayLog( LVL_MAJOR, TAG_MDSSTAT, "Warning: %s: %s does not exist", __FUNCTION__, fullpath ); return ENOENT; } else { DisplayLog(LVL_CRIT, TAG_MDSSTAT, "Error: %s: IOC_MDC_GETFILEINFO failed for %s: rc=%d, errno=%d", __FUNCTION__, fullpath, rc, errno); return rc; } } else *inode = lmd->lmd_st; return 0; }
/** Trigger a HSM action */ int LustreHSM_Action( enum hsm_user_action action, const entry_id_t * p_id, const char * hints, unsigned int archive_id ) { struct hsm_user_request * req; int data_len = 0; int rc; char * mpath; if ( hints != NULL ) data_len = strlen(hints)+1; req = llapi_hsm_user_request_alloc(1, data_len); if (!req) { rc = -errno; DisplayLog( LVL_CRIT, "HSMAction", "Cannot create HSM request: %s", strerror(-rc) ); return rc; } req->hur_request.hr_action = action; req->hur_request.hr_archive_id = archive_id; req->hur_user_item[0].hui_fid = *p_id; req->hur_user_item[0].hui_extent.offset = 0 ; /* XXX for now, always transfer entire file */ req->hur_user_item[0].hui_extent.length = -1LL; req->hur_request.hr_itemcount = 1; if ( hints != NULL ) { req->hur_request.hr_data_len = data_len; memcpy(hur_data(req), hints, data_len); } else { req->hur_request.hr_data_len = 0; } /* make tmp copy as llapi_hsm_request arg is not const */ mpath = strdup(get_mount_point(NULL)); rc = llapi_hsm_request(mpath, req); free(mpath); free(req); if (rc) DisplayLog( LVL_CRIT, "HSMAction", "ERROR performing HSM request(%s," " root=%s, fid="DFID"): %s", hsm_user_action2name(action), mpath, PFID(p_id), strerror(-rc) ); return rc; }
/** * Release resources associated to a single module. Note that the mod_list * is not resized. * * \param[in, out] mod Module descriptor to release * * \return 0 on success, negative error code on failure */ static int module_unload(rbh_module_t *mod) { if (mod->name != NULL) DisplayLog(LVL_DEBUG, MODULE_TAG, "Unloading module %s", mod->name); if (mod->sym_hdl == NULL) { DisplayLog(LVL_VERB, MODULE_TAG, "Module already unloaded, ignoring"); return 0; /* -EALREADY ? */ } dlclose(mod->sym_hdl); mod->sym_hdl = NULL; return 0; }
/** * External process termination handler. */ static void watch_child_cb(GPid pid, gint status, gpointer data) { struct exec_ctx *ctx = data; const char *err = ""; DisplayLog(LVL_DEBUG, TAG, "Child %d terminated with %d", pid, status); if (status != 0) { ctx->rc = child_status2errno(status, &err); DisplayLog(LVL_DEBUG, TAG, "Command failed (%d): %s", ctx->rc, err); } g_spawn_close_pid(pid); ctx_decref(ctx); }
/** * IO channel watcher. * Read one line from the current channel and forward it to the user function. * * Return true as long as the channel has to stay registered, false otherwise. */ static gboolean readline_cb(GIOChannel *channel, GIOCondition cond, gpointer ud) { struct io_chan_arg *args = ud; GError *error = NULL; gchar *line; gsize size; GIOStatus res; /* The channel is closed, no more data to read */ if (cond == G_IO_HUP) { g_io_channel_unref(channel); ctx_decref(args->exec_ctx); return false; } res = g_io_channel_read_line(channel, &line, &size, NULL, &error); if (res != G_IO_STATUS_NORMAL) { DisplayLog(LVL_MAJOR, TAG, "Cannot read from child: %s", error->message); g_error_free(error); g_io_channel_unref(channel); ctx_decref(args->exec_ctx); return false; } if (args->cb != NULL) args->cb(args->udata, line, size, args->ident); g_free(line); return true; }
int ListMgr_Insert(lmgr_t *p_mgr, entry_id_t *p_id, attr_set_t *p_info, int update_if_exists) { int rc; char buff[4096]; /* retry the whole transaction when the error is retryable */ retry: rc = lmgr_begin(p_mgr); if (lmgr_delayed_retry(p_mgr, rc)) goto retry; else if (rc) return rc; rc = listmgr_batch_insert_no_tx(p_mgr, &p_id, &p_info, 1, update_if_exists); if (lmgr_delayed_retry(p_mgr, rc)) goto retry; else if (rc) { lmgr_rollback(p_mgr); DisplayLog(LVL_CRIT, LISTMGR_TAG, "DB query failed in %s line %d: code=%d: %s", __FUNCTION__, __LINE__, rc, db_errmsg(&p_mgr->conn, buff, 4096)); return rc; } rc = lmgr_commit(p_mgr); if (lmgr_delayed_retry(p_mgr, rc)) goto retry; /* success, count it */ if (!rc) p_mgr->nbop[OPIDX_INSERT]++; return rc; }
/** Start FS Scan info collector */ int FSScan_Start( fs_scan_config_t *module_config, int flags, const char * partial_root ) { int rc; fs_scan_config = *module_config; fsscan_flags = flags; partial_scan_root = partial_root; if (partial_root) { /* check that partial_root is under FS root */ if (strncmp(global_config.fs_path, partial_scan_root, strlen(global_config.fs_path))) { DisplayLog( LVL_CRIT, FSSCAN_TAG, "ERROR scan root %s is not under fs root %s", partial_scan_root, global_config.fs_path ); return EINVAL; } } rc = Robinhood_InitScanModule(); if ( rc ) return rc; /* start a background thread */ pthread_attr_init( &starter_attr ); pthread_attr_setscope( &starter_attr, PTHREAD_SCOPE_SYSTEM ); if ( pthread_create( &scan_starter_thread, &starter_attr, scan_starter, NULL ) ) { return errno; } return 0; }
/* Initialize a stack of tasks */ int InitTaskStack( task_stack_t * p_stack ) { unsigned int index; int rc; /* initialize each level of the priority stack */ for ( index = 0; index <= MAX_TASK_DEPTH; index++ ) { p_stack->tasks_at_depth[index] = NULL; } /* no task waiting for now */ p_stack->max_task_depth = 0; /* initialize the lock and the semaphore for accessing the list */ pthread_mutex_init( &p_stack->stack_lock, NULL ); /* initially, no task available: sem=0 */ if ( ( rc = semaphore_init( &p_stack->sem_tasks, 0 ) ) ) { pthread_mutex_destroy( &p_stack->stack_lock ); DisplayLog( LVL_CRIT, FSSCAN_TAG, "ERROR initializing semaphore" ); return rc; } return 0; }
/** * extract relative path from full path */ int relative_path( const char * fullpath, const char * root, char * rel_path ) { size_t len; char rootcopy[1024]; /* copy root path */ strcpy(rootcopy, root); len = strlen(rootcopy); /* add '/' if needed */ if ( (len > 1) && (rootcopy[len-1] != '/') ) { rootcopy[len] = '/'; rootcopy[len+1] = '\0'; len++; } /* test if the full path starts with the same dirs */ if (strncmp(rootcopy, fullpath,len)) { DisplayLog( LVL_MAJOR, "RelPath", "ERROR: file path '%s' is not under filesystem root '%s'", fullpath, rootcopy ); return -EINVAL; } strcpy( rel_path, fullpath+len ); return 0; }
char *compar2str( filter_comparator_t compar ) { switch ( compar ) { case EQUAL: return "="; case NOTEQUAL: return "<>"; case LESSTHAN: return "<="; case MORETHAN: return ">="; case LESSTHAN_STRICT: return "<"; case MORETHAN_STRICT: return ">"; case LIKE: return " LIKE "; case UNLIKE: return " NOT LIKE "; default: DisplayLog( LVL_CRIT, LISTMGR_TAG, "Default sign for filter: should never happen !!!" ); return "="; } }
/* return 1 on success */ int parsedbtype( char *str_in, db_type_t type, db_type_u * value_out ) { int rc; switch ( type ) { case DB_ID: /* convert str to id */ rc = pk2entry_id( NULL, str_in, &value_out->val_id ); if (rc) return 0; return 1; case DB_TEXT: value_out->val_str = str_in; return 1; case DB_INT: return sscanf( str_in, "%d", &value_out->val_int ); case DB_UINT: return sscanf( str_in, "%u", &value_out->val_uint ); break; case DB_BIGINT: return sscanf( str_in, "%lld", &value_out->val_bigint ); break; case DB_BIGUINT: return sscanf( str_in, "%llu", &value_out->val_biguint ); break; case DB_BOOL: return sscanf( str_in, "%d", &value_out->val_bool ); default: DisplayLog( LVL_CRIT, LISTMGR_TAG, "Error: unknown type %d in %s", type, __FUNCTION__ ); return 0; } }
/** * Generate fields automatically from already existing fields, * and check the target mask is satisfied. */ int ListMgr_GenerateFields( attr_set_t * p_set, int target_mask ) { int save_mask = p_set->attr_mask; /* are there generated fields that are not set for the target */ if ( target_mask & ~p_set->attr_mask & gen_attr_set ) { /* try to generate missing fields */ p_set->attr_mask |= (target_mask & ~p_set->attr_mask & gen_attr_set); generate_fields( p_set ); /* still missing? */ if ( target_mask & ~p_set->attr_mask ) { DisplayLog( LVL_VERB, LISTMGR_TAG, "Field still missing (can't be generated): %#X", target_mask & ~p_set->attr_mask ); /* never leave the function with less info than when entering! */ p_set->attr_mask |= save_mask; return DB_ATTR_MISSING; } } /* never leave the function with less info than when entering! */ p_set->attr_mask |= save_mask; return DB_SUCCESS; }
int printdbtype( lmgr_t * p_mgr, char *str, db_type_t type, const db_type_u * value_ptr ) { char tmpstr[4096]; switch ( type ) { case DB_ID: /* convert id to str */ entry_id2pk( p_mgr, &value_ptr->val_id, FALSE, tmpstr ); return sprintf( str, DPK, tmpstr ); case DB_TEXT: /* escape special characters in value */ db_escape_string( &p_mgr->conn, tmpstr, 4096, value_ptr->val_str ); return sprintf( str, "'%s'", tmpstr ); case DB_INT: return sprintf( str, "%d", value_ptr->val_int ); case DB_UINT: return sprintf( str, "%u", value_ptr->val_uint ); case DB_BIGINT: return sprintf( str, "%lld", value_ptr->val_bigint ); case DB_BIGUINT: return sprintf( str, "%llu", value_ptr->val_biguint ); case DB_BOOL: if ( value_ptr->val_bool ) return sprintf( str, "1" ); else return sprintf( str, "0" ); default: DisplayLog( LVL_CRIT, LISTMGR_TAG, "Error: unknown type %d in %s", type, __FUNCTION__ ); return 0; } }
/** Creates and return a new hash table */ struct id_hash *id_hash_init(const unsigned int hash_size, bool use_lock) { unsigned int i; struct id_hash *hash; hash = MemAlloc(sizeof(struct id_hash) + hash_size * sizeof(struct id_hash_slot)); if (!hash) { DisplayLog(LVL_MAJOR, "Entry_Hash", "Can't allocate new hash table with %d slots", hash_size); } for (i = 0; i < hash_size; i++) { struct id_hash_slot *slot = &hash->slot[i]; if (use_lock) pthread_mutex_init(&slot->lock, NULL); rh_list_init(&slot->list); slot->count = 0; } hash->hash_size = hash_size; return hash; }
/** * print parent condition depending on parent list count: * parent_id == xxx or parent_id IN ( xxx, yyy, zzz ) * \return db error code */ static int append_parent_cond(lmgr_t *p_mgr, GString *str, const wagon_t *parent_list, unsigned int parent_count, const char *prefix) { DEF_PK(pk); if (unlikely(parent_count == 0)) { DisplayLog( LVL_MAJOR, LISTMGR_TAG, "Warning: parent list is empty in %s()", __func__ ); return DB_INVALID_ARG; } if (likely(parent_count == 1)) /* the only expected for now */ { entry_id2pk(&parent_list[0].id, PTR_PK(pk)); g_string_append_printf(str, "%sparent_id="DPK, prefix ? prefix : "", pk); } else { int i; g_string_append_printf(str, "%sparent_id IN (", prefix ? prefix : ""); for (i = 0; i < parent_count; i++) { entry_id2pk(&parent_list[i].id, PTR_PK(pk)); g_string_append_printf(str, "%s"DPK, (i == 0)? "":",", pk); } g_string_append(str,")"); } return DB_SUCCESS; }
/** * Build .lustre/fid path associated to a handle. */ int BuildFidPath( const entry_id_t * p_id, /* IN */ char *path ) /* OUT */ { char *curr = path; unsigned int mlen = 0; if ( !p_id || !path ) return EFAULT; /* filesystem root */ strcpy( path, get_mount_point(&mlen) ); curr += mlen; /* fid directory */ strcpy( curr, "/" FIDDIR "/" ); curr += FIDDIRLEN + 2; /* add fid string */ curr += sprintf( curr, DFID, PFID(p_id) ); #ifdef _DEBUG DisplayLog( LVL_FULL, TAG_FIDPATH, "FidPath=%s", path ); #endif return 0; }