Example #1
0
/**
 * \retval DB_NOT_EXISTS if the recovery table does not exist
 */
int ListMgr_RecovStatus( lmgr_t * p_mgr, lmgr_recov_stat_t * p_stats )
{
    int  rc, i;
    result_handle_t result;
    char * status[3];

    /* test if a RECOVERY table already exist, and contains entries */
    rc = db_exec_sql_quiet( &p_mgr->conn, "SELECT recov_status,COUNT(*),SUM(size) FROM "RECOV_TABLE
                            " GROUP BY recov_status", &result );
    if (rc)
        return rc;

    /* table exists, fill status tab */
    p_stats->total = 0;
    for (i = 0; i < RS_COUNT; i++ )
    {
        p_stats->status_count[i] = 0;
        p_stats->status_size[i] = 0;
    }

    while ( (rc = db_next_record( &p_mgr->conn, &result, status, 3 ))
            != DB_END_OF_LIST )
    {
        long long cnt;
        uint64_t sz;
        if (rc)
            return rc;

        cnt = str2bigint( status[1] );
        if ( cnt == -1LL)
            return DB_INVALID_ARG;

        sz = str2size(  status[2] );
        if ( sz == -1LL)
            return DB_INVALID_ARG;

        p_stats->total += cnt;

        if ( status[0] != NULL )
        {
            int idx = str2int( status[0] );
            if ((idx >= RS_COUNT) || (idx == -1) )
                return DB_REQUEST_FAILED;
            p_stats->status_count[idx] = cnt;
            p_stats->status_size[idx] = sz;
        }
    }

    db_result_free( &p_mgr->conn, &result );
    return 0;
}
Example #2
0
int ListMgr_Exists(lmgr_t *p_mgr, const entry_id_t *p_id)
{
    GString        *req;
    int             rc;
    result_handle_t result;
    char           *str_count = NULL;
    DEF_PK(pk);
    int             retry_status;

    /* retrieve primary key */
    entry_id2pk(p_id, PTR_PK(pk));

    /* verify it exists in main table */
    req = g_string_new("SELECT id FROM " MAIN_TABLE " WHERE id=");
    g_string_append_printf(req, DPK, pk);

retry:
    /* execute the request (must return negative value on error) */
    rc = -db_exec_sql(&p_mgr->conn, req->str, &result);
    retry_status = lmgr_delayed_retry(p_mgr, -rc);
    if (retry_status == 1)
        goto retry;
    else if (retry_status == 2) {
        rc = -DB_RBH_SIG_SHUTDOWN;
        goto free_str;
    } else if (rc)
        goto free_str;

    rc = db_next_record(&p_mgr->conn, &result, &str_count, 1);
    if (rc == 0)
        rc = 1; /* return 1 if entry exists */
    else if (rc != DB_END_OF_LIST)
    {
        retry_status = lmgr_delayed_retry(p_mgr, -rc);
        if (retry_status == 1)
            goto retry;
        else if (retry_status == 2) {
            rc = -DB_RBH_SIG_SHUTDOWN;
            goto free_result;
        }
    }
    else
        rc = 0;

free_result:
    db_result_free(&p_mgr->conn, &result);

free_str:
    g_string_free(req, TRUE);
    return rc;
}
Example #3
0
int lmgr_get_var(db_conn_t *pconn, const char *varname, char *value, int bufsize)
{
    int             rc;
    result_handle_t result;
    char           *str_val = NULL;
    GString        *req = NULL;

    if (!varname || !value)
        return DB_INVALID_ARG;

    req = g_string_new("SELECT value FROM "VAR_TABLE" WHERE varname=");
    g_string_append_printf(req, "'%s'", varname);

    /* execute the request */
    rc = db_exec_sql(pconn, req->str, &result);
    if (rc)
        goto free_str;

    rc = db_next_record(pconn, &result, &str_val, 1);

    if (rc == DB_END_OF_LIST)
        rc = DB_NOT_EXISTS;

    if (rc)
        goto free_res;

    if (str_val == NULL)
    {
        rc = DB_REQUEST_FAILED;
        goto free_res;
    }

    /* copy the result */
    if (strlen(str_val) >= bufsize)
    {
        rc = DB_BUFFER_TOO_SMALL;
    }
    else
    {
        strcpy(value, str_val);
        rc = DB_SUCCESS;
    }

free_res:
    db_result_free(pconn, &result);
free_str:
    g_string_free(req, TRUE);
    return rc;
}
Example #4
0
/* Retrieve the FID from the database given the parent FID and the file name. */
int ListMgr_Get_FID_from_Path( lmgr_t * p_mgr, const entry_id_t * parent_fid,
                               const char *name, entry_id_t * fid)
{
    result_handle_t result;
    GString        *req = NULL;
    char            escaped[RBH_NAME_MAX*2+1];
    DEF_PK(pk);
    int rc;
    char            *str_info[1];
    int             retry_status;

    entry_id2pk(parent_fid, PTR_PK(pk));

    db_escape_string(&p_mgr->conn, escaped, sizeof(escaped), name);

    req = g_string_new("SELECT id FROM "DNAMES_TABLE" WHERE pkn=");
    g_string_append_printf(req, HNAME_FMT, pk, escaped);

retry:
    rc = db_exec_sql(&p_mgr->conn, req->str, &result);
    retry_status = lmgr_delayed_retry(p_mgr, rc);
    if (retry_status == 1)
        goto retry;
    else if (retry_status == 2) {
        rc = DB_RBH_SIG_SHUTDOWN;
        goto free_str;
    } else if (rc)
        goto free_str;

    rc = db_next_record(&p_mgr->conn, &result, str_info, 1);

    retry_status = lmgr_delayed_retry(p_mgr, rc);
    if (retry_status == 1)
        goto retry;
    else if (retry_status == 2) {
        rc = DB_RBH_SIG_SHUTDOWN;
        goto free_res;
    } else if (rc != DB_SUCCESS)
        goto free_res;

    rc = pk2entry_id(p_mgr, str_info[0], fid);

free_res:
    db_result_free(&p_mgr->conn, &result);
free_str:
    g_string_free(req, TRUE);
    return rc;
}
Example #5
0
int ListMgr_RecovGetNext( struct lmgr_iterator_t *p_iter,
                          entry_id_t * p_id,
                          attr_set_t * p_info,
                          recov_status_t * last_status )
{
    int            rc = 0;
    char          *result_tab[2+RECOV_FIELD_COUNT]; /* +2 for id and recov_status */
    DEF_PK(pk);
    int entry_disappeared = FALSE;

    do
    {
        entry_disappeared = FALSE;

        rc = db_next_record( &p_iter->p_mgr->conn, &p_iter->select_result,
                             result_tab, RECOV_FIELD_COUNT+2 );

        if ( rc )
            return rc;
        if ( result_tab[0] == NULL ) /* no id? */
            return DB_REQUEST_FAILED;

        if ( sscanf( result_tab[0], SPK, PTR_PK(pk) ) != 1 )
            return DB_REQUEST_FAILED;

        if ( result_tab[1] == NULL ) { /* no status */
            if (last_status)
                *last_status = -1;
        }
        else if (last_status)
            *last_status = str2int(result_tab[1]);

        /* retrieve entry id (except validator) */
        rc = pk2entry_id( p_iter->p_mgr, pk, p_id );

        /* /!\ If the entry disappeared from DB, we must go to next record */
        if ( rc == DB_NOT_EXISTS )
            entry_disappeared = TRUE;
        else if ( rc )
            return rc;

    }
    while ( entry_disappeared );        /* goto next record if entry desappered */

    return result2attrset( T_RECOV, result_tab + 2, RECOV_FIELD_COUNT, p_info );
}
Example #6
0
/* check that validator is matching for a given entry */
int ListMgr_CheckStripe( lmgr_t * p_mgr, const entry_id_t * p_id )
{
    char           query[1024];
    char          *res;
    result_handle_t result;
    int            rc = DB_SUCCESS;
    DEF_PK(pk);

    rc = entry_id2pk( p_mgr, p_id, FALSE, PTR_PK(pk) );
    if (rc)
        return rc;

    sprintf( query, "SELECT validator FROM " STRIPE_INFO_TABLE " WHERE id="DPK, pk );

    rc = db_exec_sql( &p_mgr->conn, query, &result );
    if ( rc )
        goto out;

    rc = db_next_record( &p_mgr->conn, &result, &res, 1 );

    if ( rc == DB_END_OF_LIST )
        rc = DB_NOT_EXISTS;

    if ( rc )
        goto res_free;

    if ( res == NULL )
    {
        rc = DB_ATTR_MISSING;
        goto res_free;
    }

    if ( atoi( res ) != VALID(p_id) )
    {
        delete_stipe_info( p_mgr, pk );
        rc = DB_OUT_OF_DATE;
    }
    else
        rc = DB_SUCCESS;

  res_free:
    db_result_free( &p_mgr->conn, &result );
  out:
    return rc;
}
Example #7
0
int ListMgr_GetNext( struct lmgr_iterator_t *p_iter, entry_id_t * p_id, attr_set_t * p_info )
{
    int            rc = 0;
    char          *idstr;
    DEF_PK(pk);

    int            entry_disappeared = FALSE;

    do
    {
        entry_disappeared = FALSE;

        rc = db_next_record( &p_iter->p_mgr->conn, &p_iter->select_result, &idstr, 1 );

        if ( rc )
            return rc;
        if ( idstr == NULL )
            return DB_REQUEST_FAILED;

        if ( sscanf( idstr, SPK, PTR_PK(pk) ) != 1 )
            return DB_REQUEST_FAILED;

        /* retrieve entry id (except validator) */
        rc = pk2entry_id( p_iter->p_mgr, pk, p_id );

        /* /!\ If the entry disappeared from DB, we must go to next record */
        if ( rc == DB_NOT_EXISTS )
            entry_disappeared = TRUE;
        else if ( rc )
            return rc;

        /* Idem */
        rc = listmgr_get_by_pk( p_iter->p_mgr, pk, p_info );
        if ( rc == DB_NOT_EXISTS )
            entry_disappeared = TRUE;

    }
    while ( entry_disappeared );        /* goto next record if entry desappered */

    return rc;

}
Example #8
0
int ListMgr_Exists( lmgr_t * p_mgr, const entry_id_t * p_id )
{
    char           request[4096];
    int            rc;
    result_handle_t result;
    char          *str_count = NULL;
    DEF_PK( pk );

    /* retrieve primary key */
    entry_id2pk(p_id, PTR_PK(pk));

    /* verify it exists in main table */

    sprintf( request, "SELECT id FROM " MAIN_TABLE " WHERE id="DPK, pk );

retry:
    /* execute the request */
    rc = db_exec_sql(&p_mgr->conn, request, &result);
    if (lmgr_delayed_retry(p_mgr, rc))
        goto retry;
    else if (rc)
        return -rc;

    rc = db_next_record( &p_mgr->conn, &result, &str_count, 1 );
    if (rc == 0)
        rc = 1;
    else if (rc != DB_END_OF_LIST)
    {
        if (lmgr_delayed_retry(p_mgr, rc))
            goto retry;
        rc = -rc;
    }
    else
        rc = 0;

    db_result_free( &p_mgr->conn, &result );
    return rc;
}
Example #9
0
/* Retrieve the FID from the database given the parent FID and the file name. */
int ListMgr_Get_FID_from_Path( lmgr_t * p_mgr, const entry_id_t * parent_fid,
                               const char *name, entry_id_t * fid)
{
    result_handle_t result;
    char           query[4096];
    char           escaped[RBH_NAME_MAX*2];
    DEF_PK(pk);
    int rc;
    char            *str_info[1];

    entry_id2pk(parent_fid, PTR_PK(pk));

    db_escape_string(&p_mgr->conn, escaped, RBH_NAME_MAX*2, name);

    sprintf(query, "SELECT id FROM "DNAMES_TABLE" WHERE pkn="HNAME_FMT,
            pk, escaped);

retry:
    rc = db_exec_sql(&p_mgr->conn, query, &result);
    if (lmgr_delayed_retry(p_mgr, rc))
        goto retry;
    else if (rc)
        return rc;

    rc = db_next_record( &p_mgr->conn, &result, str_info, 1 );

    if (lmgr_delayed_retry(p_mgr, rc))
        goto retry;
    else if (rc != DB_SUCCESS)
        goto free_res;

    rc = pk2entry_id(p_mgr, str_info[0], fid);

  free_res:
    db_result_free( &p_mgr->conn, &result );
    return rc;
}
Example #10
0
int ListMgr_EntryCount(lmgr_t * p_mgr, uint64_t *count)
{
    int            rc;
    result_handle_t result;
    char          *str_count = NULL;

    /* execute the request */
retry:
    rc = db_exec_sql( &p_mgr->conn, "SELECT COUNT(*) FROM " MAIN_TABLE, &result );
    if (lmgr_delayed_retry(p_mgr, rc))
        goto retry;
    else if (rc)
        return rc;

    rc = db_next_record( &p_mgr->conn, &result, &str_count, 1 );
    if (rc)
        return rc;

    if ( sscanf( str_count, "%"SCNu64, count ) != 1 )
        rc = DB_REQUEST_FAILED;

    db_result_free( &p_mgr->conn, &result );
    return rc;
}
Example #11
0
/**
 * 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,
                     attr_mask_t attr_mask,
                     wagon_t **child_id_list, attr_set_t **child_attr_list,
                     unsigned int *child_count)
{
    result_handle_t result;
    char *path = NULL;
    int path_len;
    int                rc, i;
    GString           *req = NULL;
    GString           *fields = NULL;
    GString           *from = NULL;
    GString           *where = NULL;
    struct field_count field_cnt = {0};
    struct field_count filter_cnt = {0};
    table_enum         query_tab = T_DNAMES;
    bool               distinct = false;
    int                retry_status;

    /* XXX: 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 (unlikely(parent_count != 1))
        RBH_BUG("cannot get children for several parent simultaneously");

    /* always request for name to build fullpath in wagon */
    attr_mask_set_index(&attr_mask, ATTR_INDEX_name);

    fields = g_string_new(NULL);

    /* append fields for all tables */
    if (!attr_mask_is_null(attr_mask))
    {
        /* retrieve source info for generated fields */
        add_source_fields_for_gen(&attr_mask.std);

        field_cnt.nb_names = attrmask2fieldlist(fields, attr_mask, T_DNAMES,
                                                DNAMES_TABLE".", "",
                                                AOF_LEADING_SEP);

        field_cnt.nb_main = attrmask2fieldlist(fields, attr_mask, T_MAIN,
                                               MAIN_TABLE".", "",
                                               AOF_LEADING_SEP);

        field_cnt.nb_annex = attrmask2fieldlist(fields, attr_mask, T_ANNEX,
                                                ANNEX_TABLE".", "",
                                                AOF_LEADING_SEP);
    }
    else
    {
        /* no returned attrs */
        if (child_attr_list != NULL)
            *child_attr_list = NULL;
    }

    where = g_string_new(NULL);

    /* starts with condition on parent */
    rc = append_parent_cond(p_mgr, where, parent_list, parent_count, DNAMES_TABLE".");
    if (rc != DB_SUCCESS)
        goto free_str;

    /* check filters on other tables */
    if (!no_filter(p_filter))
    {
        if (unlikely(dir_filter(p_mgr, NULL, p_filter, NULL, NULL) != FILTERDIR_NONE))
        {
            DisplayLog(LVL_MAJOR, LISTMGR_TAG, "Directory filter not supported in %s()", __func__);
            rc = DB_NOT_SUPPORTED;
            goto free_str;
        }
        else if (unlikely(func_filter(p_mgr, NULL, p_filter, T_MAIN, 0)))
        {
            DisplayLog(LVL_MAJOR, LISTMGR_TAG, "Function filter not supported in %s()", __func__);
            rc = DB_NOT_SUPPORTED;
            goto free_str;
        }

        /* There is always a filter on T_DNAMES, which is the parent condition.
         * Look for optional filters.
         */
        filter_where(p_mgr, p_filter, &filter_cnt, where,
                     AOF_LEADING_SEP | AOF_SKIP_NAME);
        /** @FIXME process other filters on NAMES */
    }

    from = g_string_new(DNAMES_TABLE);

    /* add filter_count + field_count to build the FROM clause.
     * Preserve field count which is needed to interpret the result.
     */
    filter_cnt.nb_main += field_cnt.nb_main;
    filter_cnt.nb_annex += field_cnt.nb_annex;
    filter_cnt.nb_names += field_cnt.nb_names;
    /* query tab is DNAMES, skip_name=true, is_first_tab=T_DNAMES */
    filter_from(p_mgr, &filter_cnt, from, &query_tab, &distinct,
                AOF_LEADING_SEP | AOF_SKIP_NAME);

    /* request is always on the DNAMES table (which contains [parent_id, id] relationship */
    if (distinct)
        req = g_string_new("SELECT DISTINCT("DNAMES_TABLE".id) as id");
    else
        req = g_string_new("SELECT "DNAMES_TABLE".id as id");

    /* build the whole request */
    g_string_append_printf(req, "%s FROM %s WHERE %s", fields->str, from->str, where->str);

retry:
    rc = db_exec_sql(&p_mgr->conn, req->str, &result);
    retry_status = lmgr_delayed_retry(p_mgr, rc);
    if (retry_status == 1)
        goto retry;
    else if (retry_status == 2) {
        rc = DB_RBH_SIG_SHUTDOWN;
        goto free_str;
    } else if (rc)
        goto free_str;

    /* 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)
    {
        rc = DB_NO_MEMORY;
        goto free_str;
    }

    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 record is large enough */

        rc = db_next_record(&p_mgr->conn, &result, res, sizeof(res)/sizeof(*res));
        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)
        {
            unsigned int shift = 1; /* first was NAMES.id */

            (*child_attr_list)[i].attr_mask = attr_mask;

            /* first id, then dnames attrs, then main attrs, then annex attrs */
            if (field_cnt.nb_names > 0)
            {
                /* shift of 1 for id */
                rc = result2attrset(T_DNAMES, res + shift, field_cnt.nb_names, &((*child_attr_list)[i]));
                if (rc)
                    goto array_free;
                shift += field_cnt.nb_names;
            }

            if (field_cnt.nb_main > 0)
            {
                /* first id, then main attrs, then annex attrs */
                /* shift of 1 for id */
                rc = result2attrset(T_MAIN, res + shift, field_cnt.nb_main, &((*child_attr_list)[i]));
                if (rc)
                    goto array_free;
                shift += field_cnt.nb_main;
            }

            if (field_cnt.nb_annex > 0)
            {
                /* shift of main_attrs count */
                rc = result2attrset(T_ANNEX, res + shift, field_cnt.nb_annex,
                                     &((*child_attr_list)[i]));
                if (rc)
                    goto array_free;
                shift += field_cnt.nb_annex;
            }

#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. */
            snprintf(path, path_len, "%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);
    g_string_free(req, TRUE);
    g_string_free(fields, TRUE);
    g_string_free(from, TRUE);
    g_string_free(where, TRUE);
    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;
free_str:
    g_string_free(req, TRUE);
    g_string_free(fields, TRUE);
    g_string_free(from, TRUE);
    g_string_free(where, TRUE);
    return rc;
}
Example #12
0
int get_stripe_info( lmgr_t * p_mgr, PK_ARG_T pk, stripe_info_t * p_stripe_info,
                     stripe_items_t * p_items )
{
    char           query[1024];
    char          *res[3];
    result_handle_t result;
    int            i;
    int            rc = DB_SUCCESS;

    /* retrieve basic stripe info */
    sprintf( query,
             "SELECT stripe_count, stripe_size, pool_name FROM " STRIPE_INFO_TABLE " WHERE id="DPK,
             pk );

    rc = db_exec_sql( &p_mgr->conn, query, &result );
    if ( rc )
        goto out;

    rc = db_next_record( &p_mgr->conn, &result, res, 3 );
    if ( rc == DB_END_OF_LIST )
        rc = DB_NOT_EXISTS;
    if ( rc )
        goto res_free;

    if ( res[0] == NULL || res[1] == NULL || res[2] == NULL )
    {
        rc = DB_ATTR_MISSING;
        goto res_free;
    }

    p_stripe_info->stripe_count = atoi( res[0] );
    p_stripe_info->stripe_size = atoi( res[1] );
    strncpy( p_stripe_info->pool_name, res[2], MAX_POOL_LEN );

    db_result_free( &p_mgr->conn, &result );

    if ( p_items )
    {
        /* retrieve stripe list */
        sprintf( query, "SELECT storage_item FROM " STRIPE_ITEMS_TABLE " WHERE id="DPK, pk );

        rc = db_exec_sql( &p_mgr->conn, query, &result );
        if ( rc )
            goto out;

        if ( p_stripe_info->stripe_count != db_result_nb_records( &p_mgr->conn, &result ) )
        {
            DisplayLog( LVL_MAJOR, LISTMGR_TAG,
                        "Warning: the number of stripe items (%d) doesn't match stripe count (%u)! (Pk="DPK")",
                        db_result_nb_records( &p_mgr->conn, &result ), p_stripe_info->stripe_count, pk );
        }
        p_items->count = db_result_nb_records( &p_mgr->conn, &result );

        if ( p_items->count > 0 )
        {

            /* allocate stripe array */
            p_items->stripe_units = MemCalloc( p_items->count, sizeof( storage_unit_id_t ) );

            if ( !p_items->stripe_units )
            {
                rc = DB_NO_MEMORY;
                goto res_free;
            }

            /* fill stripe units */
            for ( i = 0; i < p_items->count; i++ )
            {
                rc = db_next_record( &p_mgr->conn, &result, res, 1 );
                if ( rc )
                    goto stripe_free;

                if ( res[0] == NULL )
                {
                    rc = DB_ATTR_MISSING;
                    goto stripe_free;
                }

                p_items->stripe_units[i] = atoi( res[0] );
            }
        }
        else
            p_items->stripe_units = NULL;

        /* last query result must be freed */
        rc = DB_SUCCESS;
        goto res_free;
    }

    /* nothing to free */
    return DB_SUCCESS;

    stripe_free:
    MemFree( p_items->stripe_units );
    p_items->stripe_units = NULL;
    p_items->count = 0;
    p_stripe_info->stripe_count = 0;
    res_free:
    db_result_free( &p_mgr->conn, &result );
    out:
    return rc;
}
Example #13
0
/**
 * 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) != 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;
}
Example #14
0
/** retrieve directory attributes (nbr of entries, avg size of entries)*/
int listmgr_get_dirattrs( lmgr_t * p_mgr, PK_ARG_T dir_pk, attr_set_t * p_attrs )
{
    GString         *req;
    result_handle_t  result;
    char            *str_info[1];
    int              rc = 0;
    int              tmp_val;
    long long        tmp_long;

    if (ATTR_MASK_TEST(p_attrs, type) &&
        (strcmp(ATTR(p_attrs, type), STR_TYPE_DIR) != 0))
    {
        DisplayLog(LVL_FULL, LISTMGR_TAG,
                   "Type='%s' != 'dir' => unsetting dirattrs in attr mask",
                   ATTR(p_attrs, type));
        p_attrs->attr_mask = attr_mask_and_not(&p_attrs->attr_mask, &dir_attr_set);
        return 0;
    }

    req = g_string_new(NULL);

    /* get child entry count from DNAMES_TABLE */
    if (ATTR_MASK_TEST(p_attrs, dircount))
    {
        g_string_printf(req, "SELECT %s FROM "DNAMES_TABLE" WHERE parent_id="DPK,
                        dirattr2str(ATTR_INDEX_dircount), dir_pk);

        rc = db_exec_sql(&p_mgr->conn, req->str, &result);
        if (rc)
            goto free_str;

        rc = db_next_record(&p_mgr->conn, &result, str_info, 1);
        if (rc == DB_END_OF_LIST)
        {
            ATTR_MASK_UNSET(p_attrs, dircount);
            rc = DB_SUCCESS;
        }
        else if (rc == DB_SUCCESS)
        {
            if (str_info[0] == NULL)
                /* count(*) should at least return 0 */
                rc = DB_REQUEST_FAILED;
            else
            {
                tmp_val = str2int(str_info[0]);
                if (tmp_val != -1)
                {
                    ATTR_MASK_SET(p_attrs, dircount);
                    ATTR(p_attrs, dircount) = tmp_val;
                    rc = DB_SUCCESS;
                }
                else
                    /* invalid output format */
                    rc = DB_REQUEST_FAILED;
            }
        }
        db_result_free(&p_mgr->conn, &result);
        if (rc)
            goto free_str;
    }

    /* get avgsize of child entries from MAIN_TABLE */
    if (ATTR_MASK_TEST(p_attrs, avgsize))
    {
        g_string_printf(req, "SELECT %s FROM "MAIN_TABLE" m, "DNAMES_TABLE" d"
                        " WHERE m.id = d.id and type='file' and d.parent_id="DPK,
                        dirattr2str(ATTR_INDEX_avgsize), dir_pk);

        rc = db_exec_sql(&p_mgr->conn, req->str, &result);
        if (rc)
            goto free_str;

        rc = db_next_record(&p_mgr->conn, &result, str_info, 1);
        if (rc == DB_END_OF_LIST)
            ATTR_MASK_UNSET(p_attrs, avgsize);
        else if (rc == DB_SUCCESS)
        {
            if (str_info[0] == NULL)
            {
                /* NULL if no entry matches the criteria */
                ATTR_MASK_UNSET(p_attrs, avgsize);
                rc = DB_SUCCESS;
            }
            else
            {
                tmp_long = str2bigint(str_info[0]);
                if (tmp_long != -1LL)
                {
                    ATTR_MASK_SET(p_attrs, avgsize);
                    ATTR(p_attrs, avgsize) = tmp_long;
                    rc = DB_SUCCESS;
                }
                else
                    /* invalid output format */
                    rc = DB_REQUEST_FAILED;
            }
        }
        db_result_free(&p_mgr->conn, &result);
    }

free_str:
    g_string_free(req, TRUE);
    return rc;
}
Example #15
0
/**
 * Get next report entry.
 * @param p_value_count is IN/OUT parameter. IN: size of output array. OUT: nbr of fields set in array.
 * @param p_profile OUT: output profile, if required.
 */
int ListMgr_GetNextReportItem(struct lmgr_report_t *p_iter,
                              db_value_t *p_value, unsigned int *p_value_count,
                              profile_u *p_profile)
{
    int rc;
    unsigned int i;

    if (*p_value_count <
        p_iter->result_count - p_iter->profile_count - p_iter->ratio_count)
        return DB_BUFFER_TOO_SMALL;

    if (p_iter->str_tab == NULL) {
        p_iter->str_tab =
            (char **)MemCalloc(p_iter->result_count, sizeof(char *));
        if (!p_iter->str_tab)
            return DB_NO_MEMORY;
    }

    rc = db_next_record(&p_iter->p_mgr->conn, &p_iter->select_result,
                        p_iter->str_tab, p_iter->result_count);

    if (rc)
        return rc;

    /* parse result values */
    for (i = 0;
         i < p_iter->result_count - p_iter->profile_count - p_iter->ratio_count;
         i++) {
        if (p_iter->str_tab[i] != NULL) {
            p_value[i].type = p_iter->result[i].type;
            if (parsedbtype(p_iter->str_tab[i], p_iter->result[i].type,
                            &(p_value[i].value_u)) != 1) {
                DisplayLog(LVL_CRIT, LISTMGR_TAG,
                           "Could not parse result field #%u: value='%s'", i,
                           p_iter->str_tab[i]);
                return DB_INVALID_ARG;
            }
            if (p_iter->result[i].flags & SEPD_LIST)
                separated_db2list_inplace((char *)p_value[i].value_u.val_str);
        } else {
            p_value[i].type = DB_TEXT;
            p_value[i].value_u.val_str = NULL;
        }
    }

    /* fill profile structure */
    if (p_profile && (p_iter->profile_count > 0)) {
        if (p_iter->profile_attr == ATTR_INDEX_size) {
            db_type_u dbval;
            for (i = 0; i < p_iter->profile_count; i++) {
                unsigned int idx = p_iter->result_count - p_iter->profile_count
                    - p_iter->ratio_count + i;
                if (p_iter->str_tab[idx] == NULL) {
                    p_profile->size.file_count[i] = 0;
                } else
                    if (parsedbtype
                        (p_iter->str_tab[idx], p_iter->result[idx].type,
                         &dbval) == 1) {
                    p_profile->size.file_count[i] = dbval.val_biguint;
                } else {
                    DisplayLog(LVL_CRIT, LISTMGR_TAG,
                               "Could not parse result field #%u: value='%s'",
                               idx, p_iter->str_tab[idx]);
                    return DB_INVALID_ARG;
                }
            }
        }
    }

    *p_value_count =
        p_iter->result_count - p_iter->profile_count - p_iter->ratio_count;

    return DB_SUCCESS;
}
Example #16
0
/**
 *  Retrieve entry attributes from its primary key
 */
int listmgr_get_by_pk( lmgr_t * p_mgr, PK_ARG_T pk, attr_set_t * p_info )
{
    int             rc;
    char           *first_table = NULL;
    GString        *req, *from;
    /* attribute count is up to 1 per bit (8 per byte).
     * x2 for bullet proofing */
    char           *result_tab[2*8*sizeof(p_info->attr_mask)];
    result_handle_t result;
    bool            checkmain   = true;
    int             main_count  = 0,
                    annex_count = 0,
                    name_count  = 0;
    attr_mask_t     gen = gen_fields(p_info->attr_mask);

    if (p_info == NULL)
        return 0;

    /* init entry info */
    memset(&p_info->attr_values, 0, sizeof(entry_info_t));
    req = g_string_new("SELECT ");
    from = g_string_new(" FROM ");

    /* retrieve source info for generated fields (only about std fields)*/
    add_source_fields_for_gen(&p_info->attr_mask.std);

    /* don't get fields that are not in main, names, annex, stripe...
     * This allows the caller to set all bits 'on' to get everything.
     * Note: this also clear generated fields. They will be restored after.
     */
    supported_bits_only(&p_info->attr_mask);

    /* get info from main table (if asked) */
    main_count = attrmask2fieldlist(req, p_info->attr_mask, T_MAIN, "", "", 0);
    if (main_count < 0)
    {
        rc = -main_count;
        goto free_str;
    }
    else if (main_count > 0)
    {
        checkmain = false;
        first_table = MAIN_TABLE;
        g_string_append(from, MAIN_TABLE);
    }

    annex_count = attrmask2fieldlist(req, p_info->attr_mask, T_ANNEX, "", "",
                                     first_table != NULL ? AOF_LEADING_SEP : 0);
    if (annex_count < 0)
    {
        rc = -annex_count;
        goto free_str;
    }
    else if (annex_count > 0)
    {
        if (first_table != NULL)
            g_string_append_printf(from, " LEFT JOIN "ANNEX_TABLE" ON %s.id="
                                   ANNEX_TABLE".id", first_table);
        else
        {
            first_table = ANNEX_TABLE;
            g_string_append(from, ANNEX_TABLE);
        }
    }

    name_count = attrmask2fieldlist(req, p_info->attr_mask, T_DNAMES, "", "",
                                    first_table != NULL ? AOF_LEADING_SEP : 0);
    if (name_count < 0)
    {
        rc = -name_count;
        goto free_str;
    }
    else if (name_count > 0)
    {
        if (first_table)
            /* it's OK to JOIN with NAMES table here even if there are multiple paths,
             * as we only take one result record. The important thing is to return
             * consistent values for parent_id, name and fullpath. */
            g_string_append_printf(from, " LEFT JOIN "DNAMES_TABLE" ON %s.id="
                                   DNAMES_TABLE".id", first_table);
        else
        {
            first_table = DNAMES_TABLE;
            g_string_append(from, DNAMES_TABLE);
        }
    }

    if (first_table != NULL)
    {
        int shift = 0;

        g_string_append_printf(req, "%s WHERE %s.id="DPK, from->str,
                               first_table, pk);

        rc = db_exec_sql(&p_mgr->conn, req->str, &result);
        if (rc)
            goto free_str;

        rc = db_next_record(&p_mgr->conn, &result, result_tab,
                            main_count + annex_count + name_count);
        /* END_OF_LIST means it does not exist */
        if (rc == DB_END_OF_LIST)
        {
            clean_std_table_bits(&p_info->attr_mask);

            /* not found, but did not check MAIN yet */
            if (checkmain)
                goto next_table;

            rc = DB_NOT_EXISTS;
        }
        if (rc)
            goto free_res;

        /* set info from result */
        if (main_count)
        {
            rc = result2attrset(T_MAIN, result_tab + shift, main_count, p_info);
            shift += main_count;
            if (rc)
                goto free_res;
        }
        if (annex_count)
        {
            rc = result2attrset(T_ANNEX, result_tab + shift, annex_count,
                                p_info);
            shift += annex_count;
            if (rc)
                goto free_res;
        }
        if (name_count)
        {
            rc = result2attrset(T_DNAMES, result_tab + shift, name_count,
                                p_info);
            shift += name_count;
            if (rc)
                goto free_res;
        }

next_table:
        db_result_free(&p_mgr->conn, &result);
    }

    /* remove stripe info if it is not a file */
    if (stripe_fields(p_info->attr_mask) && ATTR_MASK_TEST(p_info, type)
        && strcmp(ATTR(p_info, type), STR_TYPE_FILE) != 0)
    {
        p_info->attr_mask = attr_mask_and_not(&p_info->attr_mask, &stripe_attr_set);
    }

    /* get stripe info if asked */
#ifdef _LUSTRE
    if (stripe_fields(p_info->attr_mask))
    {
        rc = get_stripe_info(p_mgr, pk, &ATTR(p_info, stripe_info),
                             ATTR_MASK_TEST(p_info, stripe_items)?
                                &ATTR(p_info, stripe_items) : NULL);
        if (rc == DB_ATTR_MISSING || rc == DB_NOT_EXISTS)
        {
            /* stripe info is in std mask */
            p_info->attr_mask.std &= ~ATTR_MASK_stripe_info;

            if (ATTR_MASK_TEST(p_info, stripe_items))
                p_info->attr_mask.std &= ~ATTR_MASK_stripe_items;
        }
        else if (rc)
            goto free_str;
        else
            checkmain = false; /* entry exists */
    }
#else
    /* POSIX: always clean stripe bits */
    p_info->attr_mask = attr_mask_and_not(&p_info->attr_mask, &stripe_attr_set);
#endif

    /* special field dircount */
    if (dirattr_fields(p_info->attr_mask))
    {
        if (listmgr_get_dirattrs(p_mgr, pk, p_info))
        {
            DisplayLog(LVL_MAJOR, LISTMGR_TAG, "listmgr_get_dirattrs failed for "DPK, pk);
            p_info->attr_mask = attr_mask_and_not(&p_info->attr_mask, &dir_attr_set);
        }
    }

    if (checkmain)
    {
        /* verify it exists in main table */
        g_string_printf(req, "SELECT id FROM " MAIN_TABLE " WHERE id="DPK, pk);

        /* execute the request */
        rc = db_exec_sql(&p_mgr->conn, req->str, &result);
        if (rc)
            goto free_str;

        rc = db_next_record(&p_mgr->conn, &result, result_tab, 1);
        db_result_free(&p_mgr->conn, &result);
        if (rc)
        {
            rc = DB_NOT_EXISTS;
            goto free_str;
        }
    }

    /* restore generated fields in attr mask */
    p_info->attr_mask = attr_mask_or(&p_info->attr_mask, &gen);
    /* generate them */
    generate_fields(p_info);

    /* update operation stats */
    p_mgr->nbop[OPIDX_GET]++;

    rc = DB_SUCCESS;
    goto free_str;

  free_res:
    db_result_free(&p_mgr->conn, &result);
  free_str:
    g_string_free(req, TRUE);
    g_string_free(from, TRUE);
    return rc;
} /* listmgr_get_by_pk */
Example #17
0
/** check that validator is matching for a given entry */
int ListMgr_CheckStripe(lmgr_t *p_mgr, const entry_id_t *p_id, int validator)
{
    char *res;
    result_handle_t result;
    int rc = DB_SUCCESS;
    GString *req = NULL;
    DEF_PK(pk);

#ifndef HAVE_LLAPI_FSWAP_LAYOUTS
    if (validator != VALID_EXISTS)
        validator = VALID(p_id);
#endif

    entry_id2pk(p_id, PTR_PK(pk));

    req = g_string_new("SELECT validator FROM " STRIPE_INFO_TABLE " WHERE id=");
    g_string_append_printf(req, DPK, pk);

 retry:
    rc = db_exec_sql(&p_mgr->conn, req->str, &result);
    if (lmgr_delayed_retry(p_mgr, rc))
        goto retry;
    else if (rc)
        goto out;

    rc = db_next_record(&p_mgr->conn, &result, &res, 1);
    if (lmgr_delayed_retry(p_mgr, rc))
        goto retry;

    if (rc == DB_END_OF_LIST)
        rc = DB_NOT_EXISTS;

    if (rc)
        goto res_free;

    if (res == NULL) {
        rc = DB_ATTR_MISSING;
        goto res_free;
    }

    if (validator == VALID_EXISTS) {
        DisplayLog(LVL_FULL, LISTMGR_TAG, DFID ": validator exists (%s): OK",
                   PFID(p_id), res);
        /* just check it exists */
        rc = DB_SUCCESS;
    } else if (atoi(res) != validator) {
        DisplayLog(LVL_FULL, LISTMGR_TAG,
                   DFID ": stripe change detected: gen %s->%d", PFID(p_id), res,
                   validator);
        rc = DB_OUT_OF_DATE;
    } else {    /* validator matches */

        DisplayLog(LVL_FULL, LISTMGR_TAG, DFID ": stripe gen is unchanged (%d)",
                   PFID(p_id), validator);
        rc = DB_SUCCESS;
    }

 res_free:
    db_result_free(&p_mgr->conn, &result);
 out:
    g_string_free(req, TRUE);
    DisplayLog(LVL_FULL, LISTMGR_TAG, DFID ": %s returns with status=%d",
               PFID(p_id), __func__, rc);
    return rc;
}
Example #18
0
/**
 * \retval DB_NOT_EXISTS if the recovery table does not exist
 */
static int expected_recov_status( lmgr_t * p_mgr, lmgr_recov_stat_t * p_stats )
{
    int  rc, i;
    result_handle_t result;
    char * status[5];

    /* test if a RECOVERY table already exist, and contains entries */
    rc = db_exec_sql_quiet( &p_mgr->conn, "SELECT status,type,COUNT(*),(size=0) as empty,SUM(size) FROM "RECOV_TABLE
                            " GROUP BY status,type,empty", &result );
    if (rc)
        return rc;

    /* @TODO manage dirs and symlinks differently */

    p_stats->total = 0;
    for (i = 0; i < RS_COUNT; i++ )
    {
        p_stats->status_count[i] = 0;
        p_stats->status_size[i] = 0;
    }

    while ( (rc = db_next_record( &p_mgr->conn, &result, status, 5 ))
            != DB_END_OF_LIST )
    {
        long long cnt;
        uint64_t sz;
        int isempty;

        if (rc)
            return rc;

        cnt = str2bigint( status[2] );
        if ( cnt == -1LL)
            return DB_INVALID_ARG;

        isempty = str2int(  status[3] );
        if ( isempty == -1)
            return DB_INVALID_ARG;

        sz = str2size(  status[4] );
        if ( sz == -1LL)
            return DB_INVALID_ARG;

        p_stats->total += cnt;

        if ( status[0] != NULL )
        {
            int st = str2int( status[0] );

            /* archived entries: file and (optionally) symlinks  */
            if (!strcasecmp(status[1], STR_TYPE_FILE))
            {
                if (isempty)
                {
                     p_stats->status_count[RS_FILE_EMPTY] += cnt;
                     p_stats->status_size[RS_FILE_EMPTY] += sz;
                }
                else
                {
                    switch (st)
                    {
                        case STATUS_NEW:
                            p_stats->status_count[RS_NOBACKUP] += cnt;
                            p_stats->status_size[RS_NOBACKUP] += sz;
                            break;
                        case STATUS_MODIFIED:
                        case STATUS_ARCHIVE_RUNNING:
                            p_stats->status_count[RS_FILE_DELTA] += cnt;
                            p_stats->status_size[RS_FILE_DELTA] += sz;
                            break;
                        case STATUS_SYNCHRO:
                        case STATUS_RELEASED:
                            p_stats->status_count[RS_FILE_OK] += cnt;
                            p_stats->status_size[RS_FILE_OK] += sz;
                            break;
                    }
                }
            }
            else if (!strcasecmp(status[1], STR_TYPE_LINK)
                     || !strcasecmp(status[1], STR_TYPE_DIR))
            {
                /* symlinks and dirs always recoverable from DB */
                p_stats->status_count[RS_NON_FILE] += cnt;
                p_stats->status_size[RS_NON_FILE] += sz;
            }
            else
            {
                /* non recoverable : special entry like fifo, blk, ... */
                p_stats->status_count[RS_NOBACKUP] += cnt;
                p_stats->status_size[RS_NOBACKUP] += sz;
            }
        }
    }

    db_result_free( &p_mgr->conn, &result );
    return 0;
}
Example #19
0
/**
 *  Retrieve entry attributes from its primary key
 */
int listmgr_get_by_pk( lmgr_t * p_mgr, PK_ARG_T pk, attr_set_t * p_info )
{
    int            rc;
    char           fieldlist[4096] = "";
    char          *first_table = NULL;
    char           from[1024] = "";
    char           query[4096] = "";
    /* we assume there is not more than 128 fields */
    char          *result_tab[128];
    result_handle_t result;
    int checkmain = 1;
    int main_count = 0, annex_count = 0, name_count = 0;

    if (p_info == NULL)
        return 0;

    /* init entry info */
    memset( &p_info->attr_values, 0, sizeof( entry_info_t ) );
    fieldlist[0] = '\0';

    /* retrieve source info for generated fields */
    add_source_fields_for_gen( &p_info->attr_mask );

    /* get info from main table (if asked) */
    main_count = attrmask2fieldlist(fieldlist, p_info->attr_mask, T_MAIN, FALSE,
                                    FALSE, "", "");
    if (main_count < 0)
        return -main_count;
    else if (main_count > 0)
    {
        checkmain = 0;
        first_table = MAIN_TABLE;
        sprintf(from, MAIN_TABLE);
    }

    annex_count = attrmask2fieldlist(fieldlist + strlen(fieldlist),
                                     p_info->attr_mask, T_ANNEX,
                                     first_table != NULL, FALSE, "", "");
    if (annex_count < 0)
        return -annex_count;
    else if (annex_count > 0)
    {
        if (first_table)
            sprintf(from + strlen(from), " LEFT JOIN "ANNEX_TABLE" ON %s.id="
                    ANNEX_TABLE".id", first_table);
        else
        {
            first_table = ANNEX_TABLE;
            sprintf(from, ANNEX_TABLE);
        }
    }

    name_count = attrmask2fieldlist(fieldlist + strlen(fieldlist),
                                    p_info->attr_mask, T_DNAMES,
                                    first_table != NULL, FALSE, "", "");
    if (name_count < 0)
        return -name_count;
    else if (name_count > 0)
    {
        if (first_table)
            /* it's OK to JOIN with NAMES table here even if there are multiple paths,
             * as we only take one result record. The important thing is to return
             * consistent values for parent_id, name and fullpath. */
            sprintf(from + strlen(from), " LEFT JOIN "DNAMES_TABLE" ON %s.id="
                    DNAMES_TABLE".id", first_table);
        else
        {
            first_table = DNAMES_TABLE;
            sprintf(from, DNAMES_TABLE);
        }
    }

    if (first_table != NULL)
    {
        int shift = 0;
        sprintf(query, "SELECT %s FROM %s WHERE %s.id="DPK, fieldlist, from,
                first_table, pk);

        rc = db_exec_sql(&p_mgr->conn, query, &result);
        if (rc)
            return rc;

        rc = db_next_record(&p_mgr->conn, &result, result_tab,
                            main_count + annex_count + name_count);
        /* END_OF_LIST means it does not exist */
        if (rc == DB_END_OF_LIST)
            rc = DB_NOT_EXISTS;
        if (rc)
            goto free_res;

        /* set info from result */
        if (main_count)
        {
            rc = result2attrset(T_MAIN, result_tab + shift, main_count, p_info);
            shift += main_count;
            if (rc)
                goto free_res;
        }
        if (annex_count)
        {
            rc = result2attrset(T_ANNEX, result_tab + shift, annex_count,
                                p_info);
            shift += annex_count;
            if (rc)
                goto free_res;
        }
        if (name_count)
        {
            rc = result2attrset(T_DNAMES, result_tab + shift, name_count,
                                p_info);
            shift += name_count;
            if (rc)
                goto free_res;
        }

        db_result_free(&p_mgr->conn, &result);
    }

    /* remove stripe info if it is not a file */
    if (stripe_fields(p_info->attr_mask) && ATTR_MASK_TEST(p_info, type)
        && strcmp(ATTR(p_info, type), STR_TYPE_FILE) != 0)
    {
        p_info->attr_mask &= ~stripe_attr_set;
    }

    /* get stripe info if asked */
#ifdef _LUSTRE
    if (stripe_fields( p_info->attr_mask ))
    {
        rc = get_stripe_info( p_mgr, pk, &ATTR( p_info, stripe_info ),
                              ATTR_MASK_TEST( p_info, stripe_items ) ? &ATTR( p_info,
                                                                              stripe_items ) :
                              NULL );
        if ( rc == DB_ATTR_MISSING || rc == DB_NOT_EXISTS )
        {
            p_info->attr_mask &= ~ATTR_MASK_stripe_info;

            if ( ATTR_MASK_TEST( p_info, stripe_items ) )
                p_info->attr_mask &= ~ATTR_MASK_stripe_items;
        }
        else if ( rc )
            return rc;
        else
            checkmain = 0; /* entry exists */
    }
#else
    /* always clean them */
    p_info->attr_mask &= ~(ATTR_MASK_stripe_info | ATTR_MASK_stripe_items);
#endif

    /* special field dircount */
    if (dirattr_fields( p_info->attr_mask ))
    {
        if (listmgr_get_dirattrs(p_mgr, pk, p_info))
        {
            DisplayLog( LVL_MAJOR, LISTMGR_TAG, "listmgr_get_dirattrs failed for "DPK, pk );
            p_info->attr_mask &= ~dir_attr_set;
        }
    }

    if (checkmain)
    {
        /* verify it exists in main table */
        sprintf( query, "SELECT id FROM " MAIN_TABLE " WHERE id="DPK, pk );

        /* execute the request */
        rc = db_exec_sql( &p_mgr->conn, query, &result );
        if ( rc )
            return rc;

        rc = db_next_record( &p_mgr->conn, &result, result_tab, 1 );
        db_result_free( &p_mgr->conn, &result );
        if (rc)
            return DB_NOT_EXISTS;
    }

    /* compute generated fields if asked */
    generate_fields( p_info );

    p_mgr->nbop[OPIDX_GET]++;

    return DB_SUCCESS;

  free_res:
    db_result_free( &p_mgr->conn, &result );
    return rc;
}                               /* listmgr_get_by_pk */
Example #20
0
/**
 * Main daemon routine
 */
int main( int argc, char **argv )
{
    int            c = 0;
    char          *bin = basename( argv[0] );
    int            rc;
    char           err_msg[4096];
    robinhood_config_t config;
    int chgd = 0;

    /* options */
    char           config_file[MAX_OPT_LEN] = "";
    char           badcfg[RBH_PATH_MAX];
    int            force_log_level = FALSE;
    int            log_level = 0;
    int            margin = 0;
    char           output_file[MAX_OPT_LEN] = "/tmp/lov_objid";

    lmgr_t         lmgr;
    FILE         * out;

    /* parse command line options */
    while ((c = getopt(argc, argv, OPT_STRING)) != -1)
    {
        switch (c)
        {
            case 'l':
                force_log_level = TRUE;
                log_level = str2debuglevel(optarg);
                if (log_level == -1)
                {
                    fprintf( stderr,
                             "Unsupported log level '%s'. CRIT, MAJOR, EVENT, VERB, DEBUG or FULL expected.\n",
                             optarg );
                    exit(1);
                }
                break;
            case 'f':
                rh_strncpy(config_file, optarg, MAX_OPT_LEN);
                break;
            case 'o':
                rh_strncpy(output_file, optarg, MAX_OPT_LEN);
                break;
            case 'm':
                margin = str2int(optarg);
                if (margin < 0)
                {
                    fprintf( stderr,
                             "Invalid parameter '%s' for '-m' option: positive integer expected\n",
                             optarg );
                    exit(1);
                }
                break;
            case ':':
            case '?':
            default:
                display_help(bin);
                exit( 1 );
                break;
        }
    }

    /* get default config file, if not specified */
    if (SearchConfig(config_file, config_file, &chgd, badcfg, MAX_OPT_LEN) != 0)
    {
        fprintf(stderr, "No config file (or too many) found matching %s\n", badcfg);
        exit(2);
    }
    else if (chgd)
    {
        fprintf(stderr, "Using config file '%s'.\n", config_file );
    }

    /* only read ListMgr config */

    if ( ReadRobinhoodConfig( 0, config_file, err_msg, &config, FALSE ) )
    {
        fprintf( stderr, "Error reading configuration file '%s': %s\n", config_file, err_msg );
        exit( 1 );
    }
    process_config_file = config_file;

    /* set global configuration */
    global_config = config.global_config;

    if ( force_log_level )
        config.log_config.debug_level = log_level;
    else
        config.log_config.debug_level = LVL_MAJOR; /* no event message */

    /* set logging to stderr for this tool */
    strcpy( config.log_config.log_file, "stderr" );
    strcpy( config.log_config.report_file, "stderr" );
    strcpy( config.log_config.alert_file, "stderr" );

    /* Initialize logging */
    rc = InitializeLogs( bin, &config.log_config );
    if ( rc )
    {
        fprintf( stderr, "Error opening log files: rc=%d, errno=%d: %s\n",
                 rc, errno, strerror( errno ) );
        exit( rc );
    }

    /* Initialize list manager */
    rc = ListMgr_Init( &config.lmgr_config, TRUE );
    if ( rc )
    {
        DisplayLog( LVL_CRIT, TAG, "Error %d initializing list manager", rc );
        exit( rc );
    }
    else
        DisplayLog( LVL_DEBUG, TAG, "ListManager successfully initialized" );

    if ( CheckLastFS(  ) != 0 )
        exit( 1 );

    /* Create database access */
    rc = ListMgr_InitAccess( &lmgr );
    if ( rc )
    {
        DisplayLog( LVL_CRIT, TAG, "Error %d: cannot connect to database", rc );
        exit( rc );
    }

    out = fopen(output_file, "w");
    if (!out)
    {
        DisplayLog(LVL_CRIT, TAG, "Failed to open '%s' for writting: %s", output_file,
                   strerror(errno));
        return errno;
    }

    /* direct SQL request to retrieve the max object index from DB */
    result_handle_t res;
    /* FIXME max on the low weight 32bits of the 'objid' 64bits value */
    rc = db_exec_sql(&lmgr.conn, "SELECT ostidx, max(hex(cast(reverse(cast(details as binary(8))) as binary(4)))) "
                     "FROM "STRIPE_ITEMS_TABLE" GROUP BY ostidx ORDER BY ostidx", &res);
    if (rc)
        goto db_error;

    int index = -1;
    do
    {
        char *resstr[2];
        unsigned int ostidx;
        unsigned int objid;
        unsigned long long objid_long;
        resstr[0] = resstr[1] = NULL;

        rc = db_next_record( &lmgr.conn, &res, resstr, 2 );
        if (rc == DB_END_OF_LIST)
            break;
        else if (rc != DB_SUCCESS)
            goto db_error;

        index ++;

        if (resstr[0] == NULL || resstr[1] == NULL)
        {
            DisplayLog(LVL_MAJOR, TAG, "ERROR: got NULL record from DB at index %u", index);
            rc = EINVAL;
            goto out;
        }

        /* resstr[0] is ost_idx */
        if (sscanf(resstr[0], "%u", &ostidx) != 1)
        {
            DisplayLog(LVL_MAJOR, TAG, "ERROR: cannot parse OST index '%s' at index %u", resstr[0], index);
            rc = EINVAL;
            goto out;
        }
        else if (ostidx != index)
        {
            DisplayLog(LVL_MAJOR, TAG, "Warning: OST index %u not found in database, assuming current objid=1",
                       index);
            objid_long = 1 + margin;
            printf("ostidx=%u, max objid=%016LX\n", ostidx, objid_long);
            fwrite(&objid_long, sizeof(objid_long), 1, out);
            continue;
        }

        /* resstr[1] is objid (hexa) */
        if (sscanf(resstr[1], "%X", &objid) != 1)
        {
            DisplayLog(LVL_MAJOR, TAG, "ERROR: cannot parse objid '%s' at index %u", resstr[1], index);
            rc = EINVAL;
            goto out;
        }

        objid_long = objid + margin;
        printf("ostidx=%u, objid=%016LX\n", ostidx, objid_long);
        fwrite(&objid_long, sizeof(objid_long), 1, out);

    } while(rc == 0);

    fclose(out);
    ListMgr_CloseAccess( &lmgr );
    return 0;

db_error:
    DisplayLog( LVL_CRIT, TAG, "Database error %d\n", rc);
out:
    ListMgr_CloseAccess( &lmgr );
    return rc;
}
Example #21
0
int get_stripe_info(lmgr_t *p_mgr, PK_ARG_T pk, stripe_info_t *p_stripe_info,
                    stripe_items_t *p_items)
{
/* stripe_count, stripe_size, pool_name, validator => 4 */
#define STRIPE_INFO_COUNT 4
    char *res[STRIPE_INFO_COUNT];
    result_handle_t result;
    int i;
    int rc = DB_SUCCESS;
    GString *req;

    /* retrieve basic stripe info */
    req =
        g_string_new
        ("SELECT stripe_count, stripe_size, pool_name,validator FROM "
         STRIPE_INFO_TABLE " WHERE id=");
    g_string_append_printf(req, DPK, pk);

    rc = db_exec_sql(&p_mgr->conn, req->str, &result);
    if (rc)
        goto out;

    rc = db_next_record(&p_mgr->conn, &result, res, STRIPE_INFO_COUNT);

    if (rc == DB_END_OF_LIST)
        rc = DB_NOT_EXISTS;
    if (rc)
        goto res_free;

    for (i = 0; i < STRIPE_INFO_COUNT; i++) {
        DisplayLog(LVL_FULL, LISTMGR_TAG, "stripe_res[%u] = %s", i,
                   res[i] ? res[i] : "<null>");
        if (res[i] == NULL) {
            rc = DB_ATTR_MISSING;
            goto res_free;
        }
    }

    p_stripe_info->stripe_count = atoi(res[0]);
    p_stripe_info->stripe_size = atoi(res[1]);
    rh_strncpy(p_stripe_info->pool_name, res[2], MAX_POOL_LEN);
#ifdef HAVE_LLAPI_FSWAP_LAYOUTS
    p_stripe_info->validator = atoi(res[3]);
#endif

    db_result_free(&p_mgr->conn, &result);

    if (p_items) {
        /* retrieve stripe list */
        g_string_printf(req, "SELECT stripe_index,ostidx,details FROM "
                        STRIPE_ITEMS_TABLE " WHERE id=" DPK
                        " ORDER BY stripe_index ASC", pk);

        rc = db_exec_sql(&p_mgr->conn, req->str, &result);
        if (rc)
            goto out;

#ifndef _LUSTRE_HSM
        /* this is abnormal if LUSTRE/HSM feature is not present */
        if (p_stripe_info->stripe_count !=
            db_result_nb_records(&p_mgr->conn, &result)) {
            DisplayLog(LVL_MAJOR, LISTMGR_TAG,
                       "Warning: the number of stripe items (%d) doesn't match stripe count (%u)! (Pk="
                       DPK ")", db_result_nb_records(&p_mgr->conn, &result),
                       p_stripe_info->stripe_count, pk);
        }
#endif
        p_items->count = db_result_nb_records(&p_mgr->conn, &result);

        if (p_items->count > 0) {

            /* allocate stripe array */
            p_items->stripe = MemCalloc(p_items->count, sizeof(stripe_item_t));

            if (!p_items->stripe) {
                rc = DB_NO_MEMORY;
                goto res_free;
            }

            /* fill stripe units */
            for (i = 0; i < p_items->count; i++) {
                rc = db_next_record(&p_mgr->conn, &result, res,
                                    STRIPE_INFO_COUNT);
                if (rc)
                    goto stripe_free;

                if (res[0] == NULL) {
                    rc = DB_ATTR_MISSING;
                    goto stripe_free;
                }

                if (i != atoi(res[0])) {
                    DisplayLog(LVL_MAJOR, LISTMGR_TAG,
                               "Warning: inconsistent stripe order: stripe %s returned in position %u",
                               res[0], i);
                }
                p_items->stripe[i].ost_idx = atoi(res[1]);
                /* raw copy of binary buffer (last 3 fields of stripe_item_t
                 *                            = address of ost_gen field) */
                memcpy(&p_items->stripe[i].ost_gen, res[2], STRIPE_DETAIL_SZ);
            }
        } else
            p_items->stripe = NULL;

        /* last query result must be freed */
        rc = DB_SUCCESS;
        goto res_free;
    }

    rc = DB_SUCCESS;
    /* result is already freed */
    goto out;

 stripe_free:
    free_stripe_items(p_items);
 res_free:
    db_result_free(&p_mgr->conn, &result);
 out:
    g_string_free(req, TRUE);
    return rc;
}