int File_GetStripeByPath( const char *entry_path, stripe_info_t * p_stripe_info, stripe_items_t * p_stripe_items ) { /* buffer used for llapi_get_stripe. * oversize it to 4kB because there can be many stripe entries * in the case of join'ed files. */ int rc; struct lov_user_md *p_lum; #ifdef LOV_USER_MAGIC_V3 struct lov_user_md_v3 *p_lum3; #endif unsigned int i; 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; } /* Check protocol version number */ if ( p_lum->lmm_magic == LOV_USER_MAGIC_V1 ) { if ( p_stripe_info ) { p_stripe_info->stripe_size = p_lum->lmm_stripe_size; p_stripe_info->stripe_count = p_lum->lmm_stripe_count; p_stripe_info->pool_name[0] = '\0'; } if ( p_stripe_items ) { p_stripe_items->count = p_lum->lmm_stripe_count; if ( p_lum->lmm_stripe_count > 0 ) { p_stripe_items->stripe_units = ( storage_unit_id_t * ) MemCalloc( p_lum->lmm_stripe_count, sizeof( storage_unit_id_t ) ); if (p_stripe_items->stripe_units == NULL) { rc = -ENOMEM; goto out_free; } /* fill OST ids */ for ( i = 0; i < p_lum->lmm_stripe_count; i++ ) { p_stripe_items->stripe_units[i] = p_lum->lmm_objects[i].l_ost_idx; } } else { p_stripe_items->stripe_units = NULL; } } rc = 0; goto out_free; } #ifdef LOV_USER_MAGIC_V3 else if ( p_lum->lmm_magic == LOV_USER_MAGIC_V3 ) { p_lum3 = ( struct lov_user_md_v3 * ) p_lum; if ( p_stripe_info ) { p_stripe_info->stripe_size = p_lum3->lmm_stripe_size; p_stripe_info->stripe_count = p_lum3->lmm_stripe_count; strncpy( p_stripe_info->pool_name, p_lum3->lmm_pool_name, LOV_MAXPOOLNAME ); p_stripe_info->pool_name[MAX_POOL_LEN-1] = 0; } if ( p_stripe_items ) { p_stripe_items->count = p_lum3->lmm_stripe_count; if ( p_lum3->lmm_stripe_count > 0 ) { p_stripe_items->stripe_units = ( storage_unit_id_t * ) MemCalloc( p_lum3->lmm_stripe_count, sizeof( storage_unit_id_t ) ); if (p_stripe_items->stripe_units == NULL) { rc = -ENOMEM; goto out_free; } /* fill OST ids */ for ( i = 0; i < p_lum3->lmm_stripe_count; i++ ) { p_stripe_items->stripe_units[i] = p_lum3->lmm_objects[i].l_ost_idx; } } else { p_stripe_items->stripe_units = NULL; } } rc = 0; goto out_free; } #endif else { DisplayLog( LVL_CRIT, TAG_STRIPE, "Unsupported Luster magic number for %s: %#X", entry_path, p_lum->lmm_magic ); rc = -EINVAL; goto out_free; } out_free: MemFree(p_lum); return rc; }
/** * Get the list of children of a given parent (or list of parents). * \param parent_list [in] list of parents to get the child of * \param parent_count [in] number of ids in parent list * \param attr_mask [in] required attributes for children * \param child_id_list [out] ptr to array of child ids * \param child_attr_list [out] ptr to array of child attrs * \param child_count [out] number of returned children */ int ListMgr_GetChild( lmgr_t * p_mgr, const lmgr_filter_t * p_filter, const wagon_t * parent_list, unsigned int parent_count, int attr_mask, wagon_t ** child_id_list, attr_set_t ** child_attr_list, unsigned int * child_count) { result_handle_t result; char *curr; int filter_main = 0; int filter_annex = 0; int main_attrs = 0; int dnames_attrs = 0; int annex_attrs = 0; char query[4096]; char fieldlist_main[1024] = ""; char fieldlist_dnames[1024] = ""; char fieldlist_annex[1024] = ""; char filter_str_main[1024] = ""; char filter_str_annex[1024] = ""; char tmp[2048]; char *path = NULL; int path_len; char * pc; int rc, i; /* TODO: querying children from several parent cannot work, since * we need to get the paths of the children. Or we could do a * lookup into parent_list to find the right one. In the meantime, * try not to mess up the code. */ if (parent_count != 1) RBH_BUG("cannot get children for several parent simultaneously"); /* always request for name to build fullpath in wagon */ attr_mask |= ATTR_MASK_name; /* request is always on the MAIN table (which contains [parent_id, id] relationship */ /* /!\ possible cases: * - simplest: the fields of the filter and the attributes to be retrieved are in the MAIN table * - harder: the fields of the filter and attributes are in a different table */ /* 1) location of filters */ if ( p_filter ) { char dummy_str[1024]; unsigned int dummy_uint; if (dir_filter(p_mgr, dummy_str, p_filter, &dummy_uint, NULL) != FILTERDIR_NONE) { DisplayLog( LVL_MAJOR, LISTMGR_TAG, "Directory filter not supported in %s()", __func__ ); return DB_NOT_SUPPORTED; } else if (func_filter(p_mgr, dummy_str, p_filter, T_MAIN, FALSE, FALSE)) { DisplayLog( LVL_MAJOR, LISTMGR_TAG, "Function filter not supported in %s()", __func__ ); return DB_NOT_SUPPORTED; } /* There is always a filter on T_DNAMES, which is the parent condition. * Look for optional filters: */ filter_main = filter2str( p_mgr, filter_str_main, p_filter, T_MAIN, FALSE, TRUE ); if ( annex_table ) filter_annex = filter2str( p_mgr, filter_str_annex, p_filter, T_ANNEX, FALSE, TRUE ); else filter_annex = 0; /* @TODO to be implemented */ #if 0 filter_stripe_info = filter2str( p_mgr, filter_str_stripe_info, p_filter, T_STRIPE_INFO, ( filter_main > 0 ) || ( filter_annex > 0 ), TRUE ); filter_stripe_items = filter2str( p_mgr, filter_str_stripe_items, p_filter, T_STRIPE_ITEMS, ( filter_main > 0 ) || ( filter_annex > 0 ) || ( filter_stripe_info > 0 ), TRUE ); #endif } /* 2) location of requested attributes */ if (attr_mask) { /* retrieve source info for generated fields */ add_source_fields_for_gen( &attr_mask ); main_attrs = attrmask2fieldlist( fieldlist_main, attr_mask, T_MAIN, /* leading comma */ TRUE, /* for update */ FALSE, /* prefix */ MAIN_TABLE".", /* postfix */ "" ); dnames_attrs += attrmask2fieldlist( fieldlist_dnames, attr_mask, T_DNAMES, /* leading comma */ TRUE, /* for update */ FALSE, /* prefix */ DNAMES_TABLE".", /* postfix */ "" ); if ( annex_table ) annex_attrs = attrmask2fieldlist( fieldlist_annex, attr_mask, T_ANNEX, /* leading comma */ TRUE, /* for update */ FALSE, /* prefix */ ANNEX_TABLE".", /* postfix */ "" ); else annex_attrs = 0; } else { /* no returned attrs */ if (child_attr_list) *child_attr_list = NULL; } pc = parent_cond(p_mgr, tmp, sizeof(tmp), parent_list, parent_count, DNAMES_TABLE"."); if (!pc) return DB_BUFFER_TOO_SMALL; curr = query; /* SELECT clause */ /* id + dname fields */ curr += sprintf(curr, "SELECT "DNAMES_TABLE".id%s", fieldlist_dnames); /* main attrs */ if (main_attrs) curr += sprintf(curr, "%s", fieldlist_main); /* annex attrs */ if (annex_attrs) curr += sprintf(curr, "%s", fieldlist_annex); /* FROM clause */ curr += sprintf(curr, " FROM "DNAMES_TABLE); if (main_attrs || filter_main) curr += sprintf(curr, " LEFT JOIN "MAIN_TABLE " ON "DNAMES_TABLE".id="MAIN_TABLE".id"); if (annex_attrs || filter_annex) curr += sprintf(curr, " LEFT JOIN "ANNEX_TABLE " ON "DNAMES_TABLE".id="ANNEX_TABLE".id"); /* WHERE clause */ curr += sprintf(curr, " WHERE %s", pc); if (filter_main) curr += sprintf(curr, " AND %s", filter_str_main); if (filter_annex) curr += sprintf(curr, " AND %s", filter_str_annex); retry: rc = db_exec_sql(&p_mgr->conn, query, &result); if (lmgr_delayed_retry(p_mgr, rc)) goto retry; else if (rc) return rc; /* copy result to output structures */ *child_count = db_result_nb_records(&p_mgr->conn, &result); /* allocate entry_id array */ *child_id_list = MemCalloc(*child_count, sizeof(wagon_t)); if (*child_id_list == NULL) return DB_NO_MEMORY; if (child_attr_list) { *child_attr_list = MemCalloc(*child_count, sizeof(attr_set_t)); if (*child_attr_list == NULL) { rc = DB_NO_MEMORY; goto array_free; } } /* Allocate a string long enough to contain the parent path and a * child name. */ path_len = strlen(parent_list[0].fullname) + RBH_NAME_MAX + 2; path = malloc(path_len); if (!path) { DisplayLog( LVL_MAJOR, LISTMGR_TAG, "Can't alloc enough memory (%d bytes)", path_len ); rc = DB_NO_MEMORY; goto array_free; } for (i = 0; i < *child_count; i++) { char *res[128]; /* 128 fields per row is large enough */ rc = db_next_record(&p_mgr->conn, &result, res, 128); if ( rc ) goto array_free; /* copy id to array */ pk2entry_id(p_mgr, res[0], &((*child_id_list)[i].id)); /* copy attributes to array */ if (child_attr_list) { (*child_attr_list)[i].attr_mask = attr_mask; /* first id, then dnames attrs, then main attrs, then annex attrs */ if (dnames_attrs) { /* shift of 1 for id */ rc = result2attrset( T_DNAMES, res + 1, dnames_attrs, &((*child_attr_list)[i]) ); if ( rc ) goto array_free; } if (main_attrs) { /* first id, then main attrs, then annex attrs */ /* shift of 1 for id */ rc = result2attrset( T_MAIN, res + dnames_attrs + 1, main_attrs, &((*child_attr_list)[i]) ); if ( rc ) goto array_free; } if (annex_attrs) { /* shift of main_attrs count */ rc = result2attrset( T_ANNEX, res + dnames_attrs + main_attrs + 1, annex_attrs, &((*child_attr_list)[i]) ); if ( rc ) goto array_free; } #ifdef _LUSTRE if (stripe_fields(attr_mask)) { if (get_stripe_info( p_mgr, res[0], &ATTR(&(*child_attr_list)[i], stripe_info), &ATTR(&(*child_attr_list)[i], stripe_items) )) { ATTR_MASK_UNSET(&(*child_attr_list)[i], stripe_info); ATTR_MASK_UNSET(&(*child_attr_list)[i], stripe_items); } } #endif generate_fields(&((*child_attr_list)[i])); /* Note: path is properly sized already to not overflow. */ sprintf(path, "%s/%s", parent_list[0].fullname, (*child_attr_list)[i].attr_values.name); (*child_id_list)[i].fullname = strdup(path); } } if (path) free(path); db_result_free( &p_mgr->conn, &result ); return 0; array_free: if (path) free(path); if (child_attr_list && *child_attr_list) { MemFree(*child_attr_list); *child_attr_list = NULL; } MemFree(*child_id_list); *child_id_list = NULL; return rc; }