Example #1
0
static void no_name_warning(PK_PARG_T pk, attr_set_t *p_attrs, unsigned int count)
{
    DEF_PK(ppk);
    char msg[256];

    entry_id2pk(&ATTR(p_attrs, parent_id), PTR_PK(ppk));

    if (count > 1)
        snprintf(msg, sizeof(msg), "%u entries", count);
    else
        rh_strncpy(msg, "entry", sizeof(msg));

    DisplayLog(LVL_MAJOR, LISTMGR_TAG, "WARNING: %s created without"
               " name or parent information: pk="DPK", name='%s', parent='%s'",
               msg, pk, ATTR_MASK_TEST(p_attrs, name) ? ATTR(p_attrs, name) : "",
               ATTR_MASK_TEST(p_attrs, parent_id) ? ppk : "");
}
Example #2
0
/* directory callback */
static int dircb(wagon_t * id_list, attr_set_t * attr_list,
                 unsigned int entry_count, void * dummy )
{
    /* retrieve child entries for all directories */
    int i, rc;

    for (i = 0; i < entry_count; i++)
    {
        wagon_t * chids = NULL;
        attr_set_t * chattrs = NULL;
        unsigned int chcount = 0;
        int j;

        /* match condition on dirs parent */
        if (!is_expr || (EntryMatches(&id_list[i].id, &attr_list[i],
                                      &match_expr, NULL) == POLICY_MATCH))
        {
            /* don't display dirs if no_dir is specified */
            if (! (prog_options.no_dir && ATTR_MASK_TEST(&attr_list[i], type)
                   && !strcasecmp(ATTR(&attr_list[i], type), STR_TYPE_DIR)) )
                print_entry(&id_list[i], &attr_list[i]);
        }

        if (!prog_options.dir_only)
        {
            rc = ListMgr_GetChild( &lmgr, &entry_filter, id_list+i, 1,
                                   disp_mask | query_mask,
                                   &chids, &chattrs, &chcount);
            if (rc)
            {
                DisplayLog(LVL_MAJOR, FIND_TAG, "ListMgr_GetChild() failed with error %d", rc);
                return rc;
            }

            for (j = 0; j < chcount; j++)
            {
                if (!is_expr || (EntryMatches(&chids[j].id, &chattrs[j],
                                 &match_expr, NULL) == POLICY_MATCH))
                    print_entry(&chids[j], &chattrs[j]);

                ListMgr_FreeAttrs(&chattrs[j]);
            }

            free_wagon(chids, 0, chcount);
            MemFree(chids);
            MemFree(chattrs);
        }
    }
    return 0;
}
Example #3
0
static int alerter_alert(const entry_id_t *p_entry_id, attr_set_t *p_attrs,
                         const action_params_t *params, post_action_e *after,
                         db_cb_func_t db_cb_fn, void *db_cb_arg)
{
    char *str_id = NULL;
    bool  str_is_alloc = false;
    GString *gs = g_string_new(NULL);

    /* build alert string */
    if (ATTR_MASK_TEST(p_attrs, fullpath))
    {
        str_id = ATTR(p_attrs, fullpath);
    }
    else
    {
        asprintf(&str_id, DFID, PFID(p_entry_id));
        str_is_alloc = true;
    }

    /** TODO build specific parameter that represents the alert rule */
    #if 0
    rc = BoolExpr2str(&entry_proc_conf.alert_list[i].boolexpr, stralert, 2*RBH_PATH_MAX);
    if ( rc < 0 )
        strcpy( stralert, "Error building alert string" );
    #endif

    /** TODO build specific parameter that represents attr mask for the rule (alert mask) */

    print_attrs(gs, p_attrs, null_mask, 0);

    /* title: alert rule name */
    RaiseEntryAlert(rbh_param_get(params, "title"), "entry matches alert rule",
                    str_id, gs->str);

    g_string_free(gs, TRUE);
    if (str_is_alloc)
        free(str_id);

    return 0;
}
Example #4
0
/**
 * Bulk filtering in the DB.
 */
static int list_bulk(void)
{
    attr_set_t  root_attrs, attrs;
    entry_id_t  root_id, id;
    int rc;
    struct stat st;
    struct lmgr_iterator_t *it;

    /* no tranvsersal => no wagon
     * so we need the path from the DB.
     */
    query_mask |= ATTR_MASK_fullpath;

    ATTR_MASK_INIT(&root_attrs);

    rc = retrieve_root_id(&root_id);
    if (rc)
        return rc;

    /* root is not a part of the DB: print it now */
    ATTR_MASK_SET(&root_attrs, fullpath);
    strcpy(ATTR(&root_attrs, fullpath), config.global_config.fs_path);

    if (lstat(ATTR(&root_attrs, fullpath), &st) == 0)
    {
        PosixStat2EntryAttr(&st, &root_attrs, TRUE);
        ListMgr_GenerateFields(&root_attrs, disp_mask | query_mask);
    }
    /* root has no name... */
    ATTR_MASK_SET(&root_attrs, name);
    ATTR(&root_attrs, name)[0] = '\0';

    /* match condition on dirs parent */
    if (!is_expr || (EntryMatches(&root_id, &root_attrs,
                     &match_expr, NULL) == POLICY_MATCH))
    {
        /* don't display dirs if no_dir is specified */
        if (! (prog_options.no_dir && ATTR_MASK_TEST(&root_attrs, type)
               && !strcasecmp(ATTR(&root_attrs, type), STR_TYPE_DIR))) {
            wagon_t w;
            w.id = root_id;
            w.fullname = ATTR(&root_attrs, fullpath);
            print_entry(&w, &root_attrs);
        }
    }

    /* list all, including dirs */
    it = ListMgr_Iterator(&lmgr, &entry_filter, NULL, NULL);
    if (!it)
    {
        DisplayLog(LVL_MAJOR, FIND_TAG, "ERROR: cannot retrieve entry list from database");
        return -1;
    }

    attrs.attr_mask = disp_mask | query_mask;
    while ((rc = ListMgr_GetNext(it, &id, &attrs)) == DB_SUCCESS)
    {
        if (!is_expr || (EntryMatches(&id, &attrs, &match_expr, NULL)
                                      == POLICY_MATCH))
        {
            /* don't display dirs if no_dir is specified */
            if (! (prog_options.no_dir && ATTR_MASK_TEST(&attrs, type)
                   && !strcasecmp(ATTR(&attrs, type), STR_TYPE_DIR))) {
                wagon_t w;
                w.id = id;
                w.fullname = ATTR(&attrs, fullpath);
                print_entry(&w, &attrs);
            }
            /* don't display non dirs is dir_only is specified */
            else if (! (prog_options.dir_only && ATTR_MASK_TEST(&attrs, type)
                        && strcasecmp(ATTR(&attrs, type), STR_TYPE_DIR))) {
                wagon_t w;
                w.id = id;
                w.fullname = ATTR(&attrs, fullpath);
                print_entry(&w, &attrs);
            }
            else
                /* return entry don't match? */
                DisplayLog(LVL_DEBUG, FIND_TAG, "Warning: returned DB entry doesn't match filter: %s",
                           ATTR(&attrs, fullpath));
        }
        ListMgr_FreeAttrs(&attrs);

        /* prepare next call */
        attrs.attr_mask = disp_mask | query_mask;
    }
    ListMgr_CloseIterator(it);

    return 0;
}
Example #5
0
static inline void print_entry(const wagon_t *id, const attr_set_t * attrs)
{
    char ostbuf[24576] = "";

#ifdef ATTR_INDEX_status
    if (prog_options.match_status)
    {
        if (ATTR_MASK_TEST(attrs, status) && (ATTR(attrs, status) != prog_options.status))
        {
            /* no match -> no display */
            return;
        }
    }
#endif

#ifdef _LUSTRE
    /* prepare OST display buffer */
    if (prog_options.lsost && ATTR_MASK_TEST(attrs, stripe_items)
        && (ATTR(attrs, stripe_items).count > 0))
    {
        /* leave a space as first char */
        ostbuf[0] = ' ';
        FormatStripeList(ostbuf+1, sizeof(ostbuf)-2, &ATTR(attrs, stripe_items), TRUE);
    }
#endif

    if (prog_options.ls)
    {
        const char * type;
        char date_str[128];
        char mode_str[128];
#ifdef ATTR_INDEX_status
        const char * status_str = "";

        /* add status after type */
        if (ATTR_MASK_TEST(attrs, status) && (ATTR(attrs, status) != STATUS_UNKNOWN))
            status_str = db_status2str(ATTR(attrs, status), 1); /* 1 for brief */

        #define STATUS_FORMAT   "%-10s"
        #define STATUS_VAL ,status_str
#else
        #define STATUS_FORMAT   ""
        #define STATUS_VAL
#endif
        /* type2char */
        if (!ATTR_MASK_TEST(attrs, type))
            type = "?";
        else
            type = type2char(ATTR(attrs, type));

        memset(mode_str, 0, sizeof(mode_str));
        mode_string(ATTR(attrs, mode), mode_str);

        if (!ATTR_MASK_TEST(attrs, last_mod))
            strcpy(date_str, "");
        else
        {
            time_t tt;
            struct tm stm;
            tt = ATTR(attrs, last_mod);
            strftime(date_str, 128, "%Y/%m/%d %T", localtime_r(&tt, &stm));
        }

        if (ATTR_MASK_TEST(attrs, type) && !strcmp(ATTR(attrs, type), STR_TYPE_LINK)
            && ATTR_MASK_TEST(attrs, link))
            /* display: id, type, mode, nlink, (status,) owner, group, size, mtime, path -> link */
            printf(DFID" %-4s %s %3u  "STATUS_FORMAT"%-10s %-10s %15"PRIu64" %20s %s -> %s\n",
                   PFID(&id->id), type, mode_str, ATTR(attrs, nlink) STATUS_VAL,
                   ATTR(attrs, owner), ATTR(attrs, gr_name),
                   ATTR(attrs, size), date_str, id->fullname, ATTR(attrs,link));
        else
            /* display all: id, type, mode, nlink, (status,) owner, group, size, mtime, path */
            printf(DFID" %-4s %s %3u  "STATUS_FORMAT"%-10s %-10s %15"PRIu64" %20s %s%s\n",
                   PFID(&id->id), type, mode_str, ATTR(attrs, nlink) STATUS_VAL,
                   ATTR(attrs, owner), ATTR(attrs, gr_name),
                   ATTR(attrs, size), date_str, id->fullname, ostbuf);
    }
    else if (prog_options.lsost) /* lsost without -ls */
    {
        const char * type;

        /* type2char */
        if (!ATTR_MASK_TEST(attrs, type))
            type = "?";
        else
            type = type2char(ATTR(attrs, type));

        /* display: id, type, size, path */
        printf(DFID" %-4s %15"PRIu64" %s%s\n",
               PFID(&id->id), type, ATTR(attrs, size), id->fullname, ostbuf);

    }
    else if (prog_options.print)
    {
        /* just display name */
        if (id->fullname)
            printf("%s%s\n", id->fullname, ostbuf);
        else
            printf(DFID"%s\n", PFID(&id->id), ostbuf);
    }

    if (prog_options.exec)
    {
        const char *vars[] = {
            "", id->fullname,
            NULL, NULL
        };
        char * cmd = replace_cmd_parameters(prog_options.exec_cmd, vars);
        if (cmd)
        {
            execute_shell_command(FALSE, cmd, 0);
            free(cmd);
        }
    }

}
Example #6
0
static int recov_resume(int retry_errors)
{
    struct lmgr_iterator_t *it;
    int rc, st;
    entry_id_t id, new_id;
    attr_set_t attrs, new_attrs;
    char buff[128];

    /* TODO iter opt */
    it = ListMgr_RecovResume(&lmgr, path_filter, retry_errors, NULL);
    if (it == NULL) {
        fprintf(stderr,
                "ERROR: cannot get the list of entries to be recovered\n");
        return -1;
    }

    attrs.attr_mask = RECOV_ATTR_MASK;

    while (!terminate &&
           ((rc =
             ListMgr_RecovGetNext(it, &id, &attrs, NULL)) != DB_END_OF_LIST)) {
        if (rc) {
            fprintf(stderr, "ERROR %d getting entry from recovery table\n", rc);
            ListMgr_CloseIterator(it);
            return rc;
        }

        FormatFileSize(buff, 128, ATTR(&attrs, size));

        if (ATTR_MASK_TEST(&attrs, fullpath))
            printf("Restoring %s (%s)...", ATTR(&attrs, fullpath), buff);
        else
            printf("Restoring " DFID " (%s)...", PFID(&id), buff);

        /* TODO process entries asynchronously, in parallel, in separate
         * threads */
        st = rbhext_recover(&id, &attrs, &new_id, &new_attrs, NULL);

        if ((st == RS_FILE_OK) || (st == RS_FILE_EMPTY) || (st == RS_NON_FILE)
            || (st == RS_FILE_DELTA)) {
            /* don't insert readonly attrs */
            new_attrs.attr_mask &= ~readonly_attr_set;

            /* insert the entry in the database, and update recovery status */
            rc = ListMgr_Insert(&lmgr, &new_id, &new_attrs, true);
            if (rc) {
                fprintf(stderr, "DB insert failure for '%s'\n",
                        ATTR(&new_attrs, fullpath));
                st = RS_ERROR;
            }
        }

        /* old id must be used for impacting recovery table */
        if (ListMgr_RecovSetState(&lmgr, &id, st))
            st = RS_ERROR;

        switch (st) {
        case RS_FILE_OK:
            printf(" OK\n");
            break;
        case RS_FILE_DELTA:
            printf(" OK (old version)\n");
            break;
        case RS_NON_FILE:
            printf(" OK (non-file)\n");
            break;
        case RS_FILE_EMPTY:
            printf(" OK (empty file)\n");
            break;
        case RS_NOBACKUP:
            printf(" No backup available\n");
            break;
        case RS_ERROR:
            printf(" FAILED\n");
            break;
        default:
            printf(" ERROR st=%d, rc=%d\n", st, rc);
            break;
        }

        /* reset mask */
        attrs.attr_mask = RECOV_ATTR_MASK;
    }

    return 0;
}
Example #7
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 #8
0
static inline void print_entry(const wagon_t *id, const attr_set_t * attrs)
{
#ifdef ATTR_INDEX_status
    if (prog_options.match_status)
    {
        if (ATTR_MASK_TEST(attrs, status) && (ATTR(attrs, status) != prog_options.status))
        {
            /* no match -> no display */
            return;
        }
    }
#endif

    if (prog_options.ls)
    {
        const char * type;
        char date_str[128];
        char mode_str[128];
        char uname[LOGIN_NAME_MAX];
        char gname[LOGIN_NAME_MAX];
        struct passwd *passwd;
        struct group *group;
#ifdef ATTR_INDEX_status
        const char * status_str = "";

        /* add status after type */
        if (ATTR_MASK_TEST(attrs, status) && (ATTR(attrs, status) != STATUS_UNKNOWN))
            status_str = db_status2str(ATTR(attrs, status), 1); /* 1 for brief */

        #define STATUS_FORMAT   "%-10s"
        #define STATUS_VAL ,status_str
#else
        #define STATUS_FORMAT   ""
        #define STATUS_VAL
#endif
        /* type2char */
        if (!ATTR_MASK_TEST(attrs, type))
            type = "?";
        else
            type = type2char(ATTR(attrs, type));

        memset(mode_str, 0, sizeof(mode_str));
        mode_string(ATTR(attrs, mode), mode_str);

        if (!ATTR_MASK_TEST(attrs, last_mod))
            strcpy(date_str, "");
        else
        {
            time_t tt;
            struct tm stm;
            tt = ATTR(attrs, last_mod);
            strftime(date_str, 128, "%Y/%m/%d %T", localtime_r(&tt, &stm));
        }

        /* UID/GID to username/group. */
        passwd = GetPwUid(ATTR(attrs, uid));
        if (passwd)
            sprintf(uname, "%-10s", passwd->pw_name);
        else
            sprintf(uname, "%10u", ATTR(attrs, uid));

        group = GetGrGid(ATTR(attrs, gid));
        if (group)
            sprintf(gname, "%-10s", group->gr_name);
        else
            sprintf(gname, "%10u", ATTR(attrs, gid));

        if (ATTR_MASK_TEST(attrs, type) && !strcmp(ATTR(attrs, type), STR_TYPE_LINK)
            && ATTR_MASK_TEST(attrs, link))
            /* display: id, type, mode, nlink, (status,) owner, group, size, mtime, path -> link */
            printf(DFID" %-4s %s %3u  "STATUS_FORMAT"%-10s %-10s %15"PRIu64" %20s %s -> %s\n",
                   PFID(&id->id), type, mode_str, ATTR(attrs, nlink) STATUS_VAL,
                   uname, gname,
                   ATTR(attrs, size), date_str, id->fullname, ATTR(attrs,link));
        else
            /* display all: id, type, mode, nlink, (status,) owner, group, size, mtime, path */
            printf(DFID" %-4s %s %3u  "STATUS_FORMAT"%-10s %-10s %15"PRIu64" %20s %s\n",
                   PFID(&id->id), type, mode_str, ATTR(attrs, nlink) STATUS_VAL,
                   uname, gname,
                   ATTR(attrs, size), date_str, id->fullname);
    }
    else if (prog_options.lsstat)
    {
        /* In the worst case scenario, each character will be escaped
         * to '\xXX'; so the string can be up to 4 time the name
         * length. */
        char escaped_name[4*RBH_NAME_MAX+1];

        /* Exclude any file with an uncomplete attributes. */
        if ((attrs->attr_mask & LSSTAT_MASK) == LSSTAT_MASK) {
            printf("[%s,%u,%u,%zu,%lu,%lu,%lu]=%s\n",
                   ATTR(attrs, type),
                   ATTR(attrs, uid),
                   ATTR(attrs, gid),
                   ATTR(attrs, size),
                   ATTR(attrs, ctime),
                   ATTR(attrs, mtime),
                   ATTR(attrs, atime),
                   escape_name(id->fullname, escaped_name));
        } else {
            printf("SKIPPED(%x,%x)=%s\n", attrs->attr_mask, LSSTAT_MASK, id->fullname);
        }
    }
#ifdef _LUSTRE
    else if (prog_options.lsost) {
        char tmpbuf[24576];

        FormatStripeList( tmpbuf, sizeof(tmpbuf)-1, &ATTR( attrs, stripe_items), FALSE);
        printf("%s\t%s\n", id->fullname, tmpbuf);
    }
#endif
    else
    {
        /* just display name */
        if (id->fullname)
            printf("%s\n", id->fullname);
        else
            printf(DFID"\n", PFID(&id->id));
    }

}
Example #9
0
int ListMgr_MassUpdate( lmgr_t * p_mgr,
                        const lmgr_filter_t * p_filter, const attr_set_t * p_attr_set )
{
    char           query[4096];
    char           filter_str_main[2048];
    char           filter_str_annex[2048];
    char           filter_str_stripe_info[2048];
    char           filter_str_stripe_units[2048];
    int            filter_main = 0;
    int            filter_annex = 0;
    int            filter_stripe_info = 0;
    int            filter_stripe_units = 0;
    int            rc, count;
    int            impact_all = FALSE;
    int            filter_unic = FALSE;
    char           fields[2048];
    char           tmp_table_name[256];
    int            tmp_table_created = FALSE;

    filter_str_main[0] = '\0';
    filter_str_annex[0] = '\0';
    filter_str_stripe_info[0] = '\0';
    filter_str_stripe_units[0] = '\0';

    /* /!\ possible cases:
     * - simplest: the fields of the filter and the attributes to be changed are in the same table
     * - harder: the fields of the filter are in the same table and attributes are in another different table 
     */

    /* 1) check the location of filters */

    if ( p_filter )
    {
        filter_main = filter2str( p_mgr, filter_str_main, p_filter, T_MAIN,
                                  FALSE, FALSE );

        if ( annex_table )
            filter_annex = filter2str( p_mgr, filter_str_annex, p_filter,
                                       T_ANNEX, FALSE, FALSE );
        else
            filter_annex = 0;

        filter_stripe_info =
            filter2str( p_mgr, filter_str_stripe_info, p_filter, T_STRIPE_INFO,
                        FALSE, FALSE );

        filter_stripe_units =
            filter2str( p_mgr, filter_str_stripe_units, p_filter,
                        T_STRIPE_ITEMS,FALSE, FALSE );

        if ( filter_main + filter_annex + filter_stripe_info + filter_stripe_units == 0 )
        {
            /* all records */
            impact_all = TRUE;
            DisplayLog( LVL_FULL, LISTMGR_TAG, "Empty filter: all records will be affected" );
        }
        else if ( filter_main && !( filter_annex || filter_stripe_info || filter_stripe_units ) )
        {
            filter_unic = TRUE;
            DisplayLog( LVL_FULL, LISTMGR_TAG, "Filter is only on " MAIN_TABLE " table" );
        }
        else if ( filter_annex && !( filter_main || filter_stripe_info || filter_stripe_units ) )
        {
            filter_unic = TRUE;
            DisplayLog( LVL_FULL, LISTMGR_TAG, "Filter is only on " ANNEX_TABLE " table" );
        }
        else if ( filter_stripe_info && !( filter_main || filter_annex || filter_stripe_units ) )
        {
            filter_unic = TRUE;
            DisplayLog( LVL_FULL, LISTMGR_TAG, "Filter is only on " STRIPE_INFO_TABLE " table" );
        }
        else if ( filter_stripe_units && !( filter_main || filter_annex || filter_stripe_info ) )
        {
            filter_unic = TRUE;
            DisplayLog( LVL_FULL, LISTMGR_TAG, "Filter is only on " STRIPE_ITEMS_TABLE " table" );
        }
        else
            DisplayLog( LVL_FULL, LISTMGR_TAG,
                        "Filter on several tables: " MAIN_TABLE ":%d, "
                        ANNEX_TABLE ":%d, " STRIPE_INFO_TABLE ":%d, "
                        STRIPE_ITEMS_TABLE ":%d",
                        filter_main, filter_annex, filter_stripe_info, filter_stripe_units );
    }
    else
    {
        impact_all = TRUE;
        DisplayLog( LVL_FULL, LISTMGR_TAG, "Empty filter: all records will be affected" );
    }

    /* 2) check if attributes to be changed are in MAIN table */
    /* 3) if filters are in MAIN table too, make a simple update statement */
    /* 4) if not, make a compound request: update xxx set xxx WHERE pk in ( select pk from ... where ... ) */

    rc = lmgr_begin( p_mgr );
    if ( rc )
        return rc;

    /* perform updates on MAIN TABLE */
    count = attrset2updatelist( p_mgr, fields, p_attr_set, T_MAIN, FALSE );
    if ( count < 0 )
        return -count;
    if ( count > 0 )
    {
        DisplayLog( LVL_FULL, LISTMGR_TAG, "Update on " MAIN_TABLE " table" );

        if ( impact_all )
        {
            /* all records are impacted */
            sprintf( query, "UPDATE " MAIN_TABLE " SET %s", fields );
        }
        else if ( filter_unic && filter_main )
        {
            /* update on the same table as filter */
            sprintf( query, "UPDATE " MAIN_TABLE " SET %s WHERE %s", fields, filter_str_main );
        }
        else if ( filter_unic )
        {
            /* update is on a different table than filter */
            if ( filter_annex )
            {
                if ( !tmp_table_created )
                {
                    /* create temp table */
                    sprintf( tmp_table_name, "TMP_TABLE_%u_%u",
                             ( unsigned int ) getpid(  ), ( unsigned int ) pthread_self(  ) );

                    sprintf( query,
                             "CREATE TEMPORARY TABLE %s AS SELECT id FROM "
                             ANNEX_TABLE " WHERE %s", tmp_table_name, filter_str_annex );

                    rc = db_exec_sql( &p_mgr->conn, query, NULL );
                    if ( rc )
                        goto rollback;

                    tmp_table_created = TRUE;
                }

                DisplayLog( LVL_MAJOR, LISTMGR_TAG, "WARNING: passing through unoptimized algorithm" );
                sprintf( query,
                         "UPDATE " MAIN_TABLE
                         " SET %s WHERE id IN (SELECT id FROM %s)", fields, tmp_table_name );

            }
            else if ( filter_stripe_units )
            {
                if ( !tmp_table_created )
                {
                    sprintf( tmp_table_name, "TMP_TABLE_%u_%u",
                             ( unsigned int ) getpid(  ), ( unsigned int ) pthread_self(  ) );

                    /* create temp table */
                    sprintf( query,
                             "CREATE TEMPORARY TABLE %s AS SELECT id FROM "
                             STRIPE_ITEMS_TABLE " WHERE %s", tmp_table_name,
                             filter_str_stripe_units );

                    rc = db_exec_sql( &p_mgr->conn, query, NULL );
                    if ( rc )
                        goto rollback;

                    tmp_table_created = TRUE;
                }

                DisplayLog( LVL_MAJOR, LISTMGR_TAG, "WARNING: passing through unoptimized algorithm" );

                sprintf( query,
                         "UPDATE " MAIN_TABLE
                         " SET %s WHERE id IN (SELECT id FROM %s)", fields, tmp_table_name );
            }
            else if ( filter_stripe_info )
            {
                if ( !tmp_table_created )
                {
                    sprintf( tmp_table_name, "TMP_TABLE_%u_%u",
                             ( unsigned int ) getpid(  ), ( unsigned int ) pthread_self(  ) );

                    /* create temp table */
                    sprintf( query,
                             "CREATE TEMPORARY TABLE %s AS SELECT id FROM "
                             STRIPE_INFO_TABLE " WHERE %s", tmp_table_name,
                             filter_str_stripe_info );

                    rc = db_exec_sql( &p_mgr->conn, query, NULL );
                    if ( rc )
                        goto rollback;

                    tmp_table_created = TRUE;
                }

                DisplayLog( LVL_MAJOR, LISTMGR_TAG, "WARNING: passing through unoptimized algorithm" );

                sprintf( query,
                         "UPDATE " MAIN_TABLE
                         " SET %s WHERE id IN (SELECT id FROM %s)", fields, tmp_table_name );
            }

        }
        else
        {
            /* @todo mixed filter :-s */
            rc = DB_NOT_SUPPORTED;
            goto rollback;
        }

        rc = db_exec_sql( &p_mgr->conn, query, NULL );
        if ( rc )
            goto rollback;
    }


    /* update on annex table ? */
    if ( annex_table )
    {
        count = attrset2updatelist( p_mgr, fields, p_attr_set, T_ANNEX, FALSE );
        if ( count < 0 )
            return -count;
        if ( count > 0 )
        {
            DisplayLog( LVL_FULL, LISTMGR_TAG, "Update on " ANNEX_TABLE " table" );

            if ( impact_all )
            {
                /* all records are impacted */
                sprintf( query, "UPDATE " ANNEX_TABLE " SET %s", fields );
            }
            else if ( filter_unic && filter_annex )
            {
                /* update on the same table as filter */
                sprintf( query,
                         "UPDATE " ANNEX_TABLE " SET %s WHERE %s", fields, filter_str_annex );
            }
            else if ( filter_unic )
            {
                /* update is on a different table than filter */
                if ( filter_main )
                {
                    if ( !tmp_table_created )
                    {
                        /* create temp table */
                        sprintf( tmp_table_name, "TMP_TABLE_%u_%u",
                                 ( unsigned int ) getpid(  ), ( unsigned int ) pthread_self(  ) );

                        sprintf( query,
                                 "CREATE TEMPORARY TABLE %s AS SELECT id FROM "
                                 MAIN_TABLE " WHERE %s", tmp_table_name, filter_str_main );

                        rc = db_exec_sql( &p_mgr->conn, query, NULL );
                        if ( rc )
                            goto rollback;

                        tmp_table_created = TRUE;
                    }

                    DisplayLog( LVL_MAJOR, LISTMGR_TAG, "WARNING: passing through unoptimized algorithm" );

                    sprintf( query,
                             "UPDATE " ANNEX_TABLE
                             " SET %s WHERE id IN (SELECT id FROM %s)", fields, tmp_table_name );

                }
                else if ( filter_stripe_units )
                {

                    if ( !tmp_table_created )
                    {
                        /* create temp table */
                        sprintf( tmp_table_name, "TMP_TABLE_%u_%u",
                                 ( unsigned int ) getpid(  ), ( unsigned int ) pthread_self(  ) );

                        sprintf( query,
                                 "CREATE TEMPORARY TABLE %s AS SELECT id FROM "
                                 STRIPE_ITEMS_TABLE " WHERE %s",
                                 tmp_table_name, filter_str_stripe_units );

                        rc = db_exec_sql( &p_mgr->conn, query, NULL );
                        if ( rc )
                            goto rollback;

                        tmp_table_created = TRUE;
                    }

                    DisplayLog( LVL_MAJOR, LISTMGR_TAG, "WARNING: passing through unoptimized algorithm" );

                    sprintf( query,
                             "UPDATE " ANNEX_TABLE
                             " SET %s WHERE id IN (SELECT id FROM %s)", fields, tmp_table_name );
                }
                else if ( filter_stripe_info )
                {

                    if ( !tmp_table_created )
                    {
                        /* create temp table */
                        sprintf( tmp_table_name, "TMP_TABLE_%u_%u",
                                 ( unsigned int ) getpid(  ), ( unsigned int ) pthread_self(  ) );

                        sprintf( query,
                                 "CREATE TEMPORARY TABLE %s AS SELECT id FROM "
                                 STRIPE_INFO_TABLE " WHERE %s",
                                 tmp_table_name, filter_str_stripe_info );

                        rc = db_exec_sql( &p_mgr->conn, query, NULL );
                        if ( rc )
                            goto rollback;

                        tmp_table_created = TRUE;
                    }

                    DisplayLog( LVL_MAJOR, LISTMGR_TAG, "WARNING: passing through unoptimized algorithm" );

                    sprintf( query,
                             "UPDATE " ANNEX_TABLE
                             " SET %s WHERE id IN (SELECT id FROM %s)", fields, tmp_table_name );
                }
            }
            else
            {
                /* @todo mixed filter :-s */
                rc = DB_NOT_SUPPORTED;
                goto rollback;
            }

            rc = db_exec_sql( &p_mgr->conn, query, NULL );
            if ( rc )
                goto rollback;
        }
    }


    if ( ATTR_MASK_TEST( p_attr_set, stripe_info ) || ATTR_MASK_TEST( p_attr_set, stripe_items ) )
    {
        /* XXX is there a case where stripe info is to be updated massively ? */
        rc = DB_NOT_SUPPORTED;
        goto rollback;
    }

    if ( tmp_table_created )
    {
        sprintf( query, "DROP TABLE %s", tmp_table_name );
        rc = db_exec_sql( &p_mgr->conn, query, NULL );
        if ( rc )
            goto rollback;
    }

    return lmgr_commit( p_mgr );

  rollback:
    lmgr_rollback( p_mgr );
    return rc;
}
Example #10
0
/**
 * For entries from FS scan, we must get the associated entry ID.
 */
int EntryProc_get_fid( struct entry_proc_op_t *p_op, lmgr_t * lmgr )
{
#ifdef _HAVE_FID
    int            rc;
    entry_id_t     tmp_id;
    char buff[RBH_PATH_MAX];
    char * path;

    /* 2 possible options: get fid using parent_fid/name or from fullpath */
    if (ATTR_MASK_TEST(&p_op->fs_attrs, parent_id)
        && ATTR_MASK_TEST(&p_op->fs_attrs, name))
    {
        BuildFidPath( &ATTR(&p_op->fs_attrs, parent_id), buff );
        long len = strlen(buff);
        sprintf(buff+len, "/%s", ATTR(&p_op->fs_attrs, name));
        path = buff;
    }
    else if (ATTR_MASK_TEST( &p_op->fs_attrs, fullpath))
    {
        path = ATTR(&p_op->fs_attrs, fullpath);
    }
    else
    {
        DisplayLog( LVL_CRIT, ENTRYPROC_TAG,
                    "Error: not enough information to get fid: parent_id/name or fullpath needed");
        EntryProcessor_Acknowledge(p_op, -1, true);
        return EINVAL;
    }

    /* perform path2fid */
    rc = Lustre_GetFidFromPath( path, &tmp_id );

    /* Workaround for Lustre 2.3: if parent is root, llapi_path2fid returns EINVAL (see LU-3245).
     * In this case, get fid from full path.
     */
    if ((rc == -EINVAL) && ATTR_MASK_TEST( &p_op->fs_attrs, fullpath))
    {
        path = ATTR(&p_op->fs_attrs, fullpath);
        rc =  Lustre_GetFidFromPath( path, &tmp_id );
    }

    if ( rc )
    {
        /* remove the operation from pipeline */
        rc = EntryProcessor_Acknowledge(p_op, -1, true);
        if ( rc )
            DisplayLog( LVL_CRIT, ENTRYPROC_TAG,
                        "Error %d acknowledging stage STAGE_GET_FID.", rc );
    }
    else
    {
        EntryProcessor_SetEntryId( p_op, &tmp_id );

        /* go to GET_INFO_DB stage */
        rc = EntryProcessor_Acknowledge(p_op, STAGE_GET_INFO_DB, false);
        if ( rc )
            DisplayLog( LVL_CRIT, ENTRYPROC_TAG,
                        "Error %d acknowledging stage STAGE_GET_FID.", rc );
    }
    return rc;
#else
    DisplayLog( LVL_CRIT, ENTRYPROC_TAG, "Error: unexpected stage in a filesystem with no fid: STAGE_GET_FID.");
    EntryProcessor_Acknowledge(p_op, -1, true);
    return EINVAL;
#endif
}
Example #11
0
/**
 * check if the entry exists in the database and what info
 * must be retrieved.
 */
int EntryProc_get_info_db( struct entry_proc_op_t *p_op, lmgr_t * lmgr )
{
    int      rc = 0;
    int      next_stage = -1; /* -1 = skip */
    attr_mask_t attr_allow_cached = null_mask;
    attr_mask_t attr_need_fresh = null_mask;
    uint32_t status_scope = 0; /* status mask only */
    attr_mask_t tmp;

    const pipeline_stage_t *stage_info =
        &entry_proc_pipeline[p_op->pipeline_stage];

    /* check if entry is in policies scope */
    add_matching_scopes_mask(&p_op->entry_id, &p_op->fs_attrs, true,
                             &status_scope);

    /* XXX also retrieve needed attributes to check the scope? */

    /* get diff attributes from DB and FS (to allow comparison) */
    p_op->db_attr_need = attr_mask_or(&p_op->db_attr_need, &diff_mask);

    tmp = attr_mask_and_not(&diff_mask, &p_op->fs_attrs.attr_mask);
    p_op->fs_attr_need = attr_mask_or(&p_op->fs_attr_need, &tmp);

    if (entry_proc_conf.detect_fake_mtime)
        attr_mask_set_index(&p_op->db_attr_need, ATTR_INDEX_creation_time);

    attr_allow_cached = attrs_for_status_mask(status_scope, false);
    attr_need_fresh = attrs_for_status_mask(status_scope, true);
    /* XXX check if entry is in policy scope? */

    /* what must be retrieved from DB: */
    tmp = attr_mask_and_not(&attr_allow_cached, &p_op->fs_attrs.attr_mask);
    p_op->db_attr_need = attr_mask_or(&p_op->db_attr_need, &tmp);

    /* no dircount for non-dirs */
    if (ATTR_MASK_TEST(&p_op->fs_attrs, type) &&
        !strcmp(ATTR(&p_op->fs_attrs, type), STR_TYPE_DIR))
    {
        attr_mask_unset_index(&p_op->db_attr_need, ATTR_INDEX_dircount);
    }

    /* no readlink for non symlinks */
    if (ATTR_MASK_TEST(&p_op->fs_attrs, type)) /* likely */
    {
        if (!strcmp(ATTR(&p_op->fs_attrs, type), STR_TYPE_LINK))
        {
            attr_mask_set_index(&p_op->db_attr_need, ATTR_INDEX_link); /* check if it is known */
            /* no stripe for symlinks */
            attr_mask_unset_index(&p_op->db_attr_need, ATTR_INDEX_stripe_info);
            attr_mask_unset_index(&p_op->db_attr_need, ATTR_INDEX_stripe_items);
        }
        else
            attr_mask_unset_index(&p_op->db_attr_need, ATTR_INDEX_link);
    }

    if (!attr_mask_is_null(p_op->db_attr_need))
    {
        p_op->db_attrs.attr_mask = p_op->db_attr_need;
        rc = ListMgr_Get(lmgr, &p_op->entry_id, &p_op->db_attrs);

        if (rc == DB_SUCCESS)
        {
            p_op->db_exists = 1;
        }
        else if (rc == DB_NOT_EXISTS )
        {
            p_op->db_exists = 0;
            ATTR_MASK_INIT( &p_op->db_attrs );
        }
        else
        {
            /* ERROR */
            DisplayLog(LVL_CRIT, ENTRYPROC_TAG,
                       "Error %d retrieving entry "DFID" from DB: %s.", rc,
                       PFID(&p_op->entry_id), lmgr_err2str(rc));
            p_op->db_exists = 0;
            ATTR_MASK_INIT( &p_op->db_attrs );
        }
    }
    else
    {
        p_op->db_exists = ListMgr_Exists( lmgr, &p_op->entry_id );
    }

    /* get status for all policies with a matching scope */
    add_matching_scopes_mask(&p_op->entry_id, &p_op->fs_attrs, true,
                             &p_op->fs_attr_need.status);
    tmp = attr_mask_and_not(&attr_need_fresh, &p_op->fs_attrs.attr_mask);
    p_op->fs_attr_need = attr_mask_or(&p_op->fs_attr_need, &tmp);

    if ( !p_op->db_exists )
    {
        /* new entry */
        p_op->db_op_type = OP_TYPE_INSERT;

        /* set creation time if it was not set by scan module */
        if (!ATTR_MASK_TEST(&p_op->fs_attrs, creation_time))
        {
            ATTR_MASK_SET( &p_op->fs_attrs, creation_time );
            ATTR( &p_op->fs_attrs, creation_time ) = time(NULL); /* XXX min(atime,mtime,ctime)? */
        }

#ifdef _LUSTRE
        if (ATTR_MASK_TEST(&p_op->fs_attrs, type)
            && !strcmp(ATTR( &p_op->fs_attrs, type ), STR_TYPE_FILE )
                /* only if it was not retrieved during the scan */
                && !(ATTR_MASK_TEST(&p_op->fs_attrs, stripe_info)
                    && ATTR_MASK_TEST(&p_op->fs_attrs, stripe_items)))
        {
            attr_mask_set_index(&p_op->fs_attr_need, ATTR_INDEX_stripe_info);
            attr_mask_set_index(&p_op->fs_attr_need, ATTR_INDEX_stripe_items);
        }
#endif

        /* readlink for symlinks (if not already known) */
        if (ATTR_MASK_TEST(&p_op->fs_attrs, type)
            && !strcmp(ATTR( &p_op->fs_attrs, type ), STR_TYPE_LINK)
            && !ATTR_MASK_TEST(&p_op->fs_attrs, link))
        {
            attr_mask_set_index(&p_op->fs_attr_need, ATTR_INDEX_link);
        }
        else
        {
            attr_mask_unset_index(&p_op->fs_attr_need, ATTR_INDEX_link);
        }

#ifdef ATTR_INDEX_status /** @FIXME RBHv3 drop old-style status reference */
        if (ATTR_MASK_TEST(&p_op->fs_attrs, type)
#ifdef _LUSTRE_HSM
            && !strcmp( ATTR(&p_op->fs_attrs, type), STR_TYPE_FILE ))
#elif defined (_HSM_LITE)
            && (strcmp( ATTR(&p_op->fs_attrs, type), STR_TYPE_DIR ) != 0)
            && !p_op->extra_info.not_supp)
#endif
        {
            p_op->fs_attr_need |= ATTR_MASK_status;
#ifdef _HSM_LITE
            p_op->fs_attr_need |= (attr_need_fresh & ~p_op->fs_attrs.attr_mask);
#endif
        }
        else
        {
Example #12
0
/**
 * build LOVEA buffer from stripe information
 * @return size of significant information in buffer.
 */
ssize_t BuildLovEA(const entry_id_t * p_id, const attr_set_t * p_attrs, void * buff, size_t buf_sz)
{
    int i;
    size_t len = 0;

    if (!ATTR_MASK_TEST(p_attrs, stripe_info)) /* no stripe info */
        return 0;

    /* check inconsistent values */
    if (!ATTR_MASK_TEST(p_attrs, stripe_items) ||
        (ATTR(p_attrs, stripe_items).count != ATTR(p_attrs, stripe_info).stripe_count))
    {
        DisplayLog(LVL_MAJOR, "BuildLovEA", "ERROR: inconsistent stripe info for "DFID, PFID(p_id));
        return -1;
    }

    /* is there a pool? */
    if (EMPTY_STRING(ATTR(p_attrs, stripe_info).pool_name))
    {
        /* no => build lov_user_md_v1 */
        struct lov_user_md_v1 * p_lum = (struct lov_user_md_v1 *) buff;
        len = sizeof(struct lov_user_md_v1) +
            ATTR(p_attrs, stripe_info).stripe_count * sizeof(struct lov_user_ost_data_v1);

        /* check buffer size */
        if (buf_sz < len)
            return -1;

        p_lum->lmm_magic = LOV_USER_MAGIC_V1;
        p_lum->lmm_pattern = LOV_PATTERN_RAID0; /* the only supported for now */
#ifdef _HAVE_FID
        p_lum->lmm_object_id = p_id->f_oid;
        p_lum->lmm_object_seq = p_id->f_seq;
#else /* lmm_object_gr for Lustre 1.x */
        p_lum->lmm_object_id = p_id->inode;
        p_lum->lmm_object_gr = 0;
#endif
        p_lum->lmm_stripe_size = ATTR(p_attrs, stripe_info).stripe_size;
        p_lum->lmm_stripe_count = ATTR(p_attrs, stripe_info).stripe_count;
        p_lum->lmm_stripe_offset = 0;

        /* set stripe items */
        for ( i = 0; i < ATTR(p_attrs, stripe_items).count; i++ )
        {
            p_lum->lmm_objects[i].l_ost_idx = ATTR(p_attrs, stripe_items).stripe[i].ost_idx;
            p_lum->lmm_objects[i].l_ost_gen = ATTR(p_attrs, stripe_items).stripe[i].ost_gen;
#ifdef HAVE_OBJ_ID
            p_lum->lmm_objects[i].l_object_id = ATTR(p_attrs, stripe_items).stripe[i].obj_id;
#ifdef HAVE_OBJ_SEQ
            p_lum->lmm_objects[i].l_object_seq = ATTR(p_attrs, stripe_items).stripe[i].obj_seq;
#else
            p_lum->lmm_objects[i].l_object_gr = ATTR(p_attrs, stripe_items).stripe[i].obj_seq;
#endif
#else /* new structure (union of fid and id/seq) */
            p_lum->lmm_objects[i].l_ost_oi.oi.oi_id = ATTR(p_attrs, stripe_items).obj_id;
            p_lum->lmm_objects[i].l_ost_oi.oi.oi_seq = ATTR(p_attrs, stripe_items).stripe[i].obj_seq;
#endif
        }
        return len;
    }
    else
    {
        /* yes => build lov_user_md_v3 */
        struct lov_user_md_v3 * p_lum = (struct lov_user_md_v3 *) buff;
        len = sizeof(struct lov_user_md_v3) +
            ATTR(p_attrs, stripe_info).stripe_count * sizeof(struct lov_user_ost_data_v1);

        /* check buffer size */
        if (buf_sz < len)
            return (size_t)-1;

        p_lum->lmm_magic = LOV_USER_MAGIC_V3;
        p_lum->lmm_pattern = LOV_PATTERN_RAID0; /* the only supported for now */
#ifdef _HAVE_FID
        p_lum->lmm_object_id = p_id->f_oid;
        p_lum->lmm_object_seq = p_id->f_seq;
#else /* lmm_object_gr for Lustre 1.x */
        p_lum->lmm_object_id = p_id->inode;
        p_lum->lmm_object_gr = 0;
#endif
        p_lum->lmm_stripe_size = ATTR(p_attrs, stripe_info).stripe_size;
        p_lum->lmm_stripe_count = ATTR(p_attrs, stripe_info).stripe_count;
        p_lum->lmm_stripe_offset = 0;
        /* pool name */
        rh_strncpy(p_lum->lmm_pool_name, ATTR(p_attrs, stripe_info).pool_name, LOV_MAXPOOLNAME);

        /* set stripe items */
        for ( i = 0; i < ATTR(p_attrs, stripe_items).count; i++ )
        {
            p_lum->lmm_objects[i].l_ost_idx = ATTR(p_attrs, stripe_items).stripe[i].ost_idx;
            p_lum->lmm_objects[i].l_ost_gen = ATTR(p_attrs, stripe_items).stripe[i].ost_gen;
#ifdef HAVE_OBJ_ID
            p_lum->lmm_objects[i].l_object_id = ATTR(p_attrs, stripe_items).stripe[i].obj_id;
#ifdef HAVE_OBJ_SEQ
            p_lum->lmm_objects[i].l_object_seq = ATTR(p_attrs, stripe_items).stripe[i].obj_seq;
#else
            p_lum->lmm_objects[i].l_object_gr = ATTR(p_attrs, stripe_items).stripe[i].obj_seq;
#endif
#else /* new structure (union of fid and id/seq) */
            p_lum->lmm_objects[i].l_ost_oi.oi.oi_id = ATTR(p_attrs, stripe_items).obj_id;
            p_lum->lmm_objects[i].l_ost_oi.oi.oi_seq = ATTR(p_attrs, stripe_items).stripe[i].obj_seq;
#endif
        }
        return len;
    }
}
Example #13
0
int listmgr_batch_insert_no_tx(lmgr_t * p_mgr, entry_id_t **p_ids,
                               attr_set_t **p_attrs,
                               unsigned int count,
                               int update_if_exists)
{
    int            rc = 0;
    int            i, full_mask;
    char           fields[1024]; /* field list */
    pktype        *pklist = NULL;
    var_str        query = VAR_STR_NULL;
    char           values[4096] = "";
    char          *values_curr = NULL;
    bool           first;
    /* fake attribute struct, to write generic name fields */
    attr_set_t fake_attrs = *(p_attrs[0]);

    full_mask = sum_masks(p_attrs, count, ~0);
    fake_attrs.attr_mask = full_mask;

    pklist = (pktype *)MemCalloc(count, sizeof(pktype));
    if (pklist == NULL)
        return DB_NO_MEMORY;

    for (i = 0; i < count; i++)
    {
        /* check attr mask */
        if (!lmgr_batch_compat(full_mask, p_attrs[i]->attr_mask))
        {
            DisplayLog(LVL_MAJOR, LISTMGR_TAG, "Incompatible attr mask in batched operation: %#x vs. %#x",
                       p_attrs[i]->attr_mask, full_mask);
            rc = DB_INVALID_ARG;
            goto out_free;
        }
        /* fill pk array */
        entry_id2pk(p_ids[i], PTR_PK(pklist[i])); /* The same for all tables? */
    }

    /* build batch request for main table */
    attrmask2fieldlist(fields, full_mask, T_MAIN, TRUE, FALSE, "", "");

    var_str_append(&query, "INSERT INTO " MAIN_TABLE "(id");
    var_str_append(&query, fields);
    var_str_append(&query, ") VALUES ");

    first = true;
    for (i = 0; i < count; i++)
    {
        /* don't set this entry if no attribute is in main table */
        if ((p_attrs[i]->attr_mask & main_attr_set) == 0)
            continue;

        values_curr = values + sprintf(values, DPK, pklist[i]);
        attrset2valuelist(p_mgr, values_curr, p_attrs[i], T_MAIN, TRUE);

        /* add "[,](values)" to query */
        var_str_append(&query, first ? "(" : ",(");
        var_str_append(&query, values);
        var_str_append(&query, ")");
        first = false;
    }

    if (update_if_exists)
    {
        /* append "on duplicate key ..." */
        attrset2updatelist(p_mgr, values, &fake_attrs, T_MAIN, FALSE, TRUE);
        var_str_append(&query, " ON DUPLICATE KEY UPDATE ");
        var_str_append(&query, values);
    }

    rc = db_exec_sql(&p_mgr->conn, VAR_STR_START(query), NULL);
    if (rc)
        goto out_free;

    var_str_reset(&query);

    /* allow inserting entries in MAIN_TABLE, without name information */

    /* both parent and name are defined */
    if ((full_mask & ATTR_MASK_name) && (full_mask & ATTR_MASK_parent_id))
    {
        /* build batch request for names table */
        attrmask2fieldlist(fields, full_mask, T_DNAMES, TRUE, FALSE, "", "");

        var_str_append(&query, "INSERT INTO " DNAMES_TABLE "(id");
        var_str_append(&query, fields);
        var_str_append(&query, ",pkn) VALUES ");

        first = true;
        for (i = 0; i < count; i++)
        {
            /* don't set this entry if parent or name is missing */
            if (!ATTR_MASK_TEST(p_attrs[i], name) || !ATTR_MASK_TEST(p_attrs[i], parent_id))
            {
                /* warn for create operations without name information */
                if (!update_if_exists)
                    no_name_warning(pklist[i], p_attrs[i], 1);

                continue;
            }

            values_curr = values + sprintf(values, DPK, pklist[i]);
            attrset2valuelist(p_mgr, values_curr, p_attrs[i], T_DNAMES, TRUE);

            /* add "[,](values,<pk>)" to query */
            var_str_append(&query, first ? "(" : ",(");
            var_str_append(&query, values);
            var_str_append(&query, ","HNAME_DEF")");
            first = false;
        }

        values_curr = values + sprintf(values, "id=VALUES(id)"); /* not part of the PK */
        attrset2updatelist(p_mgr, values_curr, &fake_attrs, T_DNAMES, TRUE, TRUE);
        var_str_append(&query, " ON DUPLICATE KEY UPDATE ");
        var_str_append(&query, values);

        rc = db_exec_sql(&p_mgr->conn, VAR_STR_START(query), NULL);
        if (rc)
            goto out_free;

    } else if (!update_if_exists) { /* only warn for create operations */

        /* if we get here, the name information is missing in all fields.
         * use entry[0] as example for the warning message. */
        no_name_warning(pklist[0], p_attrs[0], count);
    }

    var_str_reset(&query);

    /* insert all info in annex table, if any */
    if (annex_table && (full_mask & annex_attr_set))
    {
        /* Create field and values lists.
         * Do nothing if no fields are to be set.
         */
        if (attrmask2fieldlist(fields, full_mask, T_ANNEX, TRUE, FALSE, "", "") > 0)
        {

            var_str_append(&query, "INSERT INTO "ANNEX_TABLE "(id");
            var_str_append(&query, fields);
            var_str_append(&query, ") VALUES ");

            first = true;
            for (i = 0; i < count; i++)
            {
                char           values[4096] = "";
                char          *values_curr = NULL;

                /* don't set this entry if no attribute is in annex table */
                if ((p_attrs[i]->attr_mask & annex_attr_set) == 0)
                    continue;

                sprintf(values, DPK, pklist[i]);
                values_curr = values + strlen(values);
                attrset2valuelist(p_mgr, values_curr, p_attrs[i], T_ANNEX, TRUE);

                /* add "[,](values)" to query */
                var_str_append(&query, first ? "(" : ",(");
                var_str_append(&query, values);
                var_str_append(&query, ")");
                first = false;
            }

            /* always update as having the entry in the main table
             * is the reference to know if we knew the entry */
            /* append "on duplicate key ..." */
            attrset2updatelist(p_mgr, values, &fake_attrs, T_ANNEX, FALSE, TRUE);
            var_str_append(&query, " ON DUPLICATE KEY UPDATE ");
            var_str_append(&query, values);

            rc = db_exec_sql(&p_mgr->conn, VAR_STR_START(query), NULL);
            if (rc)
                goto out_free;
        }
    }

#ifdef _LUSTRE
    /* batch insert of striping info */
    if (ATTR_MASK_TEST(&fake_attrs, stripe_info) || ATTR_MASK_TEST(&fake_attrs, stripe_items))
    {
        /* create validator list */
        int *validators = (int*)MemCalloc(count, sizeof(int));
        if (!validators)
        {
            rc =  DB_NO_MEMORY;
            goto out_free;
        }
        for (i = 0; i < count; i++)
#ifdef HAVE_LLAPI_FSWAP_LAYOUTS
            validators[i] = ATTR_MASK_TEST(p_attrs[i], stripe_info)?
                                ATTR(p_attrs[i],stripe_info).validator:VALID_NOSTRIPE;
#else
            validators[i] = VALID(p_ids[i]);
#endif

        rc = batch_insert_stripe_info(p_mgr, pklist, validators, p_attrs,
                                      count, TRUE);
        MemFree(validators);
        if (rc)
            goto out_free;
    }
#endif

out_free:
    var_str_free(&query);
    MemFree(pklist);
    return rc;
}
Example #14
0
/**
 * Output the desired information for one file.
 */
void printf_entry(GArray *chunks, const wagon_t *id, const attr_set_t *attrs)
{
    int i;

    for (i = 0; i < chunks->len; i++) {
        struct fchunk *chunk = &g_array_index(chunks, struct fchunk, i);
        const char *format = chunk->format->str;

        switch (chunk->directive) {
        case 0:
#if __GNUC__ >= 7
/*
 * "format" below is constructed safely, ignore the warning.
 * Old GCC versions do not like these statements
 */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-security"
#endif
            printf(format);
#if __GNUC__ >= 7
#pragma GCC diagnostic pop
#endif
            break;

        case 'A':
            printf_date(chunk, ATTR(attrs, last_access));
            break;

        case 'b':
            printf(format, ATTR(attrs, blocks));
            break;

        case 'C':
            printf_date(chunk, ATTR(attrs, last_mdchange));
            break;

        case 'd':
            printf(format, ATTR(attrs, depth));
            break;

        case 'f':
            printf(format, ATTR(attrs, name));
            break;

        case 'g':
            if (global_config.uid_gid_as_numbers)
                printf(format, ATTR(attrs, gid).num);
            else
                printf(format, ATTR(attrs, gid).txt);
            break;

        case 'm':
            printf(format, ATTR(attrs, mode));
            break;

        case 'M':
            {
                char mode_str[10];  /* mask + final '\0' */

                mode_str[9] = 0;
                mode_string(ATTR(attrs, mode), mode_str);

                printf(format, mode_str);
            }
            break;

        case 'n':
            printf(format, ATTR(attrs, nlink));
            break;

        case 'p':
            if (prog_options.escaped)
                printf(format, escape_name(id->fullname));
            else
                printf(format, id->fullname);
            break;

        case 's':
            printf(format, ATTR(attrs, size));
            break;

        case 'T':
            printf_date(chunk, ATTR(attrs, last_mod));
            break;

        case 'u':
            if (global_config.uid_gid_as_numbers)
                printf(format, ATTR(attrs, uid).num);
            else
                printf(format, ATTR(attrs, uid).txt);
            break;

        case 'Y':
            {
                const char *type;

                if (!ATTR_MASK_TEST(attrs, type))
                    type = "?";
                else
                    type = type2char(ATTR(attrs, type));

                printf(format, type);
            }
            break;

        case 'y':
            {
                char type;

                if (!ATTR_MASK_TEST(attrs, type))
                    type = '?';
                else
                    type = type2onechar(ATTR(attrs, type));

                printf(format, type);
            }
            break;

        case 'z':
            printf(format, 0);
            break;

        case 'R':
            /* Robinhood specifiers */
            switch (chunk->sub_directive) {
            case 'C':
                printf_date(chunk, ATTR(attrs, creation_time));
                break;

            case 'c':
                printf(format,
                       class_format(ATTR_MASK_TEST(attrs, fileclass) ?
                                    ATTR(attrs, fileclass) : NULL));
                break;

            case 'f':
                {
                    char fid_str[RBH_FID_LEN];

                    sprintf(fid_str, DFID_NOBRACE, PFID(&id->id));
                    printf(format, fid_str);
                }
                break;

            case 'm':
                if (ATTR_MASK_INFO_TEST(attrs, chunk->smi,
                                        chunk->rel_sm_info_index)) {
                    switch (chunk->def->db_type) {
                    case DB_UINT:
                        printf(format,
                               *(unsigned int *)SMI_INFO(attrs, chunk->smi,
                                                         chunk->
                                                         rel_sm_info_index));
                        break;

                    case DB_INT:
                        printf(format,
                               *(int *)SMI_INFO(attrs, chunk->smi,
                                                chunk->rel_sm_info_index));
                        break;

                    case DB_BOOL:
                        printf(format,
                               *(bool *)SMI_INFO(attrs, chunk->smi,
                                                 chunk->rel_sm_info_index));
                        break;

                    case DB_TEXT:
                        printf(format,
                               SMI_INFO(attrs, chunk->smi,
                                        chunk->rel_sm_info_index));
                        break;

                    default:
                        break;
                    }
                } else {
                    switch (chunk->def->db_type) {
                    case DB_UINT:
                    case DB_INT:
                        printf(format, 0);
                        break;

                    case DB_TEXT:
                        printf(format, "[n/a]");
                        break;

                    default:
                        break;
                    }
                }
                break;

#ifdef _LUSTRE
            case 'o':
                if (ATTR_MASK_TEST(attrs, stripe_items) &&
                    (ATTR(attrs, stripe_items).count > 0)) {
                    GString *osts = g_string_new("");

                    append_stripe_list(osts, &ATTR(attrs, stripe_items), true);
                    printf(format, osts->str);
                    g_string_free(osts, TRUE);
                }
                break;

            case 'p':
                {
                    char fid_str[RBH_FID_LEN];

                    sprintf(fid_str, DFID_NOBRACE,
                            PFID(&ATTR(attrs, parent_id)));
                    printf(format, fid_str);

                    break;
                }
#endif

            case SUB_DIRECTIVE_STATUS:
                {
                    unsigned int smi_index = chunk->smi->smi_index;

                    if (ATTR_MASK_STATUS_TEST(attrs, smi_index))
                        printf(format, STATUS_ATTR(attrs, smi_index));
                    else
                        printf(format, "[n/a]");

                    break;
                }

            }
            break;
        }
    }
}
Example #15
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 #16
0
int ListMgr_Update( lmgr_t * p_mgr, const entry_id_t * p_id, const attr_set_t * p_update_set )
{
    int            rc, main_count, annex_count;
    char           query[4096];
    char           fields[4096];
    char           annex_fields[4096];
    DEF_PK(pk);
    int            nb_tables = 0;

    /* read only fields in info mask? */
    if ( readonly_attr_set & p_update_set->attr_mask )
    {
        DisplayLog( LVL_MAJOR, LISTMGR_TAG, "Error: trying to update read only values: attr_mask=%#x",
                    readonly_attr_set & p_update_set->attr_mask );
        return DB_INVALID_ARG;
    }

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

    /* check how many tables are to be updated */
    if ( main_fields( p_update_set->attr_mask ) )
    {
        main_count = attrset2updatelist( p_mgr, fields, p_update_set, T_MAIN, FALSE );
        if ( main_count < 0 )
            return -main_count;
        if ( main_count > 0 )
            nb_tables++;
    }
    else
        main_count = 0;

    if ( annex_table && annex_fields( p_update_set->attr_mask ) )
    {
        annex_count = attrset2updatelist( p_mgr, annex_fields, p_update_set, T_ANNEX, FALSE );
        if ( annex_count < 0 )
            return -annex_count;
        if ( annex_count > 0 )
            nb_tables++;
    }
    else
        annex_count = 0;


    if ( stripe_fields( p_update_set->attr_mask ) )
        nb_tables += 2;

    /* if only 1 table is impacted, switch to autocommit mode */
    if ( nb_tables > 1 )
    {
        /* @todo in the case of sqlite, we may want to do periodic commit
         * instead of systematic one. */
        rc = lmgr_begin( p_mgr );
        if ( rc )
            return rc;
    }

    /* update main table */

    if ( main_count > 0 )
    {
        sprintf( query, "UPDATE " MAIN_TABLE " SET %s WHERE id="DPK, fields, pk );
        rc = db_exec_sql( &p_mgr->conn, query, NULL );
        if ( rc )
            goto rollback;
    }

    /* update annex table (if any) */
    if ( annex_count > 0 )
    {
        sprintf( query, "UPDATE " ANNEX_TABLE " SET %s WHERE id="DPK, annex_fields, pk );
        rc = db_exec_sql( &p_mgr->conn, query, NULL );
        if ( rc )
            goto rollback;
    }

    /* insert new stripe info if provided (and eventually remove previous values) */
    if ( ATTR_MASK_TEST( p_update_set, stripe_info ) )
    {
        rc = insert_stripe_info( p_mgr, pk, VALID(p_id), &ATTR( p_update_set, stripe_info ),
                                 ATTR_MASK_TEST( p_update_set, stripe_items ) ?
                                    &ATTR( p_update_set, stripe_items ) : NULL, TRUE );
        if ( rc )
            goto rollback;
    }


    if ( nb_tables > 1 )
        return lmgr_commit( p_mgr );
    else
        return DB_SUCCESS;

  rollback:
    lmgr_rollback( p_mgr );
    return rc;
}
Example #17
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 #18
0
int batch_insert_stripe_info(lmgr_t *p_mgr, pktype *pklist, int *validators,
                             attr_set_t **p_attrs, unsigned int count,
                             bool update_if_exists)
{
    bool first;
    int i, rc = 0;
    int total_si;
    GString *req = g_string_new("");
    attr_mask_t tmp_mask = { ATTR_MASK_stripe_info, 0, 0LL };

    if (!attr_mask_is_null(sum_masks(p_attrs, count, tmp_mask))) {
        /* build batch request for STRIPE_INFO table */
        g_string_assign(req, "INSERT INTO " STRIPE_INFO_TABLE " ("
                        STRIPE_INFO_FIELDS ") VALUES ");

        first = true;
        for (i = 0; i < count; i++) {
            /* no request if the entry has no stripe info */
            if (!ATTR_MASK_TEST(p_attrs[i], stripe_info))
                continue;

            g_string_append_printf(req, "%s(" DPK ",%d,%u,%u,'%s')",
                                   first ? "" : ",", pklist[i], validators[i],
                                   ATTR(p_attrs[i], stripe_info).stripe_count,
                                   (unsigned int)ATTR(p_attrs[i],
                                                      stripe_info).stripe_size,
                                   ATTR(p_attrs[i], stripe_info).pool_name);
            first = false;
        }

        if (update_if_exists)
            /* append "on duplicate key ..." */
            g_string_append(req,
                            " ON DUPLICATE KEY UPDATE " STRIPE_INFO_SET_VALUES);

        if (!first) {   /* do nothing if no entry had stripe info */
            rc = db_exec_sql(&p_mgr->conn, req->str, NULL);
            if (rc)
                goto out;
        }
        /* reset the string */
        g_string_assign(req, "");
    }

    /* Stripe items more tricky because we want to delete previous items
     * on update. */
    /* If update_if_exists is false, insert them all as a batch.
     * For the update case, remove previous items before bluk insert.
     */
    if (update_if_exists) {
        for (i = 0; i < count; i++) {
            /* no request if the entry has no stripe items */
            if (!ATTR_MASK_TEST(p_attrs[i], stripe_items))
                continue;

            g_string_printf(req,
                            "DELETE FROM " STRIPE_ITEMS_TABLE " WHERE id=" DPK,
                            pklist[i]);

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

    /* bulk insert stripe items (if any is set) */
    tmp_mask.std = ATTR_MASK_stripe_items;
    if (attr_mask_is_null(sum_masks(p_attrs, count, tmp_mask)))
        goto out;

    total_si = 0;
    first = true;
    g_string_assign(req, "INSERT INTO " STRIPE_ITEMS_TABLE
                    " (" STRIPE_ITEMS_FIELDS ") VALUES ");

    /* loop on all entries and all stripe items */
    for (i = 0; i < count; i++) {
        int s;
        const stripe_items_t *p_items;

        /* skip the entry if it has no stripe items */
        if (!ATTR_MASK_TEST(p_attrs[i], stripe_items))
            continue;

        p_items = &ATTR(p_attrs[i], stripe_items);
        for (s = 0; s < p_items->count; s++) {
            char buff[2 * STRIPE_DETAIL_SZ + 1];

            total_si++;
            if (buf2hex
                (buff, sizeof(buff),
                 (unsigned char *)(&p_items->stripe[s].ost_gen),
                 STRIPE_DETAIL_SZ) < 0) {
                DisplayLog(LVL_CRIT, LISTMGR_TAG,
                           "Buffer too small to store details stripe info");
                memset(buff, 0, sizeof(buff));
            }
            g_string_append_printf(req, "%s(" DPK ",%u,%u,x'%s')",
                                   first && (s == 0) ? "" : ",", pklist[i],
                                   s, p_items->stripe[s].ost_idx, buff);
            first = false;
        }
    }

    /* only execute it if there was some stripe items */
    if (total_si > 0)
        rc = db_exec_sql(&p_mgr->conn, req->str, NULL);

 out:
    g_string_free(req, TRUE);
    return rc;
}