本文整理汇总了C++中DB_ENV::txn_begin方法的典型用法代码示例。如果您正苦于以下问题:C++ DB_ENV::txn_begin方法的具体用法?C++ DB_ENV::txn_begin怎么用?C++ DB_ENV::txn_begin使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类DB_ENV
的用法示例。
在下文中一共展示了DB_ENV::txn_begin方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: main
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;
}
示例2: main
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;
}
示例3: sizeof
AccountingInfo *getAccoutingInfo(int db)
{
DB_ENV *dbenv = radacct_dbenv[db];
DB *dbp = radacct_dbp[db];
DB_TXN *tid = NULL;
DBT key, data;
db_recno_t recno;
AccountingInfo *info = NULL;
char buf[REC_SIZE];
int ret;
memset(&key, 0, sizeof(DBT));
memset(&data, 0, sizeof(DBT));
key.data = &recno;
key.size = key.ulen = sizeof(recno);
key.flags = DB_DBT_USERMEM;
data.data = buf;
data.ulen = sizeof(buf);
data.flags = DB_DBT_USERMEM;
#if USE_TXN
if((ret = dbenv->txn_begin(dbenv, NULL, &tid, 0)) != 0)
{
NETERROR(MRADC, ("getAccoutingInfo: transaction failed: %s\n", db_strerror(ret)));
return 0;
}
switch((ret = dbp->get(dbp, tid, &key, &data, DB_CONSUME)))
#else
switch((ret = dbp->get(dbp, NULL, &key, &data, DB_CONSUME)))
#endif
{
case DB_LOCK_DEADLOCK:
NETERROR(MRADC, ("getAccoutingInfo: deadlock: %s\n", db_strerror(ret)));
break;
case 0:
if((info = (AccountingInfo*)malloc(sizeof(AccountingInfo))))
{
memset(info, 0, sizeof(AccountingInfo));
info->tid = tid;
unMarshalAccountingInfo(buf, info);
}
break;
default:
NETERROR(MRADC, ("getAccoutingInfo: oops: %d\n", ret));
break;
}
return info;
}
示例4: main
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;
}
示例5: srand
/*
* 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++;
//.........这里部分代码省略.........
示例6: if
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;
}
示例7: main
int main(int argc, char **argv) {
DB *dbp;
DB_ENV *dbenv;
DB_TXN *xid;
DBT key, data;
db_recno_t recno;
int num_trials;
int ret;
char c;
double r;
int start, end;
char first_printable_ascii = ' ';
char last_printable_ascii = '~';
int ascii_length = (int)(last_printable_ascii - first_printable_ascii);
char *ASCII = (char *)malloc(sizeof(char) * ascii_length);
char *string;
for (c = 0; c < ascii_length; c++) {
ASCII[(int)c] = first_printable_ascii + c;
}
if (argc != 2) {
printf("usage: %s <num trials>\n", argv[0]);
exit(-1);
}
env_dir_create();
env_open(&dbenv);
if (db_open(dbenv, &dbp, DATABASE, 0))
return (1);
memset(&key, 0, sizeof(DBT));
memset(&data, 0, sizeof(DBT));
num_trials = atoi(argv[1]);
for (recno = 1; (int)recno <= num_trials; recno++) {
start = 0;
end = 0;
while (start == end) {
r = ((double)rand()/(double)((double)RAND_MAX+1)); /* returns [0, 1)*/
r = r*ascii_length;
start = (int)r; /* an int in the rand [0, ascii_length) */
r = ((double)rand()/(double)((double)RAND_MAX+1)); /* re turns [0, 1)*/
r = r*ascii_length;
end = (int)r; /* an int in the rand [0, ascii_length) */
}
if (end < start) {
int swap = start;
start = end;
end = swap;
}
string = (char *)malloc(sizeof(char) * (end - start) + 1);
strncpy(string, ASCII + start, end-start);
string[end-start] = '\0'; /* make the string null terminated */
dbenv->txn_begin(dbenv, NULL, &xid, 0);
key.size = sizeof(recno);
key.data = &recno;
data.size = strlen(string) + 1; // + 1 for the null terminator
data.data = string;
switch (ret = dbp->put(dbp, xid, &key, &data, 0)) {
case 0:
xid->commit(xid, 0);
break;
default:
dbp->err(dbp, ret, "DB->put");
xid->abort(xid);
break;
}
}
return 0;
}
示例8: sqlite3_backup_step
//.........这里部分代码省略.........
p->cleaned = 1;
}
/*
* Begin a transaction, unfortuantely the lock on
* the schema has to be released to allow the sqlite_master
* table to be cleared, which could allow another thread to
* alter it, however accessing the backup database during
* backup is already an illegal condition with undefined
* results.
*/
if (!sqlite3BtreeIsInTrans(p->pDest)) {
if (!p->pDest->connected) {
p->rc = btreeOpenEnvironment(p->pDest, 1);
if (p->rc != SQLITE_OK)
goto err;
}
if ((p->rc = sqlite3BtreeBeginTrans(p->pDest, 2))
!= SQLITE_OK)
goto err;
}
/* Only this process should be accessing the backup environment. */
if (p->pDest->pBt->nRef > 1) {
p->rc = SQLITE_BUSY;
goto err;
}
/*
* Begin a transaction, a lock error or update could have caused
* it to be released in a previous call to step.
*/
if (!p->srcTxn) {
dbenv = p->pSrc->pBt->dbenv;
if ((p->rc = dberr2sqlite(dbenv->txn_begin(dbenv,
p->pSrc->family_txn, &p->srcTxn, 0))) != SQLITE_OK)
goto err;
}
/*
* An update could have dropped or created a table, so recalculate
* the list of tables.
*/
if (!p->tables) {
if ((p->rc = btreeGetPageCount(p->pSrc,
&p->tables, &p->nPagecount, p->srcTxn)) != SQLITE_OK) {
sqlite3Error(p->pSrcDb, p->rc, 0);
goto err;
}
p->nRemaining = p->nPagecount;
}
/* Copy the pages. */
p->rc = btreeCopyPages(p, &pages);
if (p->rc == SQLITE_DONE) {
p->nRemaining = 0;
sqlite3ResetInternalSchema(p->pDestDb, p->iDb);
memset(&parse, 0, sizeof(parse));
parse.db = p->pDestDb;
p->rc = sqlite3ReadSchema(&parse);
if (p->rc == SQLITE_OK)
p->rc = SQLITE_DONE;
} else if (p->rc != SQLITE_OK)
goto err;
/*
* The number of pages left to copy is an estimate, so
示例9: nfs_op_readdir
nfsstat4 nfs_op_readdir(struct nfs_cxn *cxn, const READDIR4args *args,
struct list_head *writes, struct rpc_write **wr)
{
nfsstat4 status = NFS4_OK;
struct nfs_inode *ino = NULL;
uint32_t dircount, maxcount, *status_p;
struct readdir_info ri;
uint64_t cookie, attr_request;
const verifier4 *cookie_verf;
DB_TXN *txn = NULL;
DB *dirent = srv.fsdb.dirent;
DB_ENV *dbenv = srv.fsdb.env;
DBT pkey, pval;
struct fsdb_de_key key;
int cget_flags;
DBC *curs = NULL;
int rc;
uint64_t dirent_inum, db_de;
struct fsdb_de_key *rkey;
cookie = args->cookie;
cookie_verf = &args->cookieverf;
dircount = args->dircount;
maxcount = args->maxcount;
attr_request = bitmap4_decode(&args->attr_request);
status_p = WRSKIP(4);
if (debugging) {
applog(LOG_INFO, "op READDIR (COOKIE:%Lu DIR:%u MAX:%u MAP:%Lx)",
(unsigned long long) cookie,
dircount,
maxcount,
(unsigned long long) attr_request);
print_fattr_bitmap("op READDIR", attr_request);
}
/* traditionally "." and "..", hardcoded */
if (cookie == 1 || cookie == 2) {
status = NFS4ERR_BAD_COOKIE;
goto out;
}
/* don't permit request of write-only attrib */
if (attr_request & fattr_write_only_mask) {
status = NFS4ERR_INVAL;
goto out;
}
/* FIXME: very, very, very poor verifier */
if (cookie &&
memcmp(cookie_verf, &srv.instance_verf, sizeof(verifier4))) {
status = NFS4ERR_NOT_SAME;
goto out;
}
/* read inode of directory being read */
status = dir_curfh(NULL, cxn, &ino, 0);
if (status != NFS4_OK)
goto out;
if (ino->mode == 0) {
status = NFS4ERR_ACCESS;
goto out;
}
/* subtract READDIR4resok header and footer size */
if (maxcount < 16) {
status = NFS4ERR_TOOSMALL;
goto out;
}
maxcount -= (8 + 4 + 4);
/* verify within server limits */
if (dircount > SRV_MAX_READ || maxcount > SRV_MAX_READ) {
status = NFS4ERR_INVAL;
goto out;
}
/* open transaction */
rc = dbenv->txn_begin(dbenv, NULL, &txn, 0);
if (rc) {
status = NFS4ERR_IO;
dbenv->err(dbenv, rc, "DB_ENV->txn_begin");
goto out;
}
/* set up directory iteration */
memset(&ri, 0, sizeof(ri));
ri.cookie = cookie;
ri.dircount = dircount;
ri.maxcount = maxcount;
ri.attr_request = attr_request;
ri.status = NFS4_OK;
ri.writes = writes;
ri.wr = wr;
ri.dir_pos = 3;
ri.first_time = true;
/* if dir is empty, skip directory interation loop completely */
//.........这里部分代码省略.........
示例10: nfs_op_remove
nfsstat4 nfs_op_remove(struct nfs_cxn *cxn, const REMOVE4args *args,
struct list_head *writes, struct rpc_write **wr)
{
nfsstat4 status = NFS4_OK;
struct nfs_inode *dir_ino = NULL, *target_ino = NULL;
struct nfs_buf target;
change_info4 cinfo = { true, 0, 0 };
DB_TXN *txn = NULL;
DB_ENV *dbenv = srv.fsdb.env;
int rc;
nfsino_t de_inum;
target.len = args->target.utf8string_len;
target.val = args->target.utf8string_val;
if (debugging)
applog(LOG_INFO, "op REMOVE ('%.*s')",
target.len,
target.val);
if (target.len > SRV_MAX_NAME) {
status = NFS4ERR_NAMETOOLONG;
goto out;
}
if (!valid_utf8string(&target)) {
status = NFS4ERR_INVAL;
goto out;
}
if (has_dots(&target)) {
status = NFS4ERR_BADNAME;
goto out;
}
rc = dbenv->txn_begin(dbenv, NULL, &txn, 0);
if (rc) {
status = NFS4ERR_IO;
dbenv->err(dbenv, rc, "DB_ENV->txn_begin");
goto out;
}
/* reference container directory */
status = dir_curfh(txn, cxn, &dir_ino, DB_RMW);
if (status != NFS4_OK)
goto out_abort;
/* lookup target name in directory */
status = dir_lookup(txn, dir_ino, &target, 0, &de_inum);
if (status != NFS4_OK)
goto out_abort;
/* reference target inode */
target_ino = inode_getdec(txn, de_inum, DB_RMW);
if (!target_ino) {
status = NFS4ERR_NOENT;
goto out_abort;
}
/* prevent root dir deletion */
if (target_ino->inum == INO_ROOT) {
status = NFS4ERR_INVAL;
goto out_abort;
}
/* prevent removal of non-empty dirs */
if ((target_ino->type == NF4DIR) && !dir_is_empty(txn, target_ino)) {
status = NFS4ERR_NOTEMPTY;
goto out_abort;
}
/* remove target inode from directory */
rc = fsdb_dirent_del(&srv.fsdb, txn, dir_ino->inum, &target, 0);
if (rc) {
status = NFS4ERR_IO;
goto out_abort;
}
/* record directory change info */
cinfo.before = dir_ino->version;
rc = inode_touch(txn, dir_ino);
if (rc) {
status = NFS4ERR_IO;
goto out_abort;
}
cinfo.after = dir_ino->version;
/* remove link, possibly deleting inode */
rc = inode_unlink(txn, target_ino);
if (rc) {
status = NFS4ERR_IO;
goto out_abort;
}
rc = txn->commit(txn, 0);
if (rc) {
dbenv->err(dbenv, rc, "DB_ENV->txn_commit");
status = NFS4ERR_IO;
goto out;
//.........这里部分代码省略.........
示例11: nfs_op_rename
nfsstat4 nfs_op_rename(struct nfs_cxn *cxn, const RENAME4args *args,
struct list_head *writes, struct rpc_write **wr)
{
nfsstat4 status = NFS4_OK;
struct nfs_inode *src_dir = NULL, *target_dir = NULL;
struct nfs_inode *old_file = NULL, *new_file = NULL;
struct nfs_buf oldname, newname;
change_info4 src = { true, 0, 0 };
change_info4 target = { true, 0, 0 };
DB_TXN *txn = NULL;
DB_ENV *dbenv = srv.fsdb.env;
int rc;
nfsino_t old_dirent, new_dirent;
oldname.len = args->oldname.utf8string_len;
oldname.val = args->oldname.utf8string_val;
newname.len = args->newname.utf8string_len;
newname.val = args->newname.utf8string_val;
if (debugging)
applog(LOG_INFO, "op RENAME (OLD:%.*s, NEW:%.*s)",
oldname.len,
oldname.val,
newname.len,
newname.val);
/* validate text input */
if ((!valid_utf8string(&oldname)) ||
(!valid_utf8string(&newname))) {
status = NFS4ERR_INVAL;
goto out;
}
if (has_dots(&oldname) || has_dots(&newname)) {
status = NFS4ERR_BADNAME;
goto out;
}
rc = dbenv->txn_begin(dbenv, NULL, &txn, 0);
if (rc) {
status = NFS4ERR_IO;
dbenv->err(dbenv, rc, "DB_ENV->txn_begin");
goto out;
}
/* reference source, target directories.
* NOTE: src_dir and target_dir may point to the same object
*/
src_dir = inode_fhdec(txn, cxn->save_fh, DB_RMW);
if (fh_equal(cxn->save_fh, cxn->current_fh))
target_dir = src_dir;
else
target_dir = inode_fhdec(txn, cxn->current_fh, DB_RMW);
if (!src_dir || !target_dir) {
status = NFS4ERR_NOFILEHANDLE;
goto out_abort;
}
if ((src_dir->type != NF4DIR) || (target_dir->type != NF4DIR)) {
status = NFS4ERR_NOTDIR;
goto out_abort;
}
/* lookup source, target names */
status = dir_lookup(txn, src_dir, &oldname, 0, &old_dirent);
if (status != NFS4_OK)
goto out_abort;
old_file = inode_getdec(txn, old_dirent, 0);
if (!old_file) {
status = NFS4ERR_NOENT;
goto out_abort;
}
status = dir_lookup(txn, target_dir, &newname, 0, &new_dirent);
if (status != NFS4_OK && status != NFS4ERR_NOENT)
goto out_abort;
/* if target (newname) is present, attempt to remove */
if (status == NFS4_OK) {
bool ok_to_remove = false;
/* read to-be-deleted inode */
new_file = inode_getdec(txn, new_dirent, DB_RMW);
if (!new_file) {
status = NFS4ERR_NOENT;
goto out_abort;
}
/* do oldname and newname refer to same file? */
if (old_file->inum == new_file->inum) {
src.after =
src.before = src_dir->version;
target.after =
target.before = target_dir->version;
goto out_abort;
}
if (old_file->type != NF4DIR && new_file->type != NF4DIR)
ok_to_remove = true;
else if (old_file->type == NF4DIR &&
new_file->type == NF4DIR &&
//.........这里部分代码省略.........
示例12: nfs_op_link
nfsstat4 nfs_op_link(struct nfs_cxn *cxn, const LINK4args *args,
struct list_head *writes, struct rpc_write **wr)
{
nfsstat4 status;
struct nfs_inode *dir_ino = NULL, *src_ino = NULL;
struct nfs_buf newname;
uint64_t before = 0, after = 0;
DB_TXN *txn;
DB_ENV *dbenv = srv.fsdb.env;
int rc;
newname.len = args->newname.utf8string_len;
newname.val = args->newname.utf8string_val;
if (debugging)
applog(LOG_INFO, "op LINK (%.*s)",
newname.len,
newname.val);
/* verify input parameters */
if (!valid_fh(cxn->current_fh) || !valid_fh(cxn->save_fh)) {
status = NFS4ERR_NOFILEHANDLE;
goto out;
}
if (newname.len > SRV_MAX_NAME) {
status = NFS4ERR_NAMETOOLONG;
goto out;
}
/* open transaction */
rc = dbenv->txn_begin(dbenv, NULL, &txn, 0);
if (rc) {
status = NFS4ERR_IO;
dbenv->err(dbenv, rc, "DB_ENV->txn_begin");
goto out;
}
/* read source inode's directory inode */
dir_ino = inode_fhdec(txn, cxn->current_fh, 0);
if (!dir_ino) {
status = NFS4ERR_NOFILEHANDLE;
goto out_abort;
}
/* make sure target is a directory */
if (dir_ino->type != NF4DIR) {
status = NFS4ERR_NOTDIR;
goto out_abort;
}
/* read source inode */
src_ino = inode_fhdec(txn, cxn->save_fh, 0);
if (!src_ino) {
status = NFS4ERR_NOFILEHANDLE;
goto out_abort;
}
/* make sure source is a not a directory */
if (src_ino->type == NF4DIR) {
status = NFS4ERR_ISDIR;
goto out_abort;
}
before = dir_ino->version;
/* add directory entry */
status = dir_add(txn, dir_ino, &newname, src_ino);
if (status != NFS4_OK)
goto out_abort;
after = dir_ino->version;
/* update source inode */
src_ino->n_link++;
if (inode_touch(txn, src_ino)) {
status = NFS4ERR_IO;
goto out_abort;
}
/* close transaction */
rc = txn->commit(txn, 0);
if (rc) {
dbenv->err(dbenv, rc, "DB_ENV->txn_commit");
status = NFS4ERR_IO;
goto out;
}
out:
WR32(status);
if (status == NFS4_OK) {
WR32(1); /* cinfo.atomic */
WR64(before); /* cinfo.before */
WR64(after); /* cinfo.after */
}
inode_free(src_ino);
inode_free(dir_ino);
return status;
out_abort:
if (txn->abort(txn))
//.........这里部分代码省略.........
示例13: nfs_op_lookup
nfsstat4 nfs_op_lookup(struct nfs_cxn *cxn, const LOOKUP4args *args,
struct list_head *writes, struct rpc_write **wr)
{
nfsstat4 status = NFS4_OK;
struct nfs_inode *ino = NULL;
bool printed = false;
struct nfs_buf objname;
nfsino_t inum;
DB_TXN *txn = NULL;
DB_ENV *dbenv = srv.fsdb.env;
int rc;
objname.len = args->objname.utf8string_len;
objname.val = args->objname.utf8string_val;
if (!objname.len) {
status = NFS4ERR_INVAL;
goto out;
}
if (!objname.val) {
status = NFS4ERR_BADXDR;
goto out;
}
if (objname.len > SRV_MAX_NAME) {
status = NFS4ERR_NAMETOOLONG;
goto out;
}
rc = dbenv->txn_begin(dbenv, NULL, &txn, 0);
if (rc) {
status = NFS4ERR_IO;
dbenv->err(dbenv, rc, "DB_ENV->txn_begin");
goto out;
}
status = dir_curfh(txn, cxn, &ino, 0);
if (status != NFS4_OK) {
if ((status == NFS4ERR_NOTDIR) &&
(ino->type == NF4LNK))
status = NFS4ERR_SYMLINK;
goto out_abort;
}
status = dir_lookup(txn, ino, &objname, 0, &inum);
if (status != NFS4_OK)
goto out_abort;
rc = txn->commit(txn, 0);
if (rc) {
dbenv->err(dbenv, rc, "DB_ENV->txn_commit");
status = NFS4ERR_IO;
goto out;
}
fh_set(&cxn->current_fh, inum);
if (debugging) {
applog(LOG_INFO, "op LOOKUP ('%.*s') -> %016llX",
objname.len,
objname.val,
(unsigned long long) cxn->current_fh.inum);
printed = true;
}
out:
if (!printed) {
if (debugging)
applog(LOG_INFO, "op LOOKUP ('%.*s')",
objname.len,
objname.val);
}
WR32(status);
inode_free(ino);
return status;
out_abort:
if (txn->abort(txn))
dbenv->err(dbenv, rc, "DB_ENV->txn_abort");
goto out;
}
示例14: memset
/* 批量插入示例函数。*/
void *
run_bulk_delete()
{
int raw_key[NUM_KEY_INT];
DBT key;
DB_ENV *envp;
int bulk_size = 100;
DB *dbp;
DB_TXN *tid;
int *delete_load;
int delete_count, i, ret, op_flag;
char *key_buf;
void *p;
int j;
/* Initialize structs and arrays */
memset(raw_key, 0, KEY_SIZE);
memset(&key, 0, sizeof(DBT));
tid = NULL;
/*
* 初始化批量删除使用的key buffer。由于批量删除不需要data,
* 所以只需要初始化和填充key buffer。我们同样需要使用自己分配的内存。
*/
key_buf = (char*) malloc(KEY_SIZE * bulk_size * 2);
memset(key_buf, 0, KEY_SIZE * bulk_size * 2);
/* 初始化key buffer DBT 对象,设置正确的flags和ulen成员。 */
key.data = key_buf;
key.ulen = KEY_SIZE * bulk_size * 2;
key.flags = DB_DBT_USERMEM;
op_flag = DB_MULTIPLE; /* 批量删除同样需要这个flag。*/
/*
* 批量删除所有的数据。每一批删除由key buffer DBT 当中的key
* 指定的bulk_size条key/data pair. 这两个宏的详细用法见上文。
*/
for (i = 0; i < delete_count / bulk_size; ) {
/* 为批量删除初始化并填充一个key buffer DBT 对象。 */
DB_MULTIPLE_WRITE_INIT(p, &key);
for (j = i * bulk_size; j < (i + 1) * bulk_size; j++) {
raw_key[0] = delete_load[j];
DB_MULTIPLE_WRITE_NEXT(p, &key, raw_key, KEY_SIZE);
}
/* 启动事务。*/
if ((ret = envp->txn_begin(envp, NULL, &tid, 0)) != 0) {
envp->err(envp, ret, "[delete] DB_ENV->txn_begin");
exit(EXIT_FAILURE);
}
/*
* 执行批量删除。key buffer DBT
* 当中的bulk_size条key指定的key/data pairs会被从数据库当中删除。
*/
switch(ret = dbp->del(dbp, tid, &key, op_flag)) {
case 0: /* 批量删除操作成功,提交事务。*/
if ((ret = tid->commit(tid, 0)) != 0) {
envp->err(envp, ret, "[delete] DB_TXN->commit");
exit(EXIT_FAILURE);
}
break;
case DB_LOCK_DEADLOCK:
/* 如果数据库操作发生死锁,那么必须abort事务。然后,可以选择重新执行该操作。*/
if ((ret = tid->abort(tid)) != 0) {
envp->err(envp, ret, "[delete] DB_TXN->abort");
exit(EXIT_FAILURE);
}
continue;
default:
envp->err(envp, ret, "[delete] DB->del ([%d]%d)", i, delete_load[i]);
exit(EXIT_FAILURE);
}
i++;
}
(void)free(key_buf);
return (NULL);
}
示例15: bdb_thread
/************************* Transactional Berkeley DB *************************/
gpointer bdb_thread(gpointer d)
{
int res;
DB_ENV *env;
DB *db;
DB_TXN *txn = NULL;
int count = 0;
res = db_env_create(&env, 0);
g_assert(res == 0);
res = env->open(env, ".",
DB_CREATE | DB_RECOVER | DB_INIT_LOCK | DB_INIT_LOG
| DB_INIT_MPOOL | DB_INIT_TXN | DB_THREAD, 0644);
g_assert(res == 0);
if (opt_bdb_async) {
res = env->set_flags(env, DB_TXN_WRITE_NOSYNC, 1);
g_assert(res == 0);
}
res = db_create(&db, env, 0);
g_assert(res == 0);
res = db->open(db, NULL, "log.db", "log", DB_BTREE,
DB_CREATE | DB_THREAD | DB_AUTO_COMMIT, 0644);
g_assert(res == 0);
while (TRUE) {
if (txn == NULL && !opt_bdb_async) {
res = env->txn_begin(env, NULL, &txn, 0);
g_assert(res == 0);
}
struct item *item = get_item();
DBT key, value;
memset(&key, 0, sizeof(key));
memset(&value, 0, sizeof(value));
key.data = item->key;
key.size = strlen(item->key);
value.data = item->data;
value.size = item->len;
res = db->put(db, opt_bdb_async ? NULL : txn, &key, &value, 0);
g_assert(res == 0);
count++;
if (count % opt_batchsize == 0) {
if (opt_bdb_async) {
env->txn_checkpoint(env, 0, 0, 0);
} else {
txn->commit(txn, 0);
txn = NULL;
}
}
finish_item(item);
}
return NULL;
}