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; }
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; } }
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; }
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; }
/* 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; }
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); }
/* * 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); } } }
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; }
/* * 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); }
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; }
/* 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; }
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); } } }
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; }
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); } }
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; }
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; }
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; }
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; }
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); } }
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); } }
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); } } }
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); }
/* * 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); }
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; }
/* 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; }
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; }
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; }
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; }
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); }
/* 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; }