Пример #1
0
int icalbdbset_delete(DB *dbp, DBT *key)
{
    DB_TXN *tid;
    int ret;
    int done = 0;
    int retry = 0;

    while ((retry < MAX_RETRY) && !done) {

        if ((ret = ICAL_DB_ENV->txn_begin(ICAL_DB_ENV, NULL, &tid, 0)) != 0) {
            if (ret == DB_LOCK_DEADLOCK) {
                retry++;
                continue;
            } else {
                /*char *foo = db_strerror(ret); */
                abort();
            }
        }

        if ((ret = dbp->del(dbp, tid, key, 0)) != 0) {
            if (ret == DB_NOTFOUND) {
                /* do nothing - not an error condition */
            } else if (ret == DB_LOCK_DEADLOCK) {
                tid->abort(tid);
                retry++;
                continue;
            } else {
                char *strError = db_strerror(ret);

                icalerror_warn("icalbdbset_delete faild: ");
                icalerror_warn(strError);
                tid->abort(tid);
                return ICAL_FILE_ERROR;
            }
        }

        if ((ret = tid->commit(tid, 0)) != 0) {
            if (ret == DB_LOCK_DEADLOCK) {
                tid->abort(tid);
                retry++;
                continue;
            } else {
                /*char *foo = db_strerror(ret); */
                abort();
            }
        }

        done = 1;       /* all is well */
    }

    if (!done) {
        if (tid != NULL) {
            tid->abort(tid);
        }
    }

    return ret;
}
Пример #2
0
int icalbdbset_put(DB *dbp, DBT *key, DBT *data, u_int32_t access_method)
{
    int ret = 0;
    DB_TXN *tid = NULL;
    int retry = 0;
    int done = 0;

    while ((retry < MAX_RETRY) && !done) {

        if ((ret = ICAL_DB_ENV->txn_begin(ICAL_DB_ENV, NULL, &tid, 0)) != 0) {
            if (ret == DB_LOCK_DEADLOCK) {
                retry++;
                continue;
            } else {
                /*char *foo = db_strerror(ret); */
                abort();
            }
        }

        if ((ret = dbp->put(dbp, tid, key, data, access_method)) != 0) {
            if (ret == DB_LOCK_DEADLOCK) {
                tid->abort(tid);
                retry++;
                continue;
            } else {
                char *strError = db_strerror(ret);

                icalerror_warn("icalbdbset_put faild: ");
                icalerror_warn(strError);
                tid->abort(tid);
                return ICAL_FILE_ERROR;
            }
        }

        if ((ret = tid->commit(tid, 0)) != 0) {
            if (ret == DB_LOCK_DEADLOCK) {
                tid->abort(tid);
                retry++;
                continue;
            } else {
                /*char *foo = db_strerror(ret); */
                abort();
            }
        }

        done = 1;       /* all is well */
    }

    if (!done) {
        if (tid != NULL) {
            tid->abort(tid);
        }
        return ICAL_FILE_ERROR;
    } else {
        return ICAL_NO_ERROR;
    }
}
Пример #3
0
int bdb_create_queue(char *queue_name) {
    pthread_rwlock_wrlock(&qlist_ht_lock);

    char *k = strdup(queue_name);
    assert(k != NULL);
    queue_t *q = (queue_t *)calloc(1, sizeof(queue_t));
    assert(q != NULL);

    q->dbp = NULL;
    q->set_hits = q->old_set_hits = 0;
    q->get_hits = q->old_get_hits = 0;
    pthread_mutex_init(&(q->lock), NULL);
    
    int ret;
    DB_TXN *txnp = NULL;
    ret = db_create(&(q->dbp), envp, 0);
    CHECK_DB_RET(ret);

    if (bdb_settings.q_extentsize != 0){
        ret = q->dbp->set_q_extentsize(q->dbp, bdb_settings.q_extentsize);
        CHECK_DB_RET(ret);
    }
    ret = q->dbp->set_re_len(q->dbp, bdb_settings.re_len);
    CHECK_DB_RET(ret);
    ret = q->dbp->set_pagesize(q->dbp, bdb_settings.page_size);
    CHECK_DB_RET(ret);

    ret = envp->txn_begin(envp, NULL, &txnp, 0);
    CHECK_DB_RET(ret);
    ret = q->dbp->open(q->dbp, txnp, queue_name, NULL, DB_QUEUE, DB_CREATE, 0664); 
    CHECK_DB_RET(ret);
    
    DBT dbkey,dbdata;
    qstats_t qs;
    BDB_CLEANUP_DBT();
    memset(&qs, 0, sizeof(qs));
    dbkey.data = (void *)queue_name;
    dbkey.size = strlen(queue_name)+1;
    dbdata.data = (void *)&qs;
    dbdata.size = sizeof(qstats_t);
    ret = qlist_dbp->put(qlist_dbp, txnp, &dbkey, &dbdata, 0);
    CHECK_DB_RET(ret);
    ret = txnp->commit(txnp, 0);
    CHECK_DB_RET(ret);
    int result = hashtable_insert(qlist_htp, (void *)k, (void *)q);
    assert(result != 0);
    pthread_rwlock_unlock(&qlist_ht_lock);
    return 0;
dberr:
    if (txnp != NULL){
        txnp->abort(txnp);
    }
    fprintf(stderr, "bdb_create_queue: %s %s\n", queue_name, db_strerror(ret));
    pthread_rwlock_unlock(&qlist_ht_lock);
    return -1;
}
Пример #4
0
int main() {
	DB *dbp;
	DB_ENV *dbenv;
	DB_TXN *xid;
	DBT key, data;
	const unsigned int INSERT_NUM = 100;
	char value[22]; /* should be log INSERT_NUM */
	int ret, i, t_ret;

        env_dir_create();
        env_open(&dbenv);

	if ((ret = db_create(&dbp, dbenv, 0)) != 0) {
		fprintf(stderr, "db_create: %s\n", db_strerror(ret));
		exit (1);
	}

	dbenv->txn_begin(dbenv, NULL, &xid, 0);
	if ((ret = dbp->open(dbp,
					xid, DATABASE, NULL, DB_BTREE, DB_CREATE, 0664)) != 0) {
		dbp->err(dbp, ret, "%s", DATABASE);
		goto err;
	}

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

	key.size = sizeof(int);
	key.data = malloc(sizeof(int));
	data.data = value;

	for( i = 0; i < INSERT_NUM; i++ ) {
		*((int*)key.data) = i;
		data.size = sizeof(char)*strlen(data.data);
		sprintf(value, "value: %u\n", i);
		dbp->put(dbp, xid, &key, &data, 0);
	}

	xid->commit(xid, 0);
	dbenv->txn_begin(dbenv, NULL, &xid, 0);
	
	for( i = 0; i < INSERT_NUM; i++ ) {
		*((int*)key.data) = i;
		dbp->get(dbp, xid, &key, &data, 0);
		printf("db: %u: key retrieved: data was %s.\n", *((int*)key.data), (char *)data.data);
	}

	xid->abort(xid);

err:    if ((t_ret = dbp->close(dbp, 0)) != 0 && ret == 0)
			ret = t_ret; 


	return 0;

}
Пример #5
0
/* if return item is not NULL, free by caller */
item *bdb_get(char *key){
    pthread_rwlock_rdlock(&qlist_ht_lock);
    item *it = NULL;
    DB_TXN *txnp = NULL;
    int ret;
    
    queue_t *q = (queue_t *)hashtable_search(qlist_htp, (void *)key);
    /* queue not exsited */
    if (q == NULL) {
        pthread_rwlock_unlock(&qlist_ht_lock);            
        return NULL;
    } else {
        DBT dbkey, dbdata;
        db_recno_t recno;

        /* first, alloc a fixed size */
        it = item_alloc2();
        if (it == 0) {
            pthread_rwlock_unlock(&qlist_ht_lock);            
            return NULL;
        }

        BDB_CLEANUP_DBT();
        dbkey.data = &recno;
        dbkey.ulen = sizeof(recno);
        dbkey.flags = DB_DBT_USERMEM;
        dbdata.ulen = bdb_settings.re_len;
        dbdata.data = it;
        dbdata.flags = DB_DBT_USERMEM;

        ret = envp->txn_begin(envp, NULL, &txnp, 0);
        CHECK_DB_RET(ret);
        ret = q->dbp->get(q->dbp, txnp, &dbkey, &dbdata, DB_CONSUME);
        CHECK_DB_RET(ret);
        ret = txnp->commit(txnp, 0);
        CHECK_DB_RET(ret);
        pthread_mutex_lock(&(q->lock));
        (q->get_hits)++;
        pthread_mutex_unlock(&(q->lock));
    }
    pthread_rwlock_unlock(&qlist_ht_lock);    
    return it;
dberr:
    item_free(it);
    it = NULL;
    if (txnp != NULL){
        txnp->abort(txnp);
    }
    if (settings.verbose > 1) {
        fprintf(stderr, "bdb_get: %s\n", db_strerror(ret));
    }
    pthread_rwlock_unlock(&qlist_ht_lock);
    return NULL;
}
Пример #6
0
void bdb_qlist_db_open(void){
    int ret;
    DBC *cursorp = NULL;
    DB_TXN *txnp = NULL;
        
    /* Create queue.list db handle */
    ret = db_create(&qlist_dbp, envp, 0);
    CHECK_DB_RET(ret);

    /* Open and Iterate */
    ret = envp->txn_begin(envp, NULL, &txnp, 0);
    CHECK_DB_RET(ret);
    ret = qlist_dbp->open(qlist_dbp, txnp, "queue.list", NULL, DB_BTREE, DB_CREATE, 0664);
    CHECK_DB_RET(ret);
    ret = qlist_dbp->cursor(qlist_dbp, txnp, &cursorp, 0); 
    CHECK_DB_RET(ret);
    DBT dbkey, dbdata;
    char qname[512];
    qstats_t qs;
    BDB_CLEANUP_DBT();
    memset(qname, 0, 512);
    memset(&qs, 0, sizeof(qs));
    dbkey.data = (void *)qname;
    dbkey.ulen = 512;
    dbkey.flags = DB_DBT_USERMEM;
    dbdata.data = (void *)&qs;
    dbdata.ulen = sizeof(qs);
    dbdata.flags = DB_DBT_USERMEM;
    
    while ((ret = cursorp->get(cursorp, &dbkey, &dbdata, DB_NEXT)) == 0) {
        open_exsited_queue_db(txnp, qname, &qs);
    }
    if (ret != DB_NOTFOUND) {
        goto dberr;
    }
    
    ret = cursorp->close(cursorp);
    CHECK_DB_RET(ret);
    
    ret = txnp->commit(txnp, 0);
    CHECK_DB_RET(ret);
    return;
        
dberr:
    if (cursorp != NULL){
        cursorp->close(cursorp);
    }
    if (txnp != NULL){
        txnp->abort(txnp);
    }
    fprintf(stderr, "bdb_qlist_db_open: %s\n", db_strerror(ret));
    exit(EXIT_FAILURE);
}
Пример #7
0
/*
 *  Closes databases for a given filesystem.  If delete_databases is TRUE,
 *  removes the databases from the system.
 */
void
close_fsdb(char *fsname, fs_db_t *fsdb, boolean_t delete_databases)
{
	size_t		i;
	DB		*dbp;
	char		fname[MAXPATHLEN + 1];
	DB_TXN		*txn;
	int		st;

	if (fsdb == NULL) {
		return;
	}

	i = sizeof (fs_db_t) / sizeof (DB *);

	/* close secondaries first, so start from the last in the struct */
	while (i > 0) {
		i--;
		dbp = ((DB **)fsdb)[i];

		if (dbp != NULL) {
			if (dbp->fname != NULL) {
				strlcpy(fname, dbp->fname, sizeof (fname));
			} else {
				fname[0] = '\0';
			}

			/* databases must be closed before they're removed. */
			dbp->close(dbp, 0);
			((DB **)fsdb)[i] = NULL;

			if ((delete_databases) && (fname[0] != '\0')) {
				dbEnv->txn_begin(dbEnv, NULL, &txn, 0);
				dbEnv->dbremove(dbEnv, txn, fname, NULL, 0);
				txn->commit(txn, 0);
			}
		}
	}

	if (delete_databases) {
		char	namebuf[MAXPATHLEN];

		/* delete fs-specific directory */
		st = dbdir_from_fsname(fsname, namebuf, sizeof (namebuf));
		if (st == 0) {
			snprintf(fname, sizeof (fname), "%s/%s", fsmdbdir,
			    namebuf);

			(void) rmdir(fname);
		}
	}
}
Пример #8
0
int main(int argc,char * argv[])
{
	int rc;
	DB_ENV *env;
	DB *dbi;
	DBT key, data;
	DB_TXN *txn;
	DBC *cursor;
	char sval[32], kval[32];

#define FLAGS (DB_INIT_LOCK|DB_INIT_LOG|DB_INIT_TXN|DB_INIT_MPOOL|DB_CREATE|DB_THREAD)
	rc = db_env_create(&env, 0);
	rc = env->open(env, "./testdb", FLAGS, 0664);
	rc = db_create(&dbi, env, 0);
	rc = env->txn_begin(env, NULL, &txn, 0);
	rc = dbi->open(dbi, txn, "test.bdb", NULL, DB_BTREE, DB_CREATE, 0664);

	memset(&key, 0, sizeof(DBT));
	memset(&data, 0, sizeof(DBT));
	key.size = sizeof(int);
	key.data = sval;
	data.size = sizeof(sval);
	data.data = sval;

	sprintf(sval, "%03x %d foo bar", 32, 3141592);
	rc = dbi->put(dbi, txn, &key, &data, 0);
	rc = txn->commit(txn, 0);
	if (rc) {
		fprintf(stderr, "txn->commit: (%d) %s\n", rc, db_strerror(rc));
		goto leave;
	}
	rc = env->txn_begin(env, NULL, &txn, 0);
	rc = dbi->cursor(dbi, txn, &cursor, 0);
	key.flags = DB_DBT_USERMEM;
	key.data = kval;
	key.ulen = sizeof(kval);
	data.flags = DB_DBT_USERMEM;
	data.data = sval;
	data.ulen = sizeof(sval);
	while ((rc = cursor->c_get(cursor, &key, &data, DB_NEXT)) == 0) {
		printf("key: %p %.*s, data: %p %.*s\n",
			key.data,  (int) key.size,  (char *) key.data,
			data.data, (int) data.size, (char *) data.data);
	}
	rc = cursor->c_close(cursor);
	rc = txn->abort(txn);
leave:
	rc = dbi->close(dbi, 0);
	rc = env->close(env, 0);
	return rc;
}
Пример #9
0
/*
 * db_init --
 *	Open the database.
 */
int db_init( DB_ENV *dbenv, DB **dbpp, int dups, int pagesize)
{
    DB *dbp;
    DB_TXN *txnp;
    int ret;

    dbp = NULL;
    txnp = NULL;
    ret = 0;

    if ((ret = db_create(&dbp, dbenv, 0)) != 0) {
        fprintf(stderr,
                "%s: db_create: %s\n", progname, db_strerror(ret));
        return (ret);
    }
    dbp->set_errfile(dbp, stderr);
    dbp->set_errpfx(dbp, progname);
    if ((ret = dbp->set_pagesize(dbp, pagesize)) != 0) {
        dbp->err(dbp, ret, "set_pagesize");
        goto err;
    }
    if (dups && (ret = dbp->set_flags(dbp, DB_DUP)) != 0) {
        dbp->err(dbp, ret, "set_flags");
        goto err;
    }

    if ((ret = dbenv->txn_begin(dbenv, NULL, &txnp, 0)) != 0)
        goto err;

    if ((ret = dbp->open(dbp, txnp, "sss.db", "primary", DB_BTREE,
                         DB_CREATE , 0664)) != 0) {
        dbp->err(dbp, ret, "%s: open", "sss.db");
        goto err;
    }
    *dbpp = dbp;

    ret = txnp->commit(txnp, 0);
    txnp = NULL;
    if (ret != 0)
        goto err;

    return (0);

err:
    if (txnp != NULL)
        (void)txnp->abort(0);
    if (dbp != NULL)
        (void)dbp->close(dbp, 0);
    return (ret);
}
Пример #10
0
int store_tx_commit(struct acrd_txid *tx)
{
	int ret;
	DB_TXN *tid = tx->tid;

	dprintf("tid : %p\n", tid);
	ret = tid->commit(tid, 0);

	if (ret != 0) {
		envp->err(envp, ret, "DB_TXN->commit failed\n");
		return -1;
	}

	return 0;
}
Пример #11
0
/* 0 for Success
   -1 for SERVER_ERROR
*/
int bdb_set(char *key, item *it){
    pthread_rwlock_rdlock(&qlist_ht_lock);
    queue_t *q = (queue_t *)hashtable_search(qlist_htp, (void *)key);
    DB_TXN *txnp = NULL;
    int ret;

    if (NULL == q) {
        pthread_rwlock_unlock(&qlist_ht_lock);
        ret = bdb_create_queue(key);
        if (0 != ret){
            return -1;
        }
        /* search again */
        pthread_rwlock_rdlock(&qlist_ht_lock);
        q = (queue_t *)hashtable_search(qlist_htp, (void *)key);        
    }
    
    if (NULL != q) {
        db_recno_t recno;
        DBT dbkey, dbdata;    
        BDB_CLEANUP_DBT();
        dbkey.data = &recno;
        dbkey.ulen = sizeof(recno);
        dbkey.flags = DB_DBT_USERMEM;
        dbdata.data = it;
        dbdata.size = ITEM_ntotal(it);
        ret = envp->txn_begin(envp, NULL, &txnp, 0);
        CHECK_DB_RET(ret);
        ret = q->dbp->put(q->dbp, txnp, &dbkey, &dbdata, DB_APPEND);
        CHECK_DB_RET(ret);
        ret = txnp->commit(txnp, 0);
        CHECK_DB_RET(ret);
        pthread_mutex_lock(&(q->lock));
        (q->set_hits)++;
        pthread_mutex_unlock(&(q->lock));
    }
    pthread_rwlock_unlock(&qlist_ht_lock);    
    return 0;
dberr:
    if (txnp != NULL){
        txnp->abort(txnp);
    }
    if (settings.verbose > 1) {
        fprintf(stderr, "bdb_set: %s\n", db_strerror(ret));
    }
    pthread_rwlock_unlock(&qlist_ht_lock);
    return -1;
}
Пример #12
0
void
add_fruit(DB_ENV *dbenv, DB *db, char *fruit, char *name)
{
	DBT key, data;
	DB_TXN *tid;
	int ret;

	/* Initialization. */
	memset(&key, 0, sizeof(key));
	memset(&data, 0, sizeof(data));
	key.data = fruit;
	key.size = strlen(fruit);
	data.data = name;
	data.size = strlen(name);

	for (;;) {
		/* Begin the transaction. */
		if ((ret = dbenv->txn_begin(dbenv, NULL, &tid, 0)) != 0) {
			dbenv->err(dbenv, ret, "DB_ENV->txn_begin");
			exit (1);
		}

		/* Store the value. */
		switch (ret = db->put(db, tid, &key, &data, 0)) {
		case 0:
			/* Success: commit the change. */
			if ((ret = tid->commit(tid, 0)) != 0) {
				dbenv->err(dbenv, ret, "DB_TXN->commit");
				exit (1);
			}
			return;
		case DB_LOCK_DEADLOCK:
			/* Deadlock: retry the operation. */
			if ((ret = tid->abort(tid)) != 0) {
				dbenv->err(dbenv, ret, "DB_TXN->abort");
				exit (1);
			}
			break;
		default:
			/* Error: run recovery. */
			dbenv->err(dbenv, ret, "dbc->put: %s/%s", fruit, name);
			exit (1);
		}
	}
}
Пример #13
0
static int txn_op_commit(lua_State *L)
{
    DB_TXN** ptx = check_txn(L, 1);
    DB_TXN* tx = *ptx;
    u_int32_t flags = 0;
    int status;
    if (lua_gettop(L) > 1)
    {
        flags = luabdb_getflags(L, 2);
    }
    if (tx != NULL)
    {
        dbgprint("commit tran 0x%x\n", tx);
        status = tx->commit(tx, flags);
        handle_dbexception(L, status);
        *ptx = NULL;
    }
    return 0;
}
Пример #14
0
static void do_mode_user(void)
{
	char s[LINE_MAX + 1];
	DB_TXN *txn = NULL;
	int rc;

	rc = tdb.env->txn_begin(tdb.env, NULL, &txn, 0);
	if (rc) {
		fprintf(stderr, "txn_begin failed: %d\n", rc);
		exit(1);
	}

	while (fgets(s, sizeof(s), stdin) != NULL)
		user_line(txn, s);

	rc = txn->commit(txn, 0);
	if (rc) {
		fprintf(stderr, "txn_commit failed: %d\n", rc);
		exit(1);
	}
}
Пример #15
0
int
dbfe_opendb (DB_ENV *dbe, DB **dbp, str filename, int flags, int mode = 0664, bool dups = false)
{
  int r (-1);
  r = db_create (dbp, dbe, 0);
  if (r) return r;

  DB *db = *dbp;
  db->set_pagesize (db, 16 * 1024);

  /* Secondary databases, for example, require duplicates */
  if (dups && (r = db->set_flags (db, DB_DUPSORT)) != 0) {
    (void)db->close(db, 0);
    dbe->err (dbe, r, "db->set_flags: DB_DUP");
    return r;
  }

  /* the below seems to cause the db to grow much larger. */
  // db->set_bt_minkey(db, 60);

#if ((DB_VERSION_MAJOR < 4) || ((DB_VERSION_MAJOR == 4) && (DB_VERSION_MINOR < 1)))
  r = db->open (db, filename.cstr (), NULL, DB_BTREE, flags, mode);
#else
  if (!dbe) {
    r = db->open (db, NULL, filename.cstr (), NULL, DB_BTREE, flags, mode);
  } else {
    // Sleepycat 4.1 and greater force us to open the DB inside a
    // transaction the open suceeds in either case, but if the open
    // isn't surrounded by a transaction, later calls that use a
    // transaction will fail
    DB_TXN *t = NULL;
    r = dbe->txn_begin (dbe, NULL, &t, 0);
    if (r || !t) return r;
    r = db->open (db, t, filename.cstr (), NULL, DB_BTREE, flags, mode);
    r = t->commit (t, 0);
#endif
  }
  return r;
}
Пример #16
0
int bdb_delete_queue(char *queue_name){
    pthread_rwlock_wrlock(&qlist_ht_lock);
    queue_t *q = hashtable_search(qlist_htp, (void *)queue_name);
    /* NOT FOUND */
    if (q == NULL) {
        pthread_rwlock_unlock(&qlist_ht_lock);
        return 1;
    } 
    /* Found, just close and remove it. */
    q->dbp->close(q->dbp, 0);
    pthread_mutex_destroy(&(q->lock));
    q = hashtable_remove(qlist_htp, (void *)queue_name);
    assert(NULL != q);
    free(q);
    
    int ret;
    DB_TXN *txnp = NULL;
    ret = envp->txn_begin(envp, NULL, &txnp, 0);
    CHECK_DB_RET(ret);
    ret = envp->dbremove(envp, txnp, queue_name, NULL, 0);
    CHECK_DB_RET(ret);
    DBT dbkey;
    memset(&dbkey, 0, sizeof(dbkey));
    dbkey.data = (void *)queue_name;
    dbkey.size = strlen(queue_name) + 1;
    ret = qlist_dbp->del(qlist_dbp, txnp, &dbkey, 0);
    CHECK_DB_RET(ret);
    ret = txnp->commit(txnp, 0);
    CHECK_DB_RET(ret);
    pthread_rwlock_unlock(&qlist_ht_lock);
    return 0;
dberr:
    if (txnp != NULL){
        txnp->abort(txnp);
    }
    fprintf(stderr, "bdb_delete_queue: %s %s\n", queue_name, db_strerror(ret));
    pthread_rwlock_unlock(&qlist_ht_lock);
    return -1;
}
Пример #17
0
DWORD
BdbTxnCommit(
    PVDIR_BACKEND_CTX   pBECtx
    )
{
    DWORD   dwError = 0;
    DB_TXN* pTxn = NULL;

    assert(pBECtx);

    if (pBECtx->pBEPrivate)
    {
        assert(pBECtx->iBEPrivateRef >= 1);
        pBECtx->iBEPrivateRef--;

        if (pBECtx->iBEPrivateRef == 0)
        {
            pTxn = (DB_TXN*)pBECtx->pBEPrivate;
            pBECtx->pBEPrivate = NULL;

            dwError = pTxn->commit(pTxn, BDB_FLAGS_ZERO);
            BAIL_ON_VMDIR_ERROR(dwError);
        }
    }

cleanup:

    return dwError;

error:

    dwError = BdbToBackendError(dwError, 0, ERROR_BACKEND_ERROR, pBECtx);

    VMDIR_SAFE_FREE_MEMORY(pBECtx->pszBEErrorMsg);
    VmDirAllocateStringA(db_strerror(pBECtx->dwBEErrorCode), &pBECtx->pszBEErrorMsg);

    goto cleanup;
}
Пример #18
0
 DB* PerconaFTEngine::GetFTDB(Context& ctx, const Data& ns, bool create_if_missing)
 {
     RWLockGuard<SpinRWLock> guard(m_lock, !create_if_missing);
     FTDBTable::iterator found = m_dbs.find(ns);
     if (found != m_dbs.end())
     {
         return found->second;
     }
     if (!create_if_missing)
     {
         return NULL;
     }
     DB *db = NULL;
     int r = 0;
     CHECK_EXPR(r = db_create(&db, m_env, 0));
     if (0 == r)
     {
         DB_TXN* txn = NULL;
         CHECK_EXPR(m_env->txn_begin(m_env, NULL, &txn, 0));
         uint32 open_flags = DB_CREATE | DB_THREAD;
         int open_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
         CHECK_EXPR(r = db->open(db, txn, ns.AsString().c_str(), NULL, DB_BTREE, open_flags, open_mode));
         txn->commit(txn, 0);
     }
     if (0 == r)
     {
         db->set_compression_method(db, g_perconaft_config.compression);
         m_dbs[ns] = db;
         INFO_LOG("Success to open db:%s", ns.AsString().c_str());
     }
     else
     {
         free(db);
         db = NULL;
         ERROR_LOG("Failed to open db:%s for reason:(%d)%s", ns.AsString().c_str(), r, db_strerror(r));
     }
     return db;
 }
Пример #19
0
void
run_xact(DB_ENV *dbenv, DB *db, int offset, int count)
{
	va_list ap;
	DBC *dbc;
	DBT key, data;
	DB_TXN *tid;
	int ret;
	char *s;

	/* Initialization. */
	memset(&key, 0, sizeof(key));
	memset(&data, 0, sizeof(data));
	int keyPtr;
	int valPtr;
	key.data = &keyPtr;
	key.size = sizeof(int);/*strlen(name);*/
	data.data = &valPtr;
	data.size = sizeof(int);

retry:	/* Begin the transaction. */
	if ((ret = dbenv->txn_begin(dbenv, NULL, &tid, 0)) != 0) {
		dbenv->err(dbenv, ret, "DB_ENV->txn_begin");
		exit (1);
	}

	/* Delete any previously existing item. */
	/*	switch (ret = db->del(db, tid, &key, 0)) {
	case 0:
	case DB_NOTFOUND:
		break;
	case DB_LOCK_DEADLOCK:
		/ * Deadlock: retry the operation. * /
		if ((ret = tid->abort(tid)) != 0) {
			dbenv->err(dbenv, ret, "DB_TXN->abort");
			exit (1);
		}
		goto retry;
	default:
		dbenv->err(dbenv, ret, "db->del: %s", name);
		exit (1);
		} */
 
	/* Create a cursor. */
	if ((ret = db->cursor(db, tid, &dbc, 0)) != 0) {
		dbenv->err(dbenv, ret, "db->cursor");
		exit (1);
	}

	/* Append the items, in order. */
	//	va_start(ap, name);
	//	while ((s = va_arg(ap, char *)) != NULL) {
	int q;
	for(q = offset; q < offset + count; q++) {
	  keyPtr = q;
	  valPtr = q;
	  /*		data.data = s;
			data.size = strlen(s); */
	  //	  printf("A"); fflush(NULL);
		switch (ret = dbc->c_put(dbc, &key, &data, DB_KEYLAST)) {
		case 0:
		  //		  printf("B"); fflush(NULL);
			break;
		case DB_LOCK_DEADLOCK:
			va_end(ap);

			/* Deadlock: retry the operation. */
			if ((ret = dbc->c_close(dbc)) != 0) {
				dbenv->err(
				    dbenv, ret, "dbc->c_close");
				exit (1);
			}
			if ((ret = tid->abort(tid)) != 0) {
				dbenv->err(dbenv, ret, "DB_TXN->abort");
				exit (1);
			}
			goto retry;
		default:
			/* Error: run recovery. */
			dbenv->err(dbenv, ret, "dbc->put: %d/%d", q, q);
			exit (1);
		}
	}
	va_end(ap);

	/* Success: commit the change. */
	if ((ret = dbc->c_close(dbc)) != 0) {
		dbenv->err(dbenv, ret, "dbc->c_close");
		exit (1);
	}
	if ((ret = tid->commit(tid, 0)) != 0) {
		dbenv->err(dbenv, ret, "DB_TXN->commit");
		exit (1);
	}
}
Пример #20
0
void
add_cat(DB_ENV *dbenv, DB *db, char *name, ...)
{
	va_list ap;
	DBC *dbc;
	DBT key, data;
	DB_TXN *tid;
	int ret;
	char *s;

	/* Initialization. */
	memset(&key, 0, sizeof(key));
	memset(&data, 0, sizeof(data));
	key.data = name;
	key.size = strlen(name);

retry:	/* Begin the transaction. */
	if ((ret = dbenv->txn_begin(dbenv, NULL, &tid, 0)) != 0) {
		dbenv->err(dbenv, ret, "DB_ENV->txn_begin");
		exit (1);
	}

	/* Delete any previously existing item. */
	switch (ret = db->del(db, tid, &key, 0)) {
	case 0:
	case DB_NOTFOUND:
		break;
	case DB_LOCK_DEADLOCK:
		/* Deadlock: retry the operation. */
		if ((ret = tid->abort(tid)) != 0) {
			dbenv->err(dbenv, ret, "DB_TXN->abort");
			exit (1);
		}
		goto retry;
	default:
		dbenv->err(dbenv, ret, "db->del: %s", name);
		exit (1);
	}

	/* Create a cursor. */
	if ((ret = db->cursor(db, tid, &dbc, 0)) != 0) {
		dbenv->err(dbenv, ret, "db->cursor");
		exit (1);
	}

	/* Append the items, in order. */
	va_start(ap, name);
	while ((s = va_arg(ap, char *)) != NULL) {
		data.data = s;
		data.size = strlen(s);
		switch (ret = dbc->c_put(dbc, &key, &data, DB_KEYLAST)) {
		case 0:
			break;
		case DB_LOCK_DEADLOCK:
			va_end(ap);

			/* Deadlock: retry the operation. */
			if ((ret = dbc->c_close(dbc)) != 0) {
				dbenv->err(
				    dbenv, ret, "dbc->c_close");
				exit (1);
			}
			if ((ret = tid->abort(tid)) != 0) {
				dbenv->err(dbenv, ret, "DB_TXN->abort");
				exit (1);
			}
			goto retry;
		default:
			/* Error: run recovery. */
			dbenv->err(dbenv, ret, "dbc->put: %s/%s", name, s);
			exit (1);
		}
	}
	va_end(ap);

	/* Success: commit the change. */
	if ((ret = dbc->c_close(dbc)) != 0) {
		dbenv->err(dbenv, ret, "dbc->c_close");
		exit (1);
	}
	if ((ret = tid->commit(tid, 0)) != 0) {
		dbenv->err(dbenv, ret, "DB_TXN->commit");
		exit (1);
	}
}
Пример #21
0
void
add_color(DB_ENV *dbenv, DB *dbp, char *color, int increment)
{
	DBT key, data;
	DB_TXN *tid;
	int original, ret;
	char buf[64];

	/* Initialization. */
	memset(&key, 0, sizeof(key));
	key.data = color;
	key.size = strlen(color);
	memset(&data, 0, sizeof(data));
	data.flags = DB_DBT_MALLOC;

	for (;;) {
		/* Begin the transaction. */
		if ((ret = dbenv->txn_begin(dbenv, NULL, &tid, 0)) != 0) {
			dbenv->err(dbenv, ret, "DB_ENV->txn_begin");
			exit (1);
		}

		/*
		 * Get the key.  If it exists, we increment the value.  If it
		 * doesn't exist, we create it.
		 */
		switch (ret = dbp->get(dbp, tid, &key, &data, 0)) {
		case 0:
			original = atoi(data.data);
			break;
		case DB_LOCK_DEADLOCK:
			/* Deadlock: retry the operation. */
			if ((ret = tid->abort(tid)) != 0) {
				dbenv->err(dbenv, ret, "DB_TXN->abort");
				exit (1);
			}
			continue;
		case DB_NOTFOUND:
			original = 0;
			break;
		default:
			/* Error: run recovery. */
			dbenv->err(
			    dbenv, ret, "dbc->get: %s/%d", color, increment);
			exit (1);
		}
		if (data.data != NULL)
			free(data.data);

		/* Create the new data item. */
		(void)snprintf(buf, sizeof(buf), "%d", original + increment);
		data.data = buf;
		data.size = strlen(buf) + 1;

		/* Store the new value. */
		switch (ret = dbp->put(dbp, tid, &key, &data, 0)) {
		case 0:
			/* Success: commit the change. */
			if ((ret = tid->commit(tid, 0)) != 0) {
				dbenv->err(dbenv, ret, "DB_TXN->commit");
				exit (1);
			}
			return;
		case DB_LOCK_DEADLOCK:
			/* Deadlock: retry the operation. */
			if ((ret = tid->abort(tid)) != 0) {
				dbenv->err(dbenv, ret, "DB_TXN->abort");
				exit (1);
			}
			break;
		default:
			/* Error: run recovery. */
			dbenv->err(
			    dbenv, ret, "dbc->put: %s/%d", color, increment);
			exit (1);
		}
	}
}
Пример #22
0
int
b_txn(int argc, char *argv[])
{
    extern char *optarg;
    extern int optind;
    DB_ENV *dbenv;
    DB_TXN *txn;
    int tabort, ch, i, count;

    count = 1000;
    tabort = 0;
    while ((ch = getopt(argc, argv, "ac:")) != EOF)
        switch (ch) {
        case 'a':
            tabort = 1;
            break;
        case 'c':
            count = atoi(optarg);
            break;
        case '?':
        default:
            return (usage());
        }
    argc -= optind;
    argv += optind;
    if (argc != 0)
        return (usage());

    /* Create the environment. */
    DB_BENCH_ASSERT(db_env_create(&dbenv, 0) == 0);
    dbenv->set_errfile(dbenv, stderr);
#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR < 1
    DB_BENCH_ASSERT(dbenv->open(dbenv, TESTDIR,
                                NULL, DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG |
                                DB_INIT_MPOOL | DB_INIT_TXN | DB_PRIVATE, 0666) == 0);
#else
    DB_BENCH_ASSERT(dbenv->open(dbenv, TESTDIR,
                                DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG |
                                DB_INIT_MPOOL | DB_INIT_TXN | DB_PRIVATE, 0666) == 0);
#endif

    /* Start and commit/abort a transaction count times. */
    TIMER_START;
    if (tabort)
        for (i = 0; i < count; ++i) {
#if DB_VERSION_MAJOR < 4
            DB_BENCH_ASSERT(txn_begin(dbenv, NULL, &txn, 0) == 0);
            DB_BENCH_ASSERT(txn_abort(txn) == 0);
#else
            DB_BENCH_ASSERT(
                dbenv->txn_begin(dbenv, NULL, &txn, 0) == 0);
            DB_BENCH_ASSERT(txn->abort(txn) == 0);
#endif
        }
    else
        for (i = 0; i < count; ++i) {
#if DB_VERSION_MAJOR < 4
            DB_BENCH_ASSERT(txn_begin(dbenv, NULL, &txn, 0) == 0);
            DB_BENCH_ASSERT(txn_commit(txn, 0) == 0);
#else
            DB_BENCH_ASSERT(
                dbenv->txn_begin(dbenv, NULL, &txn, 0) == 0);
            DB_BENCH_ASSERT(txn->commit(txn, 0) == 0);
#endif
        }
    TIMER_STOP;

    printf("# %d empty transaction start/%s pairs\n",
           count, tabort ? "abort" : "commit");
    TIMER_DISPLAY(count);

    DB_BENCH_ASSERT(dbenv->close(dbenv, 0) == 0);

    return (0);
}
Пример #23
0
/*
 * A function that performs a series of writes to a
 * Berkeley DB database. The information written
 * to the database is largely nonsensical, but the
 * mechanism of transactional commit/abort and
 * deadlock detection is illustrated here.
 */
void *
writer_thread(void *args)
{
    static char *key_strings[] = {
	"key 1", "key 2", "key 3", "key 4", "key 5",
	"key 6", "key 7", "key 8", "key 9", "key 10"
    };
    DB *dbp;
    DB_ENV *envp;
    DBT key, value;
    DB_TXN *txn;
    int i, j, payload, ret, thread_num;
    int retry_count, max_retries = 20;   /* Max retry on a deadlock */

    dbp = (DB *)args;
    envp = dbp->get_env(dbp);

    /* Get the thread number */
    (void)mutex_lock(&thread_num_lock);
    global_thread_num++;
    thread_num = global_thread_num;
    (void)mutex_unlock(&thread_num_lock);

    /* Initialize the random number generator */
    srand(thread_num);

    /* Write 50 times and then quit */
    for (i = 0; i < 50; i++) {
	retry_count = 0; /* Used for deadlock retries */

	/*
	 * Some think it is bad form to loop with a goto statement, but
	 * we do it anyway because it is the simplest and clearest way
	 * to achieve our abort/retry operation.
	 */
retry:
	/* Begin our transaction. We group multiple writes in
	 * this thread under a single transaction so as to
	 * (1) show that you can atomically perform multiple writes
	 * at a time, and (2) to increase the chances of a
	 * deadlock occurring so that we can observe our
	 * deadlock detection at work.
	 *
	 * Normally we would want to avoid the potential for deadlocks,
	 * so for this workload the correct thing would be to perform our
	 * puts with autocommit. But that would excessively simplify our
	 * example, so we do the "wrong" thing here instead.
	 */
	ret = envp->txn_begin(envp, NULL, &txn, 0);
	if (ret != 0) {
	    envp->err(envp, ret, "txn_begin failed");
	    return ((void *)EXIT_FAILURE);
	}
	for (j = 0; j < 10; j++) {
	    /* Set up our key and values DBTs */
	    memset(&key, 0, sizeof(DBT));
	    key.data = key_strings[j];
	    key.size = (u_int32_t)strlen(key_strings[j]) + 1;

	    memset(&value, 0, sizeof(DBT));
	    payload = rand() + i;
	    value.data = &payload;
	    value.size = sizeof(int);

	    /* Perform the database put. */
	    switch (ret = dbp->put(dbp, txn, &key, &value, 0)) {
		case 0:
		    break;

		/*
		 * Here's where we perform deadlock detection. If
		 * DB_LOCK_DEADLOCK is returned by the put operation,
		 * then this thread has been chosen to break a deadlock.
		 * It must abort its operation, and optionally retry the
		 * put.
		 */
		case DB_LOCK_DEADLOCK:
		    /*
		     * First thing that we MUST do is abort the
		     * transaction.
		     */
		    (void)txn->abort(txn);
		    /*
		     * Now we decide if we want to retry the operation.
		     * If we have retried less than max_retries,
		     * increment the retry count and goto retry.
		     */
		    if (retry_count < max_retries) {
			printf("Writer %i: Got DB_LOCK_DEADLOCK.\n",
			    thread_num);
			printf("Writer %i: Retrying write operation.\n",
			    thread_num);
			retry_count++;
			goto retry;
		    }
		    /*
		     * Otherwise, just give up.
		     */
		    printf("Writer %i: ", thread_num);
		    printf("Got DB_LOCK_DEADLOCK and out of retries.\n");
		    printf("Writer %i: Giving up.\n", thread_num);
		    return ((void *)EXIT_FAILURE);
		/*
		 * If a generic error occurs, we simply abort the
		 * transaction and exit the thread completely.
		 */
		default:
		    envp->err(envp, ret, "db put failed");
		    ret = txn->abort(txn);
		    if (ret != 0)
			envp->err(envp, ret, "txn abort failed");
		    return ((void *)EXIT_FAILURE);
	     } /** End case statement **/

	}   /** End for loop **/

	/*
	 * print the number of records found in the database.
	 * See count_records() for usage information.
	 */
	printf("Thread %i. Record count: %i\n", thread_num,
	    count_records(dbp, txn));

	/*
	 * If all goes well, we can commit the transaction and
	 * exit the thread.
	 */
	ret = txn->commit(txn, 0);
	if (ret != 0) {
	    envp->err(envp, ret, "txn commit failed");
	    return ((void *)EXIT_FAILURE);
	}
    }
    return ((void *)EXIT_SUCCESS);
}
Пример #24
0
static int
process_smtp_rcpt(int crypted)
{
    double delay;
    int rc;
    DB_ENV *dbenv;
    DB *db;
    DB_TXN *txn = NULL;
    if (setjmp(defect_jmp_buf)) {
	if (defect_msg) {
	    printf(STR_ACTION "WARN %s\n", defect_msg);
	    defect_msg = 0;
	}
	else
	    puts(STR_ACTION "WARN " PACKAGE_STRING " is not working properly");
	if (txn)
	    call_db(txn->abort(txn), "Failed to abort transaction");
	return 1;
    }
    rc = get_dbenv(&dbenv, 1);
    if (rc)
	jmperr("get_dbenv failed");
    rc = get_db(&db, 1);
    if (rc)
	jmperr("get_db failed");
    rc = call_db(dbenv->txn_begin(dbenv, NULL, &txn, 0),
		 "txn_begin failed in process_smtp_rcpt");
    if (rc)
	jmperr("txn_begin failed");
    get_grey_data(db, txn);
    if (triplet_data.crypted != crypted) {
      triplet_data.crypted = crypted;
      if (debug_me) syslog(LOG_DEBUG,"crypted field changed for some reason");
    }
    delay = difftime(triplet_data.access_time, triplet_data.create_time);
    /* Block inbound mail that is from a previously unknown (ip, from, to) triplet */
    /* However we want different behavior for crypted stuff
     */

    if(crypted > 0) {
      if(delay < cryptlist_delay) {
	triplet_data.block_count++;
	fputs(STR_ACTION, stdout);
	printf_action(reject_action_fmt, greylist_delay - delay);
	putchar('\n');
    }
    else if (triplet_data.pass_count++)
	puts(STR_ACTION "DUNNO");
      else {
        fputs(STR_ACTION, stdout);
        printf_action(cryptlisted_action_fmt, delay);
        putchar('\n');
      }
    } else {
      if(delay < greylist_delay || block_unencrypted) {
        triplet_data.block_count++;
        fputs(STR_ACTION, stdout);
        if(block_unencrypted == 1) {
          printf_action(reject_unencrypted_action_fmt, (3600*24)); // block it for a day
        } else {
          printf_action(reject_unencrypted_action_fmt, greylist_delay - delay);
        }
        putchar('\n');
      }
      else if (triplet_data.pass_count++)
        puts(STR_ACTION "DUNNO");
      else {
        fputs(STR_ACTION, stdout);
        printf_action(greylisted_action_fmt, delay);
        putchar('\n');
      }
    }
    rc = put_grey_data(db, txn);
    if (rc)
	call_db(txn->abort(txn), "abort failed");
    else
	call_db(txn->commit(txn, 0), "commit failed");
    return rc;
}
Пример #25
0
/* Upgrade the database from v0 format to the new format */
static int
upgrade_from_v0(DB_ENV *dbenv)
{
    DB *db0 = NULL, *db1 = NULL;
    DB_TXN *tid = NULL;
    DBC *cursor = NULL;
    DBT key = { 0 }, data = { 0 };
    int rc = call_db(dbenv->txn_begin(dbenv, NULL, &tid, 0),
		     "upgrade_from_v0 dbenv->txn_begin");
    if (!rc)
	rc = call_db(db_create(&db0, dbenv, 0), "upgrade_from_v0 db_create 0");
    if (!rc) {
	/* XXX do not use call_db: it is normal for this call to fail,
	   if there is no database to upgrade from. */
	rc = db0->open(db0, tid, DB_FILE_NAME_V0, NULL, DB_UNKNOWN, 0, 0644);
	if (rc == ENOENT) {
	    call_db(db0->close(db0, 0), "upgrade_from_v0 db0->close 0");
	    call_db(tid->commit(tid, 0), "upgrade_from_v0 tid->commit 0");
	    return 0;
	}
    }
    if (!rc) {
	syslog(LOG_WARNING, "Upgrading from database format v0");
	rc = call_db(db_create(&db1, dbenv, 0), "upgrade_from_v0 db_create 1");
    }
    if (!rc)
	rc = call_db(db1->open(db1, tid,
			       DB_FILE_NAME, NULL,
			       DB_BTREE, DB_CREATE | DB_EXCL, 0644),
		     "upgrade_from_v0 db1->open");
    if (!rc)
	rc = call_db(db0->cursor(db0, tid, &cursor, 0),
		     "upgrade_from_v0 db0->cursor");
    size_t buffer_size = 0;
    char *buffer = 0;
    while (!rc) {
	rc = cursor->get(cursor, &key, &data, DB_NEXT);
	if (rc == DB_NOTFOUND) {
	    /* this is expected result, do commit this transaction */
	    rc = 0;
	    break;
	}
	else if (rc) {
	    call_db(rc, "upgrade_from_v0 cursor->get");
	    break;
	}
	/* Convert this entry to new format */
	char *s, *ip, *from, *to;
	size_t iplen, fromlen, tolen;
	ip = key.data;
	iplen = strlen(ip);
	from = ip + iplen + 1;
	fromlen = strlen(from);
	to = from + fromlen + 1;
	tolen = key.size - fromlen - iplen - 2;
	int count = 0;
	for (s = strchr(ip, '.'); s != NULL; s = strchr(s + 1, '.'))
	    count++;
	s = ensure_dbkey_reserve(MAX(MAX(sizeof(struct in_addr),
					 sizeof(struct in6_addr)),
				     iplen + 1)
				 + fromlen + tolen + 2);
	if (count) {
	    /* This is supposedly an IPv4 address. Complete it with
	       trailing zeroes. A complete IPv4 address has 3 dots and
	       4 numbers. For each missing dot, add the dot and a 0. */
	    size_t needed = iplen + 2 * (3 - count) + 1;
	    if (buffer_size < needed) {
		buffer = xrealloc(buffer, needed);
		buffer_size = needed;
	    }
	    strcpy(buffer, ip);
	    while (count++ < 3)
		strcat(buffer, ".0");
	    *s++ = DBKEY_T_IP4;
	    rc = inet_pton(AF_INET, buffer, s);
	    s += sizeof(struct in_addr);
	    if (rc == -1)
		rc = errno;
	    else if (rc == 1)
		rc = 0;
	    else
		rc = EINVAL;
	    if (rc)
		break;		/* error */
	}
	else {
	    /* Try it as an IPv6 address. v0 format did not abbreviate
	       IPv6 addresses. */
	    *s++ = DBKEY_T_IP6;
	    if (inet_pton(AF_INET6, ip, s) == 1)
		s += sizeof(struct in6_addr);
	    else {
		/* Not IPv4 neither IPv6. Keep it in its raw form */
		*s++ = DBKEY_T_RAW;
		strcpy(s, ip);
		s += iplen + 1;
	    }
	}
	strcpy(s, from);
	s += fromlen + 1;
	memcpy(s, to, tolen);
	s += tolen;
	dbkey.size = s - (char*)dbkey.data;
	rc = call_db(db1->put(db1, tid, &dbkey, &data, DB_NOOVERWRITE),
		     "upgrade_from_v0 db1->put");
    }
    if (buffer != NULL)
	free(buffer);
    if (cursor != NULL)
	call_db(cursor->close(cursor), "upgrade_from_v0 cursor->close");
    if (db1 != NULL)
	call_db(db1->close(db1, 0), "upgrade_from_v0 db1->close");
    if (db0 != NULL)
	call_db(db0->close(db0, 0), "upgrade_from_v0 db0->close");
    if (!rc)
	rc = call_db(dbenv->dbremove(dbenv, tid, DB_FILE_NAME_V0, NULL, 0),
		     "upgrade_from_v0 dbenv->dbremove");
    if (tid != NULL) {
	if (rc)
	    call_db(tid->abort(tid), "upgrade_from_v0 tid->abort");
	else
	    call_db(tid->commit(tid, 0), "upgrade_from_v0 tid->commit");
    }
    return rc;
}
Пример #26
0
static void
run_expiry()
{
    DB_ENV *dbenv;
    DB *db;
    DB_TXN *txn;
    DBC *dbcp;
    int rc;
    time_t now;
    DBT key = { 0 };
    unsigned int count = 0;
    if (exit_requested)
	return;
    /* Cursor operations can hold several locks and therefore deadlock
       so don't run expiry if deadlock detection does not work
       http://docs.oracle.com/cd/E17076_02/html/programmer_reference/lock_notxn.html */
    rc = get_db(&db, 0);
    assert(! rc);
    if (db == 0 || deadlock_detect == 0)
	return;
    rc = get_dbenv(&dbenv, 0);
    assert(! rc && dbenv);
    if (time(&now) == (time_t)-1) {
	syslog(LOG_ERR, "time failed during run_expiry");
	return;
    }
    muffle_error++;
    rc = dbenv->txn_begin(dbenv, NULL, &txn, DB_TXN_NOWAIT);
    if (rc) {
	if (rc == DB_LOCK_DEADLOCK)
	    syslog(LOG_DEBUG, "skipping concurrent expiry avoids "
		   "deadlocks and unnecessary work");
	else
	    log_db_error("txn_begin failed during run_expiry", rc);
	goto out;
    }
#if DB_VERSION_MAJOR >= 5
    call_db(txn->set_priority(txn, 50), "TXN->set_priority");
#endif
    rc = call_db(db->cursor(db, txn, &dbcp, 0),
		 "db->cursor failed during expiry run");
    if (rc)
	goto txn_fail;
    while ((rc = dbcp->c_get(dbcp, &key, &dbdata, DB_NEXT | DB_RMW)) == 0) {
	time_t ref_time;
	double age_max, age;
	if (triplet_data.pass_count) {
	    ref_time = triplet_data.access_time;
	    age_max = pass_max_idle;
	}
	else {
	    ref_time = triplet_data.create_time;
	    age_max = bloc_max_idle;
	}
	age = difftime(now, ref_time);
	if (age > age_max) {
	    if (opt_verbose) {
		syslog(LOG_INFO, "Expiring %s %s after %.0f seconds idle",
		       db_key_ntop(key.data),
		       triplet_data.pass_count ? "pass" : "block", age);
	    }
	    rc = call_db(dbcp->c_del(dbcp, 0), "dbcp->c_del failed");
	    if (rc)
		goto cursor_fail;
	    count++;
	}
	if (exit_requested)
	    break;
    }
    if (rc && rc != DB_NOTFOUND) {
	if (rc == DB_LOCK_DEADLOCK)
	    syslog(LOG_NOTICE, "Aborting concurrent expiry due to deadlock");
	else
	    log_db_error("dbcp->c_get failed", rc);
	goto cursor_fail;
    }
    if (call_db(dbcp->c_close(dbcp), "dbcp->c_close failed"))
	goto txn_fail;
    call_db(txn->commit(txn, 0), "commit failed in run_expiry");
    if (count)
	syslog(LOG_NOTICE, "Expired %u triplets", count);
    goto out;

  cursor_fail:
    call_db(dbcp->c_close(dbcp), "dbcp->c_close failed");
  txn_fail:
    call_db(txn->abort(txn), "failed to abort");
  out:
    muffle_error--;
    return;
}
Пример #27
0
icalerrorenum icalbdbset_commit(icalset *set)
{
    DB *dbp;
    DBC *dbcp;
    DBT key, data;
    icalcomponent *c;
    char *str = NULL;
    int ret = 0;
    int reterr = ICAL_NO_ERROR;
    char keystore[256];
    char uidbuf[256];
    char datastore[1024];
    char *more_mem = NULL;
    DB_TXN *tid = NULL;
    icalbdbset *bset = (icalbdbset *) set;
    int bad_uid_counter = 0;
    int retry = 0, done = 0, completed = 0, deadlocked = 0;

    icalerror_check_arg_re((bset != 0), "bset", ICAL_BADARG_ERROR);

    dbp = bset->dbp;
    icalerror_check_arg_re((dbp != 0), "dbp is invalid", ICAL_BADARG_ERROR);

    if (bset->changed == 0) {
        return ICAL_NO_ERROR;
    }

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

    key.flags = DB_DBT_USERMEM;
    key.data = keystore;
    key.ulen = (u_int32_t) sizeof(keystore);

    data.flags = DB_DBT_USERMEM;
    data.data = datastore;
    data.ulen = (u_int32_t) sizeof(datastore);

    if (!ICAL_DB_ENV) {
        if (icalbdbset_init_dbenv(NULL, NULL) != 0) {
            return ICAL_INTERNAL_ERROR;
        }
    }

    while ((retry < MAX_RETRY) && !done) {

        if ((ret = ICAL_DB_ENV->txn_begin(ICAL_DB_ENV, NULL, &tid, 0)) != 0) {
            if (ret == DB_LOCK_DEADLOCK) {
                retry++;
                continue;
            } else if (ret == DB_RUNRECOVERY) {
                ICAL_DB_ENV->err(ICAL_DB_ENV, ret, "icalbdbset_commit: txn_begin failed");
                abort();
            } else {
                ICAL_DB_ENV->err(ICAL_DB_ENV, ret, "icalbdbset_commit");
                return ICAL_INTERNAL_ERROR;
            }
        }

        /* first delete everything in the database, because there could be removed components */
        if ((ret = dbp->cursor(dbp, tid, &dbcp, DB_DIRTY_READ)) != 0) {
            tid->abort(tid);
            if (ret == DB_LOCK_DEADLOCK) {
                retry++;
                continue;
            } else if (ret == DB_RUNRECOVERY) {
                ICAL_DB_ENV->err(ICAL_DB_ENV, ret, "curor failed");
                abort();
            } else {
                ICAL_DB_ENV->err(ICAL_DB_ENV, ret, "curor failed");
                /* leave bset->changed set to true */
                return ICAL_INTERNAL_ERROR;
            }
        }

        /* fetch the key/data pair, then delete it */
        completed = 0;
        while (!completed && !deadlocked) {
            ret = dbcp->c_get(dbcp, &key, &data, DB_NEXT);
            if (ret == DB_NOTFOUND) {
                completed = 1;
            } else if (ret == ENOMEM) {
                if (more_mem) {
                    free(more_mem);
                }
                more_mem = malloc(data.ulen + 1024);
                data.data = more_mem;
                data.ulen = data.ulen + 1024;
            } else if (ret == DB_LOCK_DEADLOCK) {
                deadlocked = 1;
            } else if (ret == DB_RUNRECOVERY) {
                tid->abort(tid);
                ICAL_DB_ENV->err(ICAL_DB_ENV, ret, "c_get failed.");
                abort();
            } else if (ret == 0) {
                if ((ret = dbcp->c_del(dbcp, 0)) != 0) {
                    dbp->err(dbp, ret, "cursor");
                    if (ret == DB_KEYEMPTY) {
                        /* never actually created, continue onward.. */
                        /* do nothing - break; */
                    } else if (ret == DB_LOCK_DEADLOCK) {
                        deadlocked = 1;
                    } else {
                        /*char *foo = db_strerror(ret); */
                        abort();
                    }
                }
            } else {    /* some other non-fatal error */
                dbcp->c_close(dbcp);
                tid->abort(tid);
                if (more_mem) {
                    free(more_mem);
                    more_mem = NULL;
                }
                return ICAL_INTERNAL_ERROR;
            }
        }

        if (more_mem) {
            free(more_mem);
            more_mem = NULL;
        }

        if (deadlocked) {
            dbcp->c_close(dbcp);
            tid->abort(tid);
            retry++;
            continue;   /* next retry */
        }

        deadlocked = 0;
        for (c = icalcomponent_get_first_component(bset->cluster, ICAL_ANY_COMPONENT);
             c != 0 && !deadlocked;
             c = icalcomponent_get_next_component(bset->cluster, ICAL_ANY_COMPONENT)) {

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

            /* Note that we're always inserting into a primary index. */
            if (icalcomponent_isa(c) != ICAL_VAGENDA_COMPONENT) {
                char *uidstr = (char *)icalcomponent_get_uid(c);

                if (!uidstr) {  /* this shouldn't happen */
                    /* no uid string, we need to add one */
                    snprintf(uidbuf, 256, "baduid%d-%d", getpid(), bad_uid_counter++);
                    key.data = uidbuf;
                } else {
                    key.data = uidstr;
                }
            } else {
                char *relcalid = NULL;

                relcalid = (char *)icalcomponent_get_relcalid(c);
                if (relcalid == NULL) {
                    snprintf(uidbuf, 256, "baduid%d-%d", getpid(), bad_uid_counter++);
                    key.data = uidbuf;
                } else {
                    key.data = relcalid;
                }
            }
            key.size = (u_int32_t) strlen(key.data);

            str = icalcomponent_as_ical_string_r(c);
            data.data = str;
            data.size = (u_int32_t) strlen(str);

            if ((ret = dbcp->c_put(dbcp, &key, &data, DB_KEYLAST)) != 0) {
                if (ret == DB_LOCK_DEADLOCK) {
                    deadlocked = 1;
                } else if (ret == DB_RUNRECOVERY) {
                    ICAL_DB_ENV->err(ICAL_DB_ENV, ret, "c_put failed.");
                    abort();
                } else {
                    ICAL_DB_ENV->err(ICAL_DB_ENV, ret, "c_put failed %s.", str);
                    /* continue to try to put as many icalcomponent as possible */
                    reterr = ICAL_INTERNAL_ERROR;
                }
            }
        }

        if (str) {
            free(str);
        }

        if (deadlocked) {
            dbcp->c_close(dbcp);
            tid->abort(tid);
            retry++;
            continue;
        }

        if ((ret = dbcp->c_close(dbcp)) != 0) {
            tid->abort(tid);
            if (ret == DB_LOCK_DEADLOCK) {
                retry++;
                continue;
            } else if (ret == DB_RUNRECOVERY) {
                ICAL_DB_ENV->err(ICAL_DB_ENV, ret, "c_closed failed.");
                abort();
            } else {
                ICAL_DB_ENV->err(ICAL_DB_ENV, ret, "c_closed failed.");
                reterr = ICAL_INTERNAL_ERROR;
            }
        }

        if ((ret = tid->commit(tid, 0)) != 0) {
            tid->abort(tid);
            if (ret == DB_LOCK_DEADLOCK) {
                retry++;
                continue;
            } else if (ret == DB_RUNRECOVERY) {
                ICAL_DB_ENV->err(ICAL_DB_ENV, ret, "commit failed.");
                abort();
            } else {
                ICAL_DB_ENV->err(ICAL_DB_ENV, ret, "commit failed.");
                reterr = ICAL_INTERNAL_ERROR;
            }
        }

        done = 1;
    }

    bset->changed = 0;
    return reterr;
}
Пример #28
0
int main(int argc, char **argv) {
	DB *dbp;
	DB_ENV *dbenv;
	DBT key, data;
	db_recno_t recno;
	DB_TXN *xid;

	int num_xactions;
	int  num_inserts_per_xaction;
	char *string;
	int i, j;



	if (argc != 3)  {
		printf("usage: %s <num xactions> <num inserts per xaction>\n", argv[0]);
		exit(-1);
	}

	num_xactions = atoi(argv[1]);
	num_inserts_per_xaction = atoi(argv[2]);

	env_dir_create();
	env_open(&dbenv);
	rand_str_init();

	if (db_open(dbenv, &dbp, DATABASE, 0)) {
		return (1); 	
	}

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

	recno = 1;
	for (i = 1; i <= num_xactions; i++ ) {

		dbenv->txn_begin(dbenv, NULL, &xid, 0);

		for (j = 0; j < num_inserts_per_xaction; j++) {

			string = rand_str();

			key.size = sizeof(recno);
			key.data = &recno;
			data.size = strlen(string) + 1; // + 1 for the null terminator	
			data.data = string;
			
/*
			if(VERBOSE) {
				printf("%s\n", string);
			}
*/
			dbp->put(dbp, xid, &key, &data, 0);
			recno++;
			/* Its unclear from BDB docs whether we should free string */
		}

		xid->commit(xid, 0);
	}


	return 0;
}
Пример #29
0
static void
b_inmem_op_tds(u_int ops, int update, u_int32_t env_flags, u_int32_t log_flags)
{
	DB *dbp;
	DBT key, data;
	DB_ENV *dbenv;
	DB_MPOOL_STAT  *gsp;
	DB_TXN *txn;
	char *keybuf, *databuf;

	DB_BENCH_ASSERT((keybuf = malloc(keysize)) != NULL);
	DB_BENCH_ASSERT((databuf = malloc(datasize)) != NULL);

	memset(&key, 0, sizeof(key));
	memset(&data, 0, sizeof(data));
	key.data = keybuf;
	key.size = keysize;
	memset(keybuf, 'a', keysize);

	data.data = databuf;
	data.size = datasize;
	memset(databuf, 'b', datasize);

	DB_BENCH_ASSERT(db_env_create(&dbenv, 0) == 0);

	dbenv->set_errfile(dbenv, stderr);

	/* General environment configuration. */
#ifdef DB_AUTO_COMMIT
	DB_BENCH_ASSERT(dbenv->set_flags(dbenv, DB_AUTO_COMMIT, 1) == 0);
#endif
	if (env_flags != 0)
		DB_BENCH_ASSERT(dbenv->set_flags(dbenv, env_flags, 1) == 0);

	/* Logging configuration. */
	if (log_flags != 0)
#if DB_VERSION_MINOR >= 7
		DB_BENCH_ASSERT(
		    dbenv->log_set_config(dbenv, log_flags, 1) == 0);
#else
		DB_BENCH_ASSERT(dbenv->set_flags(dbenv, log_flags, 1) == 0);
#endif
#ifdef DB_LOG_INMEMORY
	if (!(log_flags & DB_LOG_INMEMORY))
#endif
#ifdef DB_LOG_IN_MEMORY
	if (!(log_flags & DB_LOG_IN_MEMORY))
#endif
		DB_BENCH_ASSERT(dbenv->set_lg_max(dbenv, logbufsize * 10) == 0);
	DB_BENCH_ASSERT(dbenv->set_lg_bsize(dbenv, logbufsize) == 0);

	DB_BENCH_ASSERT(dbenv->open(dbenv, "TESTDIR",
	    DB_CREATE | DB_PRIVATE | DB_INIT_LOCK |
	    DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN, 0666) == 0);

	DB_BENCH_ASSERT(db_create(&dbp, dbenv, 0) == 0);
	DB_BENCH_ASSERT(dbp->set_pagesize(dbp, pagesize) == 0);
	DB_BENCH_ASSERT(dbp->open(
	    dbp, NULL, TESTFILE, NULL, DB_BTREE, DB_CREATE, 0666) == 0);

	if (update) {
		(void)dbenv->memp_stat(dbenv, &gsp, NULL, DB_STAT_CLEAR);

		TIMER_START;
		for (; ops > 0; --ops)
			DB_BENCH_ASSERT(
			    dbp->put(dbp, NULL, &key, &data, 0) == 0);
		TIMER_STOP;

		if (dbenv->memp_stat(dbenv, &gsp, NULL, 0) == 0)
			DB_BENCH_ASSERT(gsp->st_page_out == 0);
	} else {
		DB_BENCH_ASSERT(dbp->put(dbp, NULL, &key, &data, 0) == 0);
		(void)dbenv->memp_stat(dbenv, &gsp, NULL, DB_STAT_CLEAR);

		TIMER_START;
		for (; ops > 0; --ops) {
			DB_BENCH_ASSERT(
			    dbenv->txn_begin(dbenv, NULL, &txn, 0) == 0);
			DB_BENCH_ASSERT(
			    dbp->get(dbp, NULL, &key, &data, 0) == 0);
			DB_BENCH_ASSERT(txn->commit(txn, 0) == 0);
		}
		TIMER_STOP;

		if (dbenv->memp_stat(dbenv, &gsp, NULL, 0) == 0)
			DB_BENCH_ASSERT(gsp->st_cache_miss == 0);
	}

	DB_BENCH_ASSERT(dbp->close(dbp, 0) == 0);
	DB_BENCH_ASSERT(dbenv->close(dbenv, 0) == 0);
}
Пример #30
0
/* This populates a cluster with the entire contents of a database */
static icalerrorenum icalbdbset_read_database(icalbdbset *bset, char *(*pfunc) (const DBT *dbt))
{
    DB *dbp;
    DBC *dbcp;
    DBT key, data;
    char *str;
    int ret = EINVAL;
    char keystore[256];
    char datastore[1024];
    char *more_mem = NULL;
    DB_TXN *tid;

    _unused(pfunc);

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

    if (bset->sdbp) {
        dbp = bset->sdbp;
    } else {
        dbp = bset->dbp;
    }

    if (!dbp) {
        return ICAL_FILE_ERROR;
    }

    bset->cluster = icalcomponent_new(ICAL_XROOT_COMPONENT);

    if ((ret = ICAL_DB_ENV->txn_begin(ICAL_DB_ENV, NULL, &tid, 0)) != 0) {
        /*char *foo = db_strerror(ret); */
        abort();
    }

    /* acquire a cursor for the database */
    if ((ret = dbp->cursor(dbp, tid, &dbcp, 0)) != 0) {
        dbp->err(dbp, ret, "primary index");
        goto err1;
    }

    key.flags = DB_DBT_USERMEM;
    key.data = keystore;
    key.ulen = (u_int32_t) sizeof(keystore);

    data.flags = DB_DBT_USERMEM;
    data.data = datastore;
    data.ulen = (u_int32_t) sizeof(datastore);

    /* fetch the key/data pair */
    while (1) {
        ret = dbcp->c_get(dbcp, &key, &data, DB_NEXT);
        if (ret == DB_NOTFOUND) {
            break;
        } else if (ret == ENOMEM) {
            if (more_mem) {
                free(more_mem);
            }
            more_mem = malloc(data.ulen + 1024);
            data.data = more_mem;
            data.ulen = data.ulen + 1024;
        } else if (ret == DB_LOCK_DEADLOCK) {
            /*char *foo = db_strerror(ret); */
            abort();    /* should retry in case of DB_LOCK_DEADLOCK */
        } else if (ret) {
            /*char *foo = db_strerror(ret); */
            /* some other weird-ass error  */
            dbp->err(dbp, ret, "cursor");
            abort();
        } else {
            icalcomponent *cl;

            /* this prevents an array read bounds error */
            if ((str = (char *)calloc(data.size + 1, sizeof(char))) == NULL) {
                goto err2;
            }
            memcpy(str, (char *)data.data, data.size);

            cl = icalparser_parse_string(str);

            icalcomponent_add_component(bset->cluster, cl);
            free(str);
        }
    }
    if (ret != DB_NOTFOUND) {
        goto err2;
    }

    if (more_mem) {
        free(more_mem);
        more_mem = NULL;
    }

    if ((ret = dbcp->c_close(dbcp)) != 0) {
        /*char *foo = db_strerror(ret); */
        abort();        /* should retry in case of DB_LOCK_DEADLOCK */
    }

    if ((ret = tid->commit(tid, 0)) != 0) {
        /*char *foo = db_strerror(ret); */
        abort();
    }

    return ICAL_NO_ERROR;

  err2:
    if (more_mem) {
        free(more_mem);
    }
    dbcp->c_close(dbcp);
    abort();    /* should retry in case of DB_LOCK_DEADLOCK */
    return ICAL_INTERNAL_ERROR;

  err1:
    dbp->err(dbp, ret, "cursor index");
    abort();
    return ICAL_FILE_ERROR;
}