Beispiel #1
0
void
bdb_open(void)
{
	DB *db;
	DBC *dbc;
	DB_ENV *dbenv;

	assert(db_env_create(&dbenv, 0) == 0);
	dbenv->set_errpfx(dbenv, "bdb");
	dbenv->set_errfile(dbenv, stderr);
	assert(dbenv->mutex_set_max(dbenv, 10000) == 0);
	assert(dbenv->set_cachesize(dbenv, 0, 50 * 1024 * 1024, 1) == 0);
	assert(dbenv->open(dbenv, NULL,
	    DB_CREATE |
	    (g.c_delete_pct == 0 && g.c_insert_pct == 0 && g.c_write_pct == 0 ?
	    0 : DB_INIT_LOCK) |
	    DB_INIT_MPOOL | DB_PRIVATE, 0) == 0);
	assert(db_create(&db, dbenv, 0) == 0);

	if (g.c_file_type == ROW && g.c_reverse)
		assert(db->set_bt_compare(db, bdb_compare_reverse) == 0);

	assert(db->open(db, NULL, "__bdb", NULL, DB_BTREE, DB_CREATE, 0) == 0);
	g.bdb = db;
	assert(db->cursor(db, NULL, &dbc, 0) == 0);
	g.dbc = dbc;

	key_gen_setup(&keybuf);
}
Beispiel #2
0
DB *sg_open_db(DB_ENV *dbenv, char *filename,
	       int (*bt_compare_fcn)(DB *, const DBT *, const DBT *) )
{
    int ret;
    DB *dbp = NULL;

    if ((ret = db_create(&dbp, dbenv , 0)) != 0) {
	ci_debug_printf(1, "db_create: %s\n", db_strerror(ret));
	return NULL;
    }
    //     dbp->set_flags(dbp, DB_DUP);
    dbp->set_bt_compare(dbp, bt_compare_fcn);


#if(DB_VERSION_MINOR>=1)
    if ((ret = dbp->open( dbp, NULL, filename, NULL,
			  DB_BTREE, DB_RDONLY|DB_THREAD, 0)) != 0)
#else
	if ((ret = dbp->open( dbp, filename, NULL,
			      DB_BTREE, DB_RDONLY, 0)) != 0)
#endif
	{
	    ci_debug_printf(1, "open db %s: %s\n", filename, db_strerror(ret));
	    dbp->close(dbp, 0);
	    return NULL;
	}
    return dbp;
}
Beispiel #3
0
void
bdb_open(void)
{
	DB *db;
	DBC *dbc;
	DB_ENV *dbenv;

	assert(db_env_create(&dbenv, 0) == 0);
	dbenv->set_errpfx(dbenv, "bdb");
	dbenv->set_errfile(dbenv, stderr);
	assert(dbenv->mutex_set_max(dbenv, 10000) == 0);
	assert(dbenv->set_cachesize(dbenv, 0, 50 * 1024 * 1024, 1) == 0);
	assert(dbenv->open(dbenv, NULL,
	    DB_CREATE | DB_INIT_LOCK | DB_INIT_MPOOL | DB_PRIVATE, 0) == 0);
	assert(db_create(&db, dbenv, 0) == 0);

	if (g.c_reverse)
		assert(db->set_bt_compare(db, bdb_compare_reverse) == 0);

	assert(db->open(
	    db, NULL, g.home_bdb, NULL, DB_BTREE, DB_CREATE, 0) == 0);
	g.bdb = db;
	assert(db->cursor(db, NULL, &dbc, 0) == 0);
	g.dbc = dbc;

	key_gen_init(&keyitem);
}
Beispiel #4
0
int pctlmfdb_open(struct pctldb_st *pctldb,
		  struct pctldb_param_st *param, int *dberror){

  DB *mfdbp = NULL;
  int status;
  uint32_t dbflags = PCTLMFDB_FLAGS;

  status = db_create(&mfdbp, param->dbenv, 0);

  if(status == 0)
    status = mfdbp->set_bt_compare(mfdbp, timespec_cmp);

  if(status == 0)
    status = mfdbp->open(mfdbp, NULL, param->mfdbname, NULL, DB_BTREE, dbflags,
			 param->mode);

  if(status != 0){
    if(mfdbp != NULL)
      mfdbp->close(mfdbp, 0);

    *dberror = status;
    status = -1;
  }

  if(status == 0)
    pctldb->mfdbp = mfdbp;

  return(status);
}
Beispiel #5
0
DB *icalbdbset_bdb_open(const char *path, const char *subdb, int dbtype, int mode, u_int32_t flag)
{
    DB *dbp = NULL;
    int ret;
    u_int32_t flags;

    /* Initialize the correct set of db subsystems (see capdb.c) */
    flags = (u_int32_t) (DB_CREATE | DB_THREAD);

    /* should just abort here instead of opening an env in the current dir..  */
    if (!ICAL_DB_ENV) {
        if (icalbdbset_init_dbenv(NULL, NULL) != 0) {
            return NULL;
        }
    }

    /* Create and initialize database object, open the database. */
    if ((ret = db_create(&dbp, ICAL_DB_ENV, 0)) != 0) {
        return NULL;
    }

    /* set comparison function, if BTREE */
    if (dbtype == DB_BTREE) {
        dbp->set_bt_compare(dbp, _compare_keys);
    }

    /* set DUP, DUPSORT */
    if (flag != 0) {
        dbp->set_flags(dbp, flag);
    }

    if ((ret = dbp->open(dbp, NULL, path, subdb, dbtype, flags, mode)) != 0) {
        ICAL_DB_ENV->err(ICAL_DB_ENV, ret, "%s (database: %s): open failed.", path, subdb);
        if (ret == DB_RUNRECOVERY) {
            abort();
        } else {
            return NULL;
        }
    }

    return dbp;
}
Beispiel #6
0
/*
 * csv_secondary_open --
 *	Open any secondary indices.
 */
int
csv_secondary_open()
{
    DB *sdb;
    DbField *f;
    int ret, (*fcmp)(DB *, const DBT *, const DBT *);

    /*
     * Create secondary database handles.
     */
    for (f = fieldlist; f->name != NULL; ++f) {
        if (f->indx == 0)
            continue;

        if ((ret = db_create(&sdb, dbenv, 0)) != 0) {
            dbenv->err(dbenv, ret, "db_create");
            return (1);
        }
        sdb->app_private = f;

        /* Keys are small, use a relatively small page size. */
        if ((ret = sdb->set_pagesize(sdb, 8 * 1024)) != 0) {
            dbenv->err(dbenv, ret, "DB->set_pagesize");
            return (1);
        }

        /*
         * Sort the database based on the underlying type.  Skip
         * strings, Berkeley DB defaults to lexicographic sort.
         */
        switch (f->type) {
        case DOUBLE:
            fcmp = compare_double;
            break;
        case ULONG:
            fcmp = compare_ulong;
            break;
        case NOTSET:
        case STRING:
        default:
            fcmp = NULL;
            break;
        }
        if (fcmp != NULL &&
                (ret = sdb->set_bt_compare(sdb, fcmp)) != 0) {
            dbenv->err(dbenv, ret, "DB->set_bt_compare");
            return (1);
        }

        /* Always configure secondaries for sorted duplicates. */
        if ((ret = sdb->set_flags(sdb, DB_DUPSORT)) != 0) {
            dbenv->err(dbenv, ret, "DB->set_flags");
            return (1);
        }
        if ((ret = sdb->set_dup_compare(sdb, compare_ulong)) != 0) {
            dbenv->err(dbenv, ret, "DB->set_dup_compare");
            return (1);
        }

        if ((ret = sdb->open(
                       sdb, NULL, f->name, NULL, DB_BTREE, DB_CREATE, 0)) != 0) {
            dbenv->err(dbenv, ret, "DB->open: %s", f->name);
            return (1);
        }
        if ((ret = sdb->associate(
                       db, NULL, sdb, secondary_callback, DB_CREATE)) != 0) {
            dbenv->err(dbenv, ret, "DB->set_associate");
            return (1);
        }
        f->secondary = sdb;
    }

    return (0);
}
Beispiel #7
0
/*
 *  worker function shared between top10Users and top10Groups
 *
 *  Creates in-memory only database to store temporary results
 *  as long as done == FALSE.  As soon as done is set to TRUE,
 *  generate the top10 lists for the database.
 *
 *  The results parameter is used to pass the database pointer around
 *  while calculating, then changes to an agg_type_t when complete.
 *
 */
static int
do_top10(filinfo_t *filinfo, filvar_t *filvar, boolean_t done,	/* ARGSUSED */
         fm_rptno_t which, fmFuncRes_t *results)
{
    int		st;
    DB		*dbp;
    DBC		*curs;
    DBT		key;
    DBT		data;
    DB_TXN		*txn = NULL;
    agg_size_t	agg;
    agg_list_t	*agglist = NULL;
    agg_size_t	*aggp;
    int		i;
    agg_size_t	*aggreport;

    dbp = results->rptDB;

    if (done == FALSE) {
        if ((filinfo == NULL) || (filvar == NULL)) {
            return (-1);
        }

        if (dbp == NULL) {
            st = db_create(&dbp, dbEnv, 0);
            if (st != 0) {
                return (st);
            }
            /* no duplicates, sort on id */
            st = dbp->set_bt_compare(dbp, bt_compare_uint64);
            if (st != 0) {
                dbp->remove(dbp, NULL, NULL, 0);
                return (st);
            }

            st = dbp->open(dbp, NULL, NULL, NULL, DB_BTREE,
                           db_fl, 0644);
            if (st != 0) {
                dbp->remove(dbp, NULL, NULL, 0);
                return (st);
            }

            results->rptDB = dbp;
        }

        memset(&agg, 0, sizeof (agg_size_t));

        if (which == TOP_USERS) {
            agg.id = filinfo->owner;
        } else {
            agg.id = filinfo->group;
        }

        /* fetch id info if it exists */
        memset(&key, 0, sizeof (DBT));
        memset(&data, 0, sizeof (DBT));

        key.data = &agg.id;
        key.size = sizeof (uint64_t);

        data.data = &agg;
        data.size = data.ulen = sizeof (agg_size_t);
        data.flags = DB_DBT_USERMEM;

        dbEnv->txn_begin(dbEnv, NULL, &txn, 0);
        st = dbp->get(dbp, txn, &key, &data, 0);

        if ((st != 0) && (st != DB_NOTFOUND)) {
            txn->abort(txn);
            return (st);
        }

        agg.count++;
        agg.total_size += filinfo->size;
        agg.total_osize += filinfo->osize;

        st = dbp->put(dbp, txn, &key, &data, 0);
        if (st == 0) {
            st = txn->commit(txn, 0);
        } else {
            txn->abort(txn);
        }
    }

    /* final processing */
    if (done == TRUE) {
        uint64_t	aggid = 0;
        int 		numids = 0;
        agg_list_t	*aggent;
        agg_list_t	*ptr;
        agg_list_t	*last;

        if (dbp == NULL) {
            return (-1);
        }

        dbEnv->txn_begin(dbEnv, NULL, &txn, 0);

        st = dbp->cursor(dbp, txn, &curs, 0);
        if (st != 0) {
            /* blast db? */
            txn->abort(txn);
            return (st);
        }

        memset(&key, 0, sizeof (DBT));
        memset(&data, 0, sizeof (DBT));

        key.data = &aggid;
        key.size = key.ulen = sizeof (uint64_t);
        key.flags = DB_DBT_USERMEM;

        data.flags = DB_DBT_MALLOC;

        /* fetch first entry */
        while ((st = curs->c_get(curs, &key, &data, DB_NEXT)) == 0) {
            aggp = (agg_size_t *)data.data;
            last = NULL;

            if (agglist == NULL) {
                aggent = malloc(sizeof (agg_list_t));
                aggent->agg = aggp;

                aggent->prev = NULL;
                aggent->next = NULL;
                agglist = aggent;

                numids = 1;
                continue;
            }

            ptr = agglist;

            while (ptr != NULL) {
                last = ptr;
                if (aggp->total_size >
                        ptr->agg->total_size) {
                    break;
                }
                ptr = ptr->next;
            }

            if ((ptr != NULL) || (numids < 10)) {
                aggent = malloc(sizeof (agg_list_t));
                if (aggent == NULL) {
                    st = ENOMEM;
                    goto done;
                }
                aggent->agg = aggp;
                aggent->next = ptr;
                if (ptr != NULL) {
                    aggent->prev = ptr->prev;
                    if (ptr->prev != NULL) {
                        ptr->prev->next = aggent;
                    }
                    ptr->prev = aggent;
                } else {
                    aggent->prev = last;
                    if (last != NULL) {
                        last->next = aggent;
                    }
                }

                if (aggent->prev == NULL) {
                    agglist = aggent;
                }
                numids++;
                aggp = NULL;
            }

            if (numids > 10) {
                ptr = agglist;

                while (ptr->next != NULL) {
                    ptr = ptr->next;
                }

                free(ptr->agg);
                ptr->prev->next = NULL;
                free(ptr);
                numids--;
            }

            if (aggp != NULL) {
                free(aggp);
            }
        }

        /* done with the in-mem database now */
        (void) curs->c_close(curs);
        (void) txn->commit(txn, 0);

        (void) dbp->close(dbp, 0);
        results->rptDB = NULL;

        if ((st != 0) && (st != DB_NOTFOUND)) {
            /* something bad happened */
            goto done;
        }

        /* got the top 10, allocate the final structure */
        results->rptSize = 10 * (sizeof (agg_size_t));
        aggreport = calloc(1, results->rptSize);
        results->result = (void *)aggreport;

        if (aggreport == NULL) {
            st = ENOMEM;
            goto done;
        }

        ptr = agglist;

        for (i = 0; ptr != NULL; i++) {
            aggp = ptr->agg;
            memcpy(&aggreport[i], aggp, sizeof (agg_size_t));
            ptr = ptr->next;
        }

        st = 0;
done:
        while (agglist != NULL) {
            ptr = agglist;
            agglist = ptr->next;

            free(ptr->agg);
            free(ptr);
        }

    }

    return (st);
}
Beispiel #8
0
Datei: db3.c Projekt: xrg/RPM
static int db3open(rpmdb rpmdb, rpmTag rpmtag, dbiIndex * dbip)
{
    extern const struct _dbiVec db3vec;
    const char * root;
    const char * home;
    char * dbhome;
    const char * dbfile;
    const char * dbsubfile;
    dbiIndex dbi = NULL;
    int rc = 0;
    int xx;

    DB * db = NULL;
    DB_ENV * dbenv = NULL;
    DB_TXN * txnid = NULL;
    uint32_t oflags;
    int _printit;

    if (dbip)
	*dbip = NULL;

    /*
     * Parse db configuration parameters.
     */
    if ((dbi = db3New(rpmdb, rpmtag)) == NULL)
	return 1;
    dbi->dbi_api = DB_VERSION_MAJOR;

    /*
     * Get the prefix/root component and directory path.
     */
    root = (dbi->dbi_root ? dbi->dbi_root : rpmdb->db_root);
    if ((root[0] == '/' && root[1] == '\0') || rpmdb->db_chrootDone)
	root = NULL;
    home = (dbi->dbi_home ? dbi->dbi_home : rpmdb->db_home);

    dbhome = rpmGenPath(root, home, NULL);
    if (dbi->dbi_temporary) {
	dbfile = NULL;
	dbsubfile = NULL;
    } else {
#ifdef	HACK	/* XXX necessary to support dbsubfile */
	dbfile = (dbi->dbi_file ? dbi->dbi_file : db3basename);
	dbsubfile = (dbi->dbi_subfile ? dbi->dbi_subfile : rpmTagGetName(dbi->dbi_rpmtag));
#else
	dbfile = (dbi->dbi_file ? dbi->dbi_file : rpmTagGetName(dbi->dbi_rpmtag));
	dbsubfile = NULL;
#endif
    }

    oflags = (dbi->dbi_oeflags | dbi->dbi_oflags);
    oflags &= ~DB_TRUNCATE;	/* XXX this is dangerous */

#if 0	/* XXX rpmdb: illegal flag combination specified to DB->open */
    if ( dbi->dbi_mode & O_EXCL) oflags |= DB_EXCL;
#endif

    /*
     * Map open mode flags onto configured database/environment flags.
     */
    if (dbi->dbi_temporary) {
	oflags |= DB_CREATE;
	dbi->dbi_oeflags |= DB_CREATE;
	oflags &= ~DB_RDONLY;
	dbi->dbi_oflags &= ~DB_RDONLY;
    } else {
	if ((dbi->dbi_mode & O_ACCMODE) == O_RDONLY) oflags |= DB_RDONLY;
	if (dbi->dbi_mode & O_CREAT) {
	    oflags |= DB_CREATE;
	    dbi->dbi_oeflags |= DB_CREATE;
	}
#ifdef	DANGEROUS
	if ( dbi->dbi_mode & O_TRUNC) oflags |= DB_TRUNCATE;
#endif
    }

    /*
     * Create the /var/lib/rpm directory if it doesn't exist (root only).
     */
    (void) rpmioMkpath(dbhome, 0755, getuid(), getgid());

    /*
     * Avoid incompatible DB_CREATE/DB_RDONLY flags on DBENV->open.
     */
    if (dbi->dbi_use_dbenv) {

	if (access(dbhome, W_OK) == -1) {

	    /* dbhome is unwritable, don't attempt DB_CREATE on DB->open ... */
	    oflags &= ~DB_CREATE;

	    /* ... but DBENV->open might still need DB_CREATE ... */
	    if (dbi->dbi_eflags & DB_PRIVATE) {
		dbi->dbi_eflags &= ~DB_JOINENV;
	    } else {
		dbi->dbi_eflags |= DB_JOINENV;
		dbi->dbi_oeflags &= ~DB_CREATE;
		dbi->dbi_oeflags &= ~DB_THREAD;
		/* ... but, unless DB_PRIVATE is used, skip DBENV. */
		dbi->dbi_use_dbenv = 0;
	    }

	    /* ... DB_RDONLY maps dbhome perms across files ...  */
	    if (dbi->dbi_temporary) {
		oflags |= DB_CREATE;
		dbi->dbi_oeflags |= DB_CREATE;
		oflags &= ~DB_RDONLY;
		dbi->dbi_oflags &= ~DB_RDONLY;
	    } else {
		oflags |= DB_RDONLY;
		/* ... and DB_WRITECURSOR won't be needed ...  */
		dbi->dbi_oflags |= DB_RDONLY;
	    }

	} else {	/* dbhome is writable, check for persistent dbenv. */
	    char * dbf = rpmGetPath(dbhome, "/__db.001", NULL);

	    if (access(dbf, F_OK) == -1) {
		/* ... non-existent (or unwritable) DBENV, will create ... */
		dbi->dbi_oeflags |= DB_CREATE;
		dbi->dbi_eflags &= ~DB_JOINENV;
	    } else {
		/* ... pre-existent (or bogus) DBENV, will join ... */
		if (dbi->dbi_eflags & DB_PRIVATE) {
		    dbi->dbi_eflags &= ~DB_JOINENV;
		} else {
		    dbi->dbi_eflags |= DB_JOINENV;
		    dbi->dbi_oeflags &= ~DB_CREATE;
		    dbi->dbi_oeflags &= ~DB_THREAD;
		}
	    }
	    dbf = _free(dbf);
	}
    }

    /*
     * Avoid incompatible DB_CREATE/DB_RDONLY flags on DB->open.
     */
    if ((oflags & DB_CREATE) && (oflags & DB_RDONLY)) {
	/* dbhome is writable, and DB->open flags may conflict. */
	const char * dbfn = (dbfile ? dbfile : rpmTagGetName(dbi->dbi_rpmtag));
	char * dbf = rpmGetPath(dbhome, "/", dbfn, NULL);

	if (access(dbf, F_OK) == -1) {
	    /* File does not exist, DB->open might create ... */
	    oflags &= ~DB_RDONLY;
	} else {
	    /* File exists, DB->open need not create ... */
	    oflags &= ~DB_CREATE;
	}

	/* Only writers need DB_WRITECURSOR ... */
	if (!(oflags & DB_RDONLY) && access(dbf, W_OK) == 0) {
	    dbi->dbi_oflags &= ~DB_RDONLY;
	} else {
	    dbi->dbi_oflags |= DB_RDONLY;
	}
	dbf = _free(dbf);
    }

    /*
     * Turn off verify-on-close if opening read-only.
     */
    if (oflags & DB_RDONLY)
	dbi->dbi_verify_on_close = 0;

    if (dbi->dbi_use_dbenv) {
	if (rpmdb->db_dbenv == NULL) {
	    rc = db_init(dbi, dbhome, dbfile, dbsubfile, &dbenv);
	    if (rc == 0) {
		rpmdb->db_dbenv = dbenv;
		rpmdb->db_opens = 1;
	    }
	} else {
	    dbenv = rpmdb->db_dbenv;
	    rpmdb->db_opens++;
	}
    }

    {	char *dbiflags = prDbiOpenFlags(oflags, 0);
    	rpmlog(RPMLOG_DEBUG, "opening  db index       %s/%s %s mode=0x%x\n",
		dbhome, (dbfile ? dbfile : rpmTagGetName(dbi->dbi_rpmtag)),
		dbiflags, dbi->dbi_mode);
	free(dbiflags);
    }

    if (rc == 0) {
	static int _lockdbfd = 0;

	rc = db_create(&db, dbenv, dbi->dbi_cflags);
	rc = cvtdberr(dbi, "db_create", rc, _debug);
	if (rc == 0 && db != NULL) {

	    if (rc == 0 &&
			rpmdb->db_malloc && rpmdb->db_realloc && rpmdb->db_free)
	    {
		rc = db->set_alloc(db,
			rpmdb->db_malloc, rpmdb->db_realloc, rpmdb->db_free);
		rc = cvtdberr(dbi, "db->set_alloc", rc, _debug);
	    }

/* 4.1: db->set_cache_priority(???) */
	    if (rc == 0 && !dbi->dbi_use_dbenv && dbi->dbi_cachesize) {
		rc = db->set_cachesize(db, 0, dbi->dbi_cachesize, 0);
		rc = cvtdberr(dbi, "db->set_cachesize", rc, _debug);
	    }
/* 4.1: db->set_encrypt(???) */
/* 4.1: db->set_errcall(dbenv, rpmdb->db_errcall); */
/* 4.1: db->set_errfile(dbenv, rpmdb->db_errfile); */
/* 4.1: db->set_errpfx(dbenv, rpmdb->db_errpfx); */
 /* 4.1: db->set_feedback(???) */

	    if (rc == 0 && dbi->dbi_lorder) {
		rc = db->set_lorder(db, dbi->dbi_lorder);
		rc = cvtdberr(dbi, "db->set_lorder", rc, _debug);
	    }
	    if (rc == 0 && dbi->dbi_pagesize) {
		rc = db->set_pagesize(db, dbi->dbi_pagesize);
		rc = cvtdberr(dbi, "db->set_pagesize", rc, _debug);
	    }
 /* 4.1: db->set_paniccall(???) */
	    if (rc == 0 && oflags & DB_CREATE) {
		switch(dbi->dbi_type) {
		default:
		case DB_HASH:
		    if (dbi->dbi_h_ffactor) {
			rc = db->set_h_ffactor(db, dbi->dbi_h_ffactor);
			rc = cvtdberr(dbi, "db->set_h_ffactor", rc, _debug);
			if (rc) break;
		    }
		    if (dbi->dbi_h_nelem) {
			rc = db->set_h_nelem(db, dbi->dbi_h_nelem);
			rc = cvtdberr(dbi, "db->set_h_nelem", rc, _debug);
			if (rc) break;
		    }
		    if (dbi->dbi_h_flags) {
			rc = db->set_flags(db, dbi->dbi_h_flags);
			rc = cvtdberr(dbi, "db->set_h_flags", rc, _debug);
			if (rc) break;
		    }
		    if (dbi->dbi_h_hash_fcn) {
			rc = db->set_h_hash(db, dbi->dbi_h_hash_fcn);
			rc = cvtdberr(dbi, "db->set_h_hash", rc, _debug);
			if (rc) break;
		    }
		    if (dbi->dbi_h_dup_compare_fcn) {
			rc = db->set_dup_compare(db, dbi->dbi_h_dup_compare_fcn);
			rc = cvtdberr(dbi, "db->set_dup_compare", rc, _debug);
			if (rc) break;
		    }
		    break;
		case DB_BTREE:
/* 4.1: db->set_append_recno(???) */
		    if (dbi->dbi_bt_flags) {
			rc = db->set_flags(db, dbi->dbi_bt_flags);
			rc = cvtdberr(dbi, "db->set_bt_flags", rc, _debug);
			if (rc) break;
		    }
		    if (dbi->dbi_bt_minkey) {
			rc = db->set_bt_minkey(db, dbi->dbi_bt_minkey);
			rc = cvtdberr(dbi, "db->set_bt_minkey", rc, _debug);
			if (rc) break;
		    }
		    if (dbi->dbi_bt_compare_fcn) {
			rc = db->set_bt_compare(db, dbi->dbi_bt_compare_fcn);
			rc = cvtdberr(dbi, "db->set_bt_compare", rc, _debug);
			if (rc) break;
		    }
		    if (dbi->dbi_bt_dup_compare_fcn) {
			rc = db->set_dup_compare(db, dbi->dbi_bt_dup_compare_fcn);
			rc = cvtdberr(dbi, "db->set_dup_compare", rc, _debug);
			if (rc) break;
		    }
		    if (dbi->dbi_bt_prefix_fcn) {
			rc = db->set_bt_prefix(db, dbi->dbi_bt_prefix_fcn);
			rc = cvtdberr(dbi, "db->set_bt_prefix", rc, _debug);
			if (rc) break;
		    }
		    break;
		case DB_RECNO:
		    if (dbi->dbi_re_delim) {
/* 4.1: db->set_append_recno(???) */
			rc = db->set_re_delim(db, dbi->dbi_re_delim);
			rc = cvtdberr(dbi, "db->set_re_selim", rc, _debug);
			if (rc) break;
		    }
		    if (dbi->dbi_re_len) {
			rc = db->set_re_len(db, dbi->dbi_re_len);
			rc = cvtdberr(dbi, "db->set_re_len", rc, _debug);
			if (rc) break;
		    }
		    if (dbi->dbi_re_pad) {
			rc = db->set_re_pad(db, dbi->dbi_re_pad);
			rc = cvtdberr(dbi, "db->set_re_pad", rc, _debug);
			if (rc) break;
		    }
		    if (dbi->dbi_re_source) {
			rc = db->set_re_source(db, dbi->dbi_re_source);
			rc = cvtdberr(dbi, "db->set_re_source", rc, _debug);
			if (rc) break;
		    }
		    break;
		case DB_QUEUE:
		    if (dbi->dbi_q_extentsize) {
			rc = db->set_q_extentsize(db, dbi->dbi_q_extentsize);
			rc = cvtdberr(dbi, "db->set_q_extentsize", rc, _debug);
			if (rc) break;
		    }
		    break;
		}
	    }

	    if (rc == 0) {
		char * fullpath;
		const char * dbpath;
		fullpath = rpmGetPath(dbhome, "/", dbfile ? dbfile : "", NULL);

#ifdef	HACK	/* XXX necessary to support dbsubfile */
		dbpath = (!dbi->dbi_use_dbenv && !dbi->dbi_temporary)
			? fullpath : dbfile;
#else
		dbpath = (!dbi->dbi_temporary)
			? fullpath : dbfile;
#endif

		rc = (db->open)(db, txnid, dbpath, dbsubfile,
		    dbi->dbi_type, oflags, dbi->dbi_perms);

		if (rc == 0 && dbi->dbi_type == DB_UNKNOWN) {
		    DBTYPE dbi_type = DB_UNKNOWN;
		    xx = db->get_type(db, &dbi_type);
		    if (xx == 0)
			dbi->dbi_type = dbi_type;
		}
		free(fullpath);
	    }

	    /* XXX return rc == errno without printing */
	    _printit = (rc > 0 ? 0 : _debug);
	    xx = cvtdberr(dbi, "db->open", rc, _printit);

	    dbi->dbi_txnid = NULL;

	    /*
	     * Lock a file using fcntl(2). Traditionally this is Packages,
	     * the file used to store metadata of installed header(s),
	     * as Packages is always opened, and should be opened first,
	     * for any rpmdb access.
	     *
	     * If no DBENV is used, then access is protected with a
	     * shared/exclusive locking scheme, as always.
	     *
	     * With a DBENV, the fcntl(2) lock is necessary only to keep
	     * the riff-raff from playing where they don't belong, as
	     * the DBENV should provide it's own locking scheme. So try to
	     * acquire a lock, but permit failures, as some other
	     * DBENV player may already have acquired the lock.
	     *
	     * With NPTL posix mutexes, revert to fcntl lock on non-functioning
	     * glibc/kernel combinations.
	     */
	    if (rc == 0 && dbi->dbi_lockdbfd &&
		!((dbi->dbi_ecflags & DB_CLIENT) && dbi->dbi_host) &&
		(!dbi->dbi_use_dbenv || _lockdbfd++ == 0))
	    {
		int fdno = -1;

		if (!(db->fd(db, &fdno) == 0 && fdno >= 0)) {
		    rc = 1;
		} else {
		    struct flock l;
		    memset(&l, 0, sizeof(l));
		    l.l_whence = 0;
		    l.l_start = 0;
		    l.l_len = 0;
		    l.l_type = (dbi->dbi_mode & O_ACCMODE) == O_RDONLY
				? F_RDLCK : F_WRLCK;
		    l.l_pid = 0;

		    rc = fcntl(fdno, F_SETLK, (void *) &l);
		    if (rc) {
			/* Warning iff using non-private CDB locking. */
			rc = ((dbi->dbi_use_dbenv &&
				(dbi->dbi_eflags & DB_INIT_CDB) &&
				!(dbi->dbi_eflags & DB_PRIVATE))
			    ? 0 : 1);
			rpmlog( (rc ? RPMLOG_ERR : RPMLOG_WARNING),
				_("cannot get %s lock on %s/%s\n"),
				((dbi->dbi_mode & O_ACCMODE) == O_RDONLY)
					? _("shared") : _("exclusive"),
				dbhome, (dbfile ? dbfile : ""));
		    } else if (dbfile) {
			rpmlog(RPMLOG_DEBUG,
				"locked   db index       %s/%s\n",
				dbhome, dbfile);
		    }
		}
	    }
	}
    }

    dbi->dbi_db = db;

    if (rc == 0 && dbi->dbi_db != NULL && dbip != NULL) {
	dbi->dbi_vec = &db3vec;
	*dbip = dbi;
    } else {
	dbi->dbi_verify_on_close = 0;
	(void) db3close(dbi, 0);
    }

    free(dbhome);

    return rc;
}
Beispiel #9
0
int
open_fs_db(
	char		*dirnam,
	char		*fsname,
	DB_ENV		*p_env,
	boolean_t	create,		/* add new databases if not existing */
	fs_db_t		*fsdb)
{
	DB		*pdb;
	int		st;
	char		buf[MAXPATHLEN+1];
	mode_t		md = 0644;
	char		namebuf[MAXPATHLEN+1] = {0};
	struct stat64	sbuf;

	memset(fsdb, 0, sizeof (fs_db_t));

	/* make sure fs-specific directory exists */
	st = dbdir_from_fsname(fsname, namebuf, sizeof (namebuf));
	if (st != 0) {
		goto err;
	}

	snprintf(buf, sizeof (buf), "%s/%s", dirnam, namebuf);

	if (!create) {
		if (stat64(buf, &sbuf) != 0) {
			return (ENOENT);
		}
	}
	(void) mkdirp(buf, 0744);

	if (fsdb->snapDB == NULL) {
		/* Create & open the snapshot database - RECNO */
		snprintf(buf, sizeof (buf), "%s/snaps.db", namebuf);

		if ((st = db_create(&fsdb->snapDB, p_env, 0)) != 0) {
			goto err;
		}

		pdb = fsdb->snapDB;

		if ((st = pdb->set_append_recno(pdb, set_snapid)) != 0) {
			goto err;
		}

		if ((st = pdb->open(pdb, NULL, buf, NULL, DB_RECNO,
		    db_fl, md)) != 0) {
			goto err;
		}

		/*  create the secondary for the snapdb */
		snprintf(buf, sizeof (buf), "%s/snapid.db", namebuf);

		if ((st = db_create(&fsdb->snapidDB, p_env, 0)) != 0) {
			goto err;
		}

		pdb = fsdb->snapidDB;

		pdb->set_bt_compare(pdb, compare_pathname);

		if ((st = pdb->open(pdb, NULL, buf, NULL, DB_BTREE, db_fl,
		    md)) != 0) {
			goto err;
		}

		if ((st = (fsdb->snapDB)->associate(fsdb->snapDB, NULL, pdb,
		    index_snapname, DB_CREATE)) != 0) {
			goto err;
		}
	}

	if (fsdb->fidDB == NULL) {
		/* Path components by FID - Primary, BTREE */
		snprintf(buf, sizeof (buf), "%s/path_fid.db", namebuf);

		if ((st = db_create(&fsdb->fidDB, p_env, 0)) != 0) {
			goto err;
		}

		pdb = fsdb->fidDB;

		pdb->set_bt_compare(pdb, bt_compare_uint64);

		if ((st = pdb->open(pdb, NULL, buf, NULL, DB_BTREE, db_fl,
		    md)) != 0) {
			goto err;
		}

		/* pathname DB - BTREE */
		snprintf(buf, sizeof (buf), "%s/path.db", namebuf);

		if ((st = db_create(&fsdb->pathDB, p_env, 0)) != 0) {
			goto err;
		}

		pdb = fsdb->pathDB;

		pdb->set_bt_compare(pdb, compare_path_t);

		if ((st = pdb->open(pdb, NULL, buf, NULL, DB_BTREE, db_fl,
		    md)) != 0) {
			goto err;
		}

		if ((st = (fsdb->fidDB)->associate(fsdb->fidDB, NULL, pdb,
		    index_path, DB_CREATE|DB_IMMUTABLE_KEY)) != 0) {
			goto err;
		}

		/*
		 * dirName DB - BTREE - full path for quick lookups
		 * Note:  This was a secondary database to fidDB, but
		 * it was impossible to delete items from this DB because
		 * we were breaking the reproducibility rules when creating
		 * the secondary index.  This db exists for performance
		 * reasons when adding files/looking up full paths.  The
		 * "most right" answer is probably a directory name cache
		 * and should be considered for a future enhancement.
		 */
		snprintf(buf, sizeof (buf), "%s/dir.db", namebuf);

		if ((st = db_create(&fsdb->dirDB, p_env, 0)) != 0) {
			goto err;
		}

		pdb = fsdb->dirDB;

		pdb->set_bt_compare(pdb, compare_pathname);

		if ((st = pdb->open(pdb, NULL, buf, NULL, DB_BTREE, db_fl,
		    md)) != 0) {
			goto err;
		}
	}

	if (fsdb->snapfileDB == NULL) {
		snprintf(buf, sizeof (buf), "%s/snapfiles.db", namebuf);

		/* snapfile DB */
		if ((st = db_create(&fsdb->snapfileDB, p_env, 0)) != 0) {
			goto err;
		}

		pdb = fsdb->snapfileDB;

		pdb->set_bt_compare(pdb, bt_compare_sfid);

		if ((st = pdb->open(pdb, NULL, buf, NULL, DB_BTREE, db_fl,
		    md)) != 0) {
			goto err;
		}
	}

	if (fsdb->filesDB == NULL) {
		snprintf(buf, sizeof (buf), "%s/files.db", namebuf);

		/* next, the db for modified files */
		if ((st = db_create(&fsdb->filesDB, p_env, 0)) != 0) {
			goto err;
		}

		pdb = fsdb->filesDB;

		pdb->set_bt_compare(pdb, bt_compare_fuid);

		if ((st = pdb->open(pdb, NULL, buf, NULL, DB_BTREE, db_fl,
		    md)) != 0) {
			goto err;
		}
	}

	/* VSNs by snapshot */
	if (fsdb->snapvsnDB == NULL) {
		snprintf(buf, sizeof (buf), "%s/snapvsn.db", namebuf);

		if ((st = db_create(&fsdb->snapvsnDB, p_env, 0)) != 0) {
			goto err;
		}

		pdb = fsdb->snapvsnDB;

		pdb->set_bt_compare(pdb, bt_compare_uint32);

		pdb->set_flags(pdb, DB_DUPSORT);

		pdb->set_dup_compare(pdb, bt_compare_uint32);

		if ((st = pdb->open(pdb, NULL, buf, NULL, DB_BTREE,
		    db_fl, md)) != 0) {
			goto err;
		}
	}

	if (fsdb->metricsDB == NULL) {
		snprintf(buf, sizeof (buf), "%s/metrics.db", namebuf);

		/* next, the db for file metrics results.  No duplicates.  */
		if ((st = db_create(&fsdb->metricsDB, p_env, 0)) != 0) {
			goto err;
		}

		pdb = fsdb->metricsDB;

		pdb->set_bt_compare(pdb, bt_compare_fmRpt);

		if ((st = pdb->open(pdb, NULL, buf, NULL, DB_BTREE, db_fl,
		    md)) != 0) {
			goto err;
		}
	}

	return (0);

err:
	close_fsdb(fsname, fsdb, FALSE);
	return (st);

}
Beispiel #10
0
static int 
dbverify_ext( ldbm_instance *inst, int verbose )
{
    char dbdir[MAXPATHLEN];
    char *filep           = NULL;
    PRDir *dirhandle      = NULL;
    PRDirEntry *direntry  = NULL;
    DB *dbp               = NULL;
    size_t tmplen            = 0;
    size_t filelen           = 0;
    int rval              = 1;
    int rval_main         = 0;
    struct ldbminfo *li   = inst->inst_li;
    dblayer_private *priv = (dblayer_private*)li->li_dblayer_private;
    struct dblayer_private_env *pEnv = priv->dblayer_env;

    dbdir[sizeof(dbdir)-1] = '\0';
    PR_snprintf(dbdir, sizeof(dbdir), "%s/%s", inst->inst_parent_dir_name,
                                               inst->inst_dir_name);
    if ('\0' != dbdir[sizeof(dbdir)-1]) /* overflown */
    {
        slapi_log_err(SLAPI_LOG_ERR, "dbverify_ext",
                        "db path too long: %s/%s\n",
                         inst->inst_parent_dir_name, inst->inst_dir_name);
        return 1;
    }
    tmplen = strlen(dbdir);
    filep = dbdir + tmplen;
    filelen = sizeof(dbdir) - tmplen;

    /* run dbverify on each each db file */
    dirhandle = PR_OpenDir(dbdir);
    if (! dirhandle)
    {
        slapi_log_err(SLAPI_LOG_ERR, "dbverify_ext",
                        "PR_OpenDir (%s) failed (%d): %s\n", 
                        dbdir, PR_GetError(),slapd_pr_strerror(PR_GetError()));
        return 1;
    }
    while (NULL !=
          (direntry = PR_ReadDir(dirhandle, PR_SKIP_DOT | PR_SKIP_DOT_DOT)))
    {
        /* struct attrinfo *ai = NULL; */
        dbp = NULL;

        if (!direntry->name)
        {
            break;
        }
        if (!strstr(direntry->name, LDBM_FILENAME_SUFFIX)) /* non db file */
        {
            continue;
        }
        if (sizeof(direntry->name) + 2 > filelen)
        {
            slapi_log_err(SLAPI_LOG_ERR, "dbverify_ext",
                                        "db path too long: %s/%s\n",
                                         dbdir, direntry->name);
            continue;
        }
        PR_snprintf(filep, filelen, "/%s", direntry->name);
        rval = db_create(&dbp, pEnv->dblayer_DB_ENV, 0);
        if (0 != rval)
        {
            slapi_log_err(SLAPI_LOG_ERR, "dbverify_ext",
                        "Unable to create id2entry db file %d\n", rval);
            return rval;
        }

#define VLVPREFIX "vlv#"
        if (0 != strncmp(direntry->name, ID2ENTRY, strlen(ID2ENTRY)))
        {
            struct attrinfo *ai = NULL;
            char *p = NULL;
            p = strstr(filep, LDBM_FILENAME_SUFFIX); /* since already checked,
                                                        it must have it */
            if(p)
                *p = '\0';
            ainfo_get( inst->inst_be, filep+1, &ai );
            if(p)
                *p = '.';
            if (ai->ai_key_cmp_fn) {
                dbp->app_private = (void *)ai->ai_key_cmp_fn;
                dbp->set_bt_compare(dbp, dblayer_bt_compare);
            }
            if (idl_get_idl_new())
            {
                rval = dbp->set_pagesize(dbp,
                        (priv->dblayer_index_page_size == 0) ?
                        DBLAYER_INDEX_PAGESIZE : priv->dblayer_index_page_size);
            }
            else
            {
                rval = dbp->set_pagesize(dbp,
                        (priv->dblayer_page_size == 0) ?
                        DBLAYER_PAGESIZE : priv->dblayer_page_size);
            }
            if (0 != rval)
            {
                slapi_log_err(SLAPI_LOG_ERR, "DB verify",
                         "Unable to set pagesize flags to db (%d)\n", rval);
                return rval;
            }
            if (0 == strncmp(direntry->name, VLVPREFIX, strlen(VLVPREFIX)))
            {
                rval = dbp->set_flags(dbp, DB_RECNUM);
                if (0 != rval)
                {
                    slapi_log_err(SLAPI_LOG_ERR, "dbverify_ext",
                         "Unable to set RECNUM flag to vlv index (%d)\n", rval);
                    return rval;
                }
            }
            else if (idl_get_idl_new())
            {
                rval = dbp->set_flags(dbp, DB_DUP | DB_DUPSORT);
                if (0 != rval)
                {
                    slapi_log_err(SLAPI_LOG_ERR, "dbverify_ext",
                           "Unable to set DUP flags to db (%d)\n", rval);
                    return rval;
                }
    
				if (ai->ai_dup_cmp_fn) {
					/* If set, use the special dup compare callback */
					rval = dbp->set_dup_compare(dbp, ai->ai_dup_cmp_fn);
				} else {
					rval = dbp->set_dup_compare(dbp, idl_new_compare_dups);
				}

                if (0 != rval)
                {
                    slapi_log_err(SLAPI_LOG_ERR, "dbverify_ext",
                           "Unable to set dup_compare to db (%d)\n", rval);
                    return rval;
                }
            }
        }
#undef VLVPREFIX
        rval = dbp->verify(dbp, dbdir, NULL, NULL, 0);
        if (0 == rval)
        {
            if (verbose)
            {
                slapi_log_err(SLAPI_LOG_ERR, "dbverify_ext",
                                                 "%s: ok\n", dbdir);
            }
        }
        else
        {
            slapi_log_err(SLAPI_LOG_ERR, "dbverify_ext",
                            "verify failed(%d): %s\n", rval, dbdir);
        }
        rval_main |= rval;
        *filep = '\0';
    }
    PR_CloseDir(dirhandle);

    return rval_main;
}
Beispiel #11
0
int main(int argc, const char *argv[])
{
	DB *dbp;
	int error;
	const char *progname = argv[0];
	const char *dbname = argv[1];
	int retval = 0;
	struct dbfs_fsinfo_data dfd;
	struct dbfs_dentry_key *ddk;
	struct dbfs_dentry_data ddd;
	size_t ddk_size;

	if (argc != 2) {
		fprintf(stderr, "Format: %s file name\n", progname);
		goto out1;
	}
	if ((error = db_create(&dbp, NULL, 0))) {
		fprintf(stderr, "%s: db_create failed", progname);	
		goto out1;
	}
	dbp->set_errfile(dbp, stderr);
	dbp->set_errpfx(dbp, progname);

	if ((error = dbp->set_bt_compare(dbp, dbfs_bt_compare))) {
		dbp->err(dbp, error, "%s: open failed", dbname);
		goto out1;
	}

	/* Create database */
	if ((error = dbp->open(dbp,
	    NULL, dbname, NULL, DB_BTREE, DB_CREATE | DB_EXCL | DB_THREAD, 0664))) {
		dbp->err(dbp, error, "open: %s", dbname);
		goto out1;
	}

	ddk_size = dbfs_ddk_size("/");
	if (!(ddk = malloc(ddk_size))) {
		goto out2;
	}

	dbfs_init_dentry_key("/", ddk);

	if ((error = dbfs_create_attr(dbp, ddk, ddk_size, &ddd, mangoo_container, 
		S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH, DBFS_ROOT_INO))) {
		goto out2;
	}

	dfd.dfd_lastino = DBFS_ROOT_INO;

	if ((error = dbfs_create_fsinfo(dbp, &dfd)))
		goto out2;

	printf("dbfs created successfully.\n");

out2:
	if ((dbp->close(dbp, 0))) {
		fprintf(stderr, "%s: close failed", progname);	
	}

out1:
	return retval;
}