diff options
Diffstat (limited to 'db2/xa')
-rw-r--r-- | db2/xa/xa.c | 682 | ||||
-rw-r--r-- | db2/xa/xa_db.c | 308 | ||||
-rw-r--r-- | db2/xa/xa_map.c | 305 |
3 files changed, 0 insertions, 1295 deletions
diff --git a/db2/xa/xa.c b/db2/xa/xa.c deleted file mode 100644 index 94a96e7e09..0000000000 --- a/db2/xa/xa.c +++ /dev/null @@ -1,682 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1998 - * Sleepycat Software. All rights reserved. - */ - -/* XXX Remove the global transaction and hang it off the environment. */ -#include "config.h" - -#ifndef lint -static const char sccsid[] = "@(#)xa.c 10.4 (Sleepycat) 10/11/98"; -#endif /* not lint */ - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#endif - -#include "db_int.h" -#include "db_page.h" -#include "shqueue.h" -#include "log.h" -#include "txn.h" -#include "db_auto.h" -#include "db_ext.h" -#include "db_dispatch.h" - -static int __db_xa_close __P((char *, int, long)); -static int __db_xa_commit __P((XID *, int, long)); -static int __db_xa_complete __P((int *, int *, int, long)); -static int __db_xa_end __P((XID *, int, long)); -static int __db_xa_forget __P((XID *, int, long)); -static int __db_xa_open __P((char *, int, long)); -static int __db_xa_prepare __P((XID *, int, long)); -static int __db_xa_recover __P((XID *, long, int, long)); -static int __db_xa_rollback __P((XID *, int, long)); -static int __db_xa_start __P((XID *, int, long)); -static void __xa_txn_end __P((DB_ENV *)); -static void __xa_txn_init __P((DB_ENV *, TXN_DETAIL *, size_t)); - -/* - * Possible flag values: - * Dynamic registration 0 => no dynamic registration - * TMREGISTER => dynamic registration - * Asynchronous operation 0 => no support for asynchrony - * TMUSEASYNC => async support - * Migration support 0 => migration of transactions across - * threads is possible - * TMNOMIGRATE => no migration across threads - */ -const struct xa_switch_t db_xa_switch = { - "Berkeley DB", /* name[RMNAMESZ] */ - TMNOMIGRATE, /* flags */ - 0, /* version */ - __db_xa_open, /* xa_open_entry */ - __db_xa_close, /* xa_close_entry */ - __db_xa_start, /* xa_start_entry */ - __db_xa_end, /* xa_end_entry */ - __db_xa_rollback, /* xa_rollback_entry */ - __db_xa_prepare, /* xa_prepare_entry */ - __db_xa_commit, /* xa_commit_entry */ - __db_xa_recover, /* xa_recover_entry */ - __db_xa_forget, /* xa_forget_entry */ - __db_xa_complete /* xa_complete_entry */ -}; - -/* - * __db_xa_open -- - * The open call in the XA protocol. The rmid field is an id number - * that the TM assigned us and will pass us on every xa call. We need to - * map that rmid number into a dbenv structure that we create during - * initialization. Since this id number is thread specific, we do not - * need to store it in shared memory. The file xa_map.c implements all - * such xa->db mappings. - * The xa_info field is instance specific information. We require - * that the value of DB_HOME be passed in xa_info. Since xa_info is the - * only thing that we get to pass to db_appinit, any config information - * will have to be done via a config file instead of via the db_appinit - * call. - */ -static int -__db_xa_open(xa_info, rmid, flags) - char *xa_info; - int rmid; - long flags; -{ - DB_ENV *env; - - if (LF_ISSET(TMASYNC)) - return (XAER_ASYNC); - if (flags != TMNOFLAGS) - return (XAER_INVAL); - - /* Verify if we already have this environment open. */ - if (__db_rmid_to_env(rmid, &env, 0) == 0) - return (XA_OK); - - /* - * Since we cannot tell whether the environment is OK or not, - * we can't actually do the db_appinit in xa_open. Instead, - * we save the mapping between the rmid and the xa_info. If - * we next get a call to __xa_recover, we do the db_appinit - * with DB_RECOVER set. If we get any other call, then we - * do the db_appinit. - */ - return (__db_map_rmid_name(rmid, xa_info)); -} - -/* - * __db_xa_close -- - * The close call of the XA protocol. The only trickiness here - * is that if there are any active transactions, we must fail. It is - * *not* an error to call close on an environment that has already been - * closed (I am interpreting that to mean it's OK to call close on an - * environment that has never been opened). - */ -static int -__db_xa_close(xa_info, rmid, flags) - char *xa_info; - int rmid; - long flags; -{ - DB_ENV *env; - int ret, t_ret; - - COMPQUIET(xa_info, NULL); - - if (LF_ISSET(TMASYNC)) - return (XAER_ASYNC); - if (flags != TMNOFLAGS) - return (XAER_INVAL); - - /* If the environment is closed, then we're done. */ - if (__db_rmid_to_env(rmid, &env, 0) != 0) - return (XA_OK); - - /* Check if there are any pending transactions. */ - if (env->xa_txn != NULL && env->xa_txn->txnid != TXN_INVALID) - return (XAER_PROTO); - - /* Now, destroy the mapping and close the environment. */ - ret = __db_unmap_rmid(rmid); - if ((t_ret = db_appexit(env)) != 0 && ret == 0) - ret = t_ret; - - __os_free(env, sizeof(DB_ENV)); - - return (ret == 0 ? XA_OK : XAER_RMERR); -} - -/* - * __db_xa_start -- - * Begin a transaction for the current resource manager. - */ -static int -__db_xa_start(xid, rmid, flags) - XID *xid; - int rmid; - long flags; -{ - DB_ENV *env; - TXN_DETAIL *td; - size_t off; - int is_known; - -#define OK_FLAGS (TMJOIN | TMRESUME | TMNOWAIT | TMASYNC | TMNOFLAGS) - if (LF_ISSET(~OK_FLAGS)) - return (XAER_INVAL); - - if (LF_ISSET(TMJOIN) && LF_ISSET(TMRESUME)) - return (XAER_INVAL); - - if (LF_ISSET(TMASYNC)) - return (XAER_ASYNC); - - if (__db_rmid_to_env(rmid, &env, 1) != 0) - return (XAER_PROTO); - - is_known = __db_xid_to_txn(env, xid, &off) == 0; - - if (is_known && !LF_ISSET(TMRESUME) && !LF_ISSET(TMJOIN)) - return (XAER_DUPID); - - if (!is_known && LF_ISSET(TMRESUME | TMJOIN)) - return (XAER_NOTA); - - /* - * This can't block, so we can ignore TMNOWAIT. - * - * Other error conditions: RMERR, RMFAIL, OUTSIDE, PROTO, RB* - */ - if (is_known) { - td = (TXN_DETAIL *)((u_int8_t *)env->tx_info->region + off); - if (td->xa_status == TXN_XA_SUSPENDED && !LF_SET(TMRESUME)) - return (XAER_PROTO); - if (td->xa_status == TXN_XA_DEADLOCKED) - return (XA_RBDEADLOCK); - if (td->xa_status == TXN_XA_ABORTED) - return (XA_RBOTHER); - - /* Now, fill in the global transaction structure. */ - __xa_txn_init(env, td, off); - td->xa_status = TXN_XA_STARTED; - } else { - if (__txn_xa_begin(env, env->xa_txn) != 0) - return (XAER_RMERR); - (void)__db_map_xid(env, xid, env->xa_txn->off); - td = (TXN_DETAIL *) - ((u_int8_t *)env->tx_info->region + env->xa_txn->off); - td->xa_status = TXN_XA_STARTED; - } - return (XA_OK); -} - -/* - * __db_xa_end -- - * Disassociate the current transaction from the current process. - */ -static int -__db_xa_end(xid, rmid, flags) - XID *xid; - int rmid; - long flags; -{ - DB_ENV *env; - DB_TXN *txn; - TXN_DETAIL *td; - size_t off; - - if (flags != TMNOFLAGS && !LF_ISSET(TMSUSPEND | TMSUCCESS | TMFAIL)) - return (XAER_INVAL); - - if (__db_rmid_to_env(rmid, &env, 0) != 0) - return (XAER_PROTO); - - if (__db_xid_to_txn(env, xid, &off) != 0) - return (XAER_NOTA); - - txn = env->xa_txn; - if (off != txn->off) - return (XAER_PROTO); - - td = (TXN_DETAIL *)((u_int8_t *)env->tx_info->region + off); - if (td->xa_status == TXN_XA_DEADLOCKED) - return (XA_RBDEADLOCK); - - if (td->status == TXN_ABORTED) - return (XA_RBOTHER); - - if (td->xa_status != TXN_XA_STARTED) - return (XAER_PROTO); - - /* Update the shared memory last_lsn field */ - td->last_lsn = txn->last_lsn; - - /* - * If we ever support XA migration, we cannot keep SUSPEND/END - * status in the shared region; it would have to be process local. - */ - if (LF_ISSET(TMSUSPEND)) - td->xa_status = TXN_XA_SUSPENDED; - else - td->xa_status = TXN_XA_ENDED; - - txn->txnid = TXN_INVALID; - return (XA_OK); -} - -/* - * __db_xa_prepare -- - * Sync the log to disk so we can guarantee recoverability. - */ -static int -__db_xa_prepare(xid, rmid, flags) - XID *xid; - int rmid; - long flags; -{ - DB_ENV *env; - TXN_DETAIL *td; - size_t off; - - if (LF_ISSET(TMASYNC)) - return (XAER_ASYNC); - if (flags != TMNOFLAGS) - return (XAER_INVAL); - - /* - * We need to know if we've ever called prepare on this. - * As part of the prepare, we set the xa_status field to - * reflect that fact that prepare has been called, and if - * it's ever called again, it's an error. - */ - if (__db_rmid_to_env(rmid, &env, 1) != 0) - return (XAER_PROTO); - - if (__db_xid_to_txn(env, xid, &off) != 0) - return (XAER_NOTA); - - td = (TXN_DETAIL *)((u_int8_t *)env->tx_info->region + off); - - if (td->xa_status == TXN_XA_DEADLOCKED) - return (XA_RBDEADLOCK); - - if (td->xa_status != TXN_XA_ENDED && td->xa_status != TXN_XA_SUSPENDED) - return (XAER_PROTO); - - /* Now, fill in the global transaction structure. */ - __xa_txn_init(env, td, off); - - if (txn_prepare(env->xa_txn) != 0) - return (XAER_RMERR); - - td->xa_status = TXN_XA_PREPARED; - - /* No fatal value that would require an XAER_RMFAIL. */ - __xa_txn_end(env); - return (XA_OK); -} - -/* - * __db_xa_commit -- - * Commit the transaction - */ -static int -__db_xa_commit(xid, rmid, flags) - XID *xid; - int rmid; - long flags; -{ - DB_ENV *env; - TXN_DETAIL *td; - size_t off; - - if (LF_ISSET(TMASYNC)) - return (XAER_ASYNC); -#undef OK_FLAGS -#define OK_FLAGS (TMNOFLAGS | TMNOWAIT | TMONEPHASE) - if (LF_ISSET(~OK_FLAGS)) - return (XAER_INVAL); - - /* - * We need to know if we've ever called prepare on this. - * We can verify this by examining the xa_status field. - */ - if (__db_rmid_to_env(rmid, &env, 1) != 0) - return (XAER_PROTO); - - if (__db_xid_to_txn(env, xid, &off) != 0) - return (XAER_NOTA); - - td = (TXN_DETAIL *)((u_int8_t *)env->tx_info->region + off); - - if (td->xa_status == TXN_XA_DEADLOCKED) - return (XA_RBDEADLOCK); - - if (td->xa_status == TXN_XA_ABORTED) - return (XA_RBOTHER); - - if (LF_SET(TMONEPHASE) && - td->xa_status != TXN_XA_ENDED && td->xa_status != TXN_XA_SUSPENDED) - return (XAER_PROTO); - - if (!LF_SET(TMONEPHASE) && td->xa_status != TXN_XA_PREPARED) - return (XAER_PROTO); - - /* Now, fill in the global transaction structure. */ - __xa_txn_init(env, td, off); - - if (txn_commit(env->xa_txn) != 0) - return (XAER_RMERR); - - /* No fatal value that would require an XAER_RMFAIL. */ - __xa_txn_end(env); - return (XA_OK); -} - -/* - * __db_xa_recover -- - * Returns a list of prepared and heuristically completed transactions. - * - * The return value is the number of xids placed into the xid array (less - * than or equal to the count parameter). The flags are going to indicate - * whether we are starting a scan or continuing one. - */ -static int -__db_xa_recover(xids, count, rmid, flags) - XID *xids; - long count, flags; - int rmid; -{ - __txn_xa_regop_args *argp; - DBT data; - DB_ENV *env; - DB_LOG *log; - XID *xidp; - char *dbhome; - int err, ret; - u_int32_t rectype, txnid; - - ret = 0; - xidp = xids; - - - /* - * If we are starting a scan, then we need to open the environment - * and run recovery. This recovery puts us in a state where we can - * either commit or abort any transactions that were prepared but not - * yet committed. Once we've done that, we need to figure out where - * to begin checking for such transactions. If we are not starting - * a scan, then the environment had better have already been recovered - * and we'll start from * wherever the log cursor is. Since XA apps - * cannot be threaded, we don't have to worry about someone else - * having moved it. - */ - if (LF_ISSET(TMSTARTRSCAN)) { - /* If the environment is open, we have a problem. */ - if (__db_rmid_to_env(rmid, &env, 0) == XA_OK) - return (XAER_PROTO); - - if ((ret = __os_calloc(1, sizeof(DB_ENV), &env)) != 0) - return (XAER_RMERR); - - if (__db_rmid_to_name(rmid, &dbhome) != 0) - goto err1; - -#undef XA_FLAGS -#define XA_FLAGS DB_RECOVER | \ - DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN - if ((ret = db_appinit(dbhome, NULL, env, XA_FLAGS)) != 0) - goto err1; - - if (__db_map_rmid(rmid, env) != 0) - goto err2; - - /* Now figure out from where to begin scan. */ - log = env->lg_info; - if ((err = __log_findckp(log, &log->xa_first)) == DB_NOTFOUND) { - /* - * If there were no log files, then we have no - * transactions to return, so we simply return 0. - */ - return (0); - } - if ((err = __db_txnlist_init(&log->xa_info)) != 0) - goto err3; - } else { - /* We had better already know about this rmid. */ - if (__db_rmid_to_env(rmid, &env, 0) != 0) - return (XAER_PROTO); - /* - * If we are not starting a scan, the log cursor had - * better be set. - */ - log = env->lg_info; - if (IS_ZERO_LSN(log->xa_lsn)) - return (XAER_PROTO); - } - - /* - * At this point log->xa_first contains the point in the log - * to which we need to roll back. If we are starting a scan, - * we'll start at the last record; if we're continuing a scan, - * we'll have to start at log->xa_lsn. - */ - - memset(&data, 0, sizeof(data)); - for (err = log_get(log, &log->xa_lsn, &data, - LF_ISSET(TMSTARTRSCAN) ? DB_LAST : DB_SET); - err == 0 && log_compare(&log->xa_lsn, &log->xa_first) > 0; - err = log_get(log, &log->xa_lsn, &data, DB_PREV)) { - memcpy(&rectype, data.data, sizeof(rectype)); - - /* - * The only record type we care about is an DB_txn_xa_regop. - * If it's a commit, we have to add it to a txnlist. If it's - * a prepare, and we don't have a commit, then we return it. - * We are redoing some of what's in the xa_regop_recovery - * code, but we have to do it here so we can get at the xid - * in the record. - */ - if (rectype != DB_txn_xa_regop && rectype != DB_txn_regop) - continue; - - memcpy(&txnid, (u_int8_t *)data.data + sizeof(rectype), - sizeof(txnid)); - err = __db_txnlist_find(log->xa_info, txnid); - switch (rectype) { - case DB_txn_regop: - if (err == DB_NOTFOUND) - __db_txnlist_add(log->xa_info, txnid); - err = 0; - break; - case DB_txn_xa_regop: - /* - * This transaction is commited, so we needn't read - * the record and do anything. - */ - if (err == 0) - break; - if ((err = - __txn_xa_regop_read(data.data, &argp)) != 0) { - ret = XAER_RMERR; - goto out; - } - - xidp->formatID = argp->formatID; - xidp->gtrid_length = argp->gtrid; - xidp->bqual_length = argp->bqual; - memcpy(xidp->data, argp->xid.data, argp->xid.size); - ret++; - xidp++; - __os_free(argp, sizeof(*argp)); - if (ret == count) - goto done; - break; - } - } - - if (err != 0 && err != DB_NOTFOUND) - goto out; - -done: if (LF_ISSET(TMENDRSCAN)) { - ZERO_LSN(log->xa_lsn); - ZERO_LSN(log->xa_first); - -out: __db_txnlist_end(log->xa_info); - log->xa_info = NULL; - } - return (ret); - -err3: (void)__db_unmap_rmid(rmid); -err2: (void)db_appexit(env); -err1: __os_free(env, sizeof(DB_ENV)); - return (XAER_RMERR); -} - -/* - * __db_xa_rollback - * Abort an XA transaction. - */ -static int -__db_xa_rollback(xid, rmid, flags) - XID *xid; - int rmid; - long flags; -{ - DB_ENV *env; - TXN_DETAIL *td; - size_t off; - - if (LF_ISSET(TMASYNC)) - return (XAER_ASYNC); - if (flags != TMNOFLAGS) - return (XAER_INVAL); - - if (__db_rmid_to_env(rmid, &env, 1) != 0) - return (XAER_PROTO); - - if (__db_xid_to_txn(env, xid, &off) != 0) - return (XAER_NOTA); - - td = (TXN_DETAIL *)((u_int8_t *)env->tx_info->region + off); - - if (td->xa_status == TXN_XA_DEADLOCKED) - return (XA_RBDEADLOCK); - - if (td->xa_status == TXN_XA_ABORTED) - return (XA_RBOTHER); - - if (LF_SET(TMONEPHASE) && - td->xa_status != TXN_XA_ENDED && td->xa_status != TXN_XA_SUSPENDED) - return (XAER_PROTO); - - if (!LF_SET(TMONEPHASE) && td->xa_status != TXN_XA_PREPARED) - return (XAER_PROTO); - - /* Now, fill in the global transaction structure. */ - __xa_txn_init(env, td, off); - if (txn_abort(env->xa_txn) != 0) - return (XAER_RMERR); - - /* No fatal value that would require an XAER_RMFAIL. */ - __xa_txn_end(env); - return (XA_OK); -} - -/* - * __db_xa_forget -- - * Forget about an XID for a transaction that was heuristically - * completed. Since we do not heuristically complete anything, I - * don't think we have to do anything here, but we should make sure - * that we reclaim the slots in the txnid table. - */ -static int -__db_xa_forget(xid, rmid, flags) - XID *xid; - int rmid; - long flags; -{ - DB_ENV *env; - size_t off; - - if (LF_ISSET(TMASYNC)) - return (XAER_ASYNC); - if (flags != TMNOFLAGS) - return (XAER_INVAL); - - if (__db_rmid_to_env(rmid, &env, 1) != 0) - return (XAER_PROTO); - - /* - * If mapping is gone, then we're done. - */ - if (__db_xid_to_txn(env, xid, &off) != 0) - return (XA_OK); - - __db_unmap_xid(env, xid, off); - - /* No fatal value that would require an XAER_RMFAIL. */ - return (XA_OK); -} - -/* - * __db_xa_complete -- - * Used to wait for asynchronous operations to complete. Since we're - * not doing asynch, this is an invalid operation. - */ -static int -__db_xa_complete(handle, retval, rmid, flags) - int *handle, *retval, rmid; - long flags; -{ - COMPQUIET(handle, NULL); - COMPQUIET(retval, NULL); - COMPQUIET(rmid, 0); - COMPQUIET(flags, 0); - - return (XAER_INVAL); -} - -/* - * __xa_txn_init -- - * Fill in the fields of the local transaction structure given - * the detail transaction structure. - */ -static void -__xa_txn_init(env, td, off) - DB_ENV *env; - TXN_DETAIL *td; - size_t off; -{ - DB_TXN *txn; - - txn = env->xa_txn; - txn->mgrp = env->tx_info; - txn->parent = NULL; - txn->last_lsn = td->last_lsn; - txn->txnid = td->txnid; - txn->off = off; - txn->flags = 0; -} - -/* - * __xa_txn_end -- - * Invalidate a transaction structure that was generated by xa_txn_init. - */ -static void -__xa_txn_end(env) - DB_ENV *env; -{ - DB_TXN *txn; - - txn = env->xa_txn; - if (txn != NULL) - txn->txnid = TXN_INVALID; -} - diff --git a/db2/xa/xa_db.c b/db2/xa/xa_db.c deleted file mode 100644 index 4aaaeff108..0000000000 --- a/db2/xa/xa_db.c +++ /dev/null @@ -1,308 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1998 - * Sleepycat Software. All rights reserved. - */ - -#include "config.h" - -#ifndef lint -static const char sccsid[] = "@(#)xa_db.c 10.6 (Sleepycat) 12/19/98"; -#endif /* not lint */ - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <errno.h> -#include <stdio.h> -#include <string.h> -#endif - -#undef stat - -#include "db_int.h" -#include "db_page.h" -#include "xa.h" -#include "xa_ext.h" -#include "db_am.h" -#include "db_ext.h" -#include "common_ext.h" - -static int __xa_c_close __P((DBC *)); -static int __xa_c_del __P((DBC *, u_int32_t)); -static int __xa_c_get __P((DBC *, DBT *, DBT *, u_int32_t)); -static int __xa_c_put __P((DBC *, DBT *, DBT *, u_int32_t)); -static int __xa_close __P((DB *, u_int32_t)); -static int __xa_cursor __P((DB *, DB_TXN *, DBC **, u_int32_t)); -static int __xa_del __P((DB *, DB_TXN *, DBT *, u_int32_t)); -static int __xa_fd __P((DB *, int *)); -static int __xa_get __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t)); -static int __xa_put __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t)); -static int __xa_stat __P((DB *, void *, void *(*)(size_t), u_int32_t)); -static int __xa_sync __P((DB *, u_int32_t)); - -int -db_xa_open(fname, type, flags, mode, dbinfo, dbpp) - const char *fname; - DBTYPE type; - u_int32_t flags; - int mode; - DB_INFO *dbinfo; - DB **dbpp; -{ - DB *dbp, *real_dbp; - DB_ENV *dbenv; - struct __rmname *rp; - int ret; - - /* - * First try to open up the underlying DB. - * - * !!! - * The dbenv argument is taken from the global list of environments. - * When the transaction manager called xa_start() (__db_xa_start()), - * the "current" DB environment was moved to the start of the list. - * However, if we were called in a tpsvrinit function (which is - * entirely plausible), then it's possible that xa_open was called - * (which simply recorded the name of the environment to open) and - * this is the next call into DB. In that case, we still have to - * open the environment. - * - * The way that we know that xa_open and nothing else was called - * is because the nameq is not NULL. - */ - if ((rp = TAILQ_FIRST(&DB_GLOBAL(db_nameq))) != NULL && - (ret = __db_rmid_to_env(rp->rmid, &dbenv, 1)) != 0) - return (ret); - - dbenv = TAILQ_FIRST(&DB_GLOBAL(db_envq)); - if ((ret = db_open(fname, - type, flags, mode, dbenv, dbinfo, &real_dbp)) != 0) - return (ret); - - /* - * Allocate our own DB handle, and copy the exported fields and - * function pointers into it. The internal pointer references - * the real underlying DB handle. - */ - if ((ret = __os_calloc(1, sizeof(DB), &dbp)) != 0) { - (void)real_dbp->close(real_dbp, 0); - return (ret); - } - dbp->type = real_dbp->type; - dbp->byteswapped = real_dbp->byteswapped; - dbp->dbenv = dbenv; - dbp->internal = real_dbp; - TAILQ_INIT(&dbp->active_queue); - TAILQ_INIT(&dbp->free_queue); - dbp->close = __xa_close; - dbp->cursor = __xa_cursor; - dbp->del = __xa_del; - dbp->fd = __xa_fd; - dbp->get = __xa_get; - dbp->join = real_dbp->join; - dbp->put = __xa_put; - dbp->stat = __xa_stat; - dbp->sync = __xa_sync; - - *dbpp = dbp; - return (0); -} - -static int -__xa_close(dbp, flags) - DB *dbp; - u_int32_t flags; -{ - DB *real_dbp; - DBC *dbc; - int ret; - - /* Close any associated cursors. */ - while ((dbc = TAILQ_FIRST(&dbp->active_queue)) != NULL) - (void)dbc->c_close(dbc); - - /* Close the DB handle. */ - real_dbp = (DB *)dbp->internal; - ret = real_dbp->close(real_dbp, flags); - - __os_free(dbp, sizeof(DB)); - return (ret); -} - -static int -__xa_cursor(dbp, txn, dbcp, flags) - DB *dbp; - DB_TXN *txn; - DBC **dbcp; - u_int32_t flags; -{ - DB *real_dbp; - DBC *real_dbc, *dbc; - int ret; - - real_dbp = (DB *)dbp->internal; - txn = dbp->dbenv->xa_txn; - - if ((ret = real_dbp->cursor(real_dbp, txn, &real_dbc, flags)) != 0) - return (ret); - - /* - * Allocate our own DBC handle, and copy the exported fields and - * function pointers into it. The internal pointer references - * the real underlying DBC handle. - */ - if ((ret = __os_calloc(1, sizeof(DBC), &dbc)) != 0) { - (void)real_dbc->c_close(real_dbc); - return (ret); - } - dbc->dbp = dbp; - dbc->c_close = __xa_c_close; - dbc->c_del = __xa_c_del; - dbc->c_get = __xa_c_get; - dbc->c_put = __xa_c_put; - dbc->internal = real_dbc; - TAILQ_INSERT_TAIL(&dbp->active_queue, dbc, links); - - *dbcp = dbc; - return (0); -} - -static int -__xa_fd(dbp, fdp) - DB *dbp; - int *fdp; -{ - DB *real_dbp; - - COMPQUIET(fdp, NULL); - - real_dbp = (DB *)dbp->internal; - return (__db_eopnotsup(real_dbp->dbenv)); -} - -static int -__xa_del(dbp, txn, key, flags) - DB *dbp; - DB_TXN *txn; - DBT *key; - u_int32_t flags; -{ - DB *real_dbp; - - real_dbp = (DB *)dbp->internal; - txn = dbp->dbenv->xa_txn; - - return (real_dbp->del(real_dbp, txn, key, flags)); -} - -static int -__xa_get(dbp, txn, key, data, flags) - DB *dbp; - DB_TXN *txn; - DBT *key; - DBT *data; - u_int32_t flags; -{ - DB *real_dbp; - - real_dbp = (DB *)dbp->internal; - txn = dbp->dbenv->xa_txn; - - return (real_dbp->get(real_dbp, txn, key, data, flags)); -} - -static int -__xa_put(dbp, txn, key, data, flags) - DB *dbp; - DB_TXN *txn; - DBT *key; - DBT *data; - u_int32_t flags; -{ - DB *real_dbp; - - real_dbp = (DB *)dbp->internal; - txn = dbp->dbenv->xa_txn; - - return (real_dbp->put(real_dbp, txn, key, data, flags)); -} - -static int -__xa_stat(dbp, spp, db_malloc, flags) - DB *dbp; - void *spp; - void *(*db_malloc) __P((size_t)); - u_int32_t flags; -{ - DB *real_dbp; - - real_dbp = (DB *)dbp->internal; - return (real_dbp->stat(real_dbp, spp, db_malloc, flags)); -} - -static int -__xa_sync(dbp, flags) - DB *dbp; - u_int32_t flags; -{ - DB *real_dbp; - - real_dbp = (DB *)dbp->internal; - return (real_dbp->sync(real_dbp, flags)); -} - -static int -__xa_c_close(dbc) - DBC *dbc; -{ - DBC *real_dbc; - int ret; - - real_dbc = (DBC *)dbc->internal; - - ret = real_dbc->c_close(real_dbc); - - TAILQ_REMOVE(&dbc->dbp->active_queue, dbc, links); - __os_free(dbc, sizeof(DBC)); - - return (ret); -} - -static int -__xa_c_del(dbc, flags) - DBC *dbc; - u_int32_t flags; -{ - DBC *real_dbc; - - real_dbc = (DBC *)dbc->internal; - return (real_dbc->c_del(real_dbc, flags)); -} - -static int -__xa_c_get(dbc, key, data, flags) - DBC *dbc; - DBT *key; - DBT *data; - u_int32_t flags; -{ - DBC *real_dbc; - - real_dbc = (DBC *)dbc->internal; - return (real_dbc->c_get(real_dbc, key, data, flags)); -} - -static int -__xa_c_put(dbc, key, data, flags) - DBC *dbc; - DBT *key; - DBT *data; - u_int32_t flags; -{ - DBC *real_dbc; - - real_dbc = (DBC *)dbc->internal; - return (real_dbc->c_put(real_dbc, key, data, flags)); -} diff --git a/db2/xa/xa_map.c b/db2/xa/xa_map.c deleted file mode 100644 index d4ebbae22f..0000000000 --- a/db2/xa/xa_map.c +++ /dev/null @@ -1,305 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996, 1997, 1998 - * Sleepycat Software. All rights reserved. - */ - -#include "config.h" - -#ifndef lint -static const char sccsid[] = "@(#)xa_map.c 10.4 (Sleepycat) 10/20/98"; -#endif /* not lint */ - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <errno.h> -#include <stdio.h> -#include <string.h> -#endif - -#include "db_int.h" -#include "shqueue.h" -#include "txn.h" - -/* - * This file contains all the mapping information that we need to support - * the DB/XA interface. - */ - -/* - * __db_rmid_to_env - * Return the environment associated with a given XA rmid. - * - * PUBLIC: int __db_rmid_to_env __P((int rmid, DB_ENV **envp, int open_ok)); - */ -int -__db_rmid_to_env(rmid, envp, open_ok) - int rmid; - DB_ENV **envp; - int open_ok; -{ - DB_ENV *env; - char *dbhome; - - env = TAILQ_FIRST(&DB_GLOBAL(db_envq)); - if (env != NULL && env->xa_rmid == rmid) { - *envp = env; - return (0); - } - - /* - * When we map an rmid, move that environment to be the first one in - * the list of environments, so we pass the correct environment from - * the upcoming db_xa_open() call into db_open(). - */ - for (; env != NULL; env = TAILQ_NEXT(env, links)) - if (env->xa_rmid == rmid) { - TAILQ_REMOVE(&DB_GLOBAL(db_envq), env, links); - TAILQ_INSERT_HEAD(&DB_GLOBAL(db_envq), env, links); - *envp = env; - return (0); - } - - /* - * We have not found the rmid on the environment list. If we - * are allowed to do an open, search for the rmid on the name - * list and, if we find it, then open it. - */ - if (!open_ok) - return (1); - - if (__db_rmid_to_name(rmid, &dbhome) != 0) - return (1); -#undef XA_FLAGS -#define XA_FLAGS \ - DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN - - if (__os_calloc(1, sizeof(DB_ENV), &env) != 0) - return (1); - - if (db_appinit(dbhome, NULL, env, XA_FLAGS) != 0) - goto err; - - if (__db_map_rmid(rmid, env) != 0) - goto err1; - - __db_unmap_rmid_name(rmid); - - *envp = env; - return (0); - -err1: (void)db_appexit(env); -err: __os_free(env, sizeof(DB_ENV)); - return (1); -} - -/* - * __db_xid_to_txn - * Return the txn that corresponds to this XID. - * - * PUBLIC: int __db_xid_to_txn __P((DB_ENV *, XID *, size_t *)); - */ -int -__db_xid_to_txn(dbenv, xid, offp) - DB_ENV *dbenv; - XID *xid; - size_t *offp; -{ - DB_TXNREGION *tmr; - struct __txn_detail *td; - - /* - * Search the internal active transaction table to find the - * matching xid. If this is a performance hit, then we - * can create a hash table, but I doubt it's worth it. - */ - tmr = dbenv->tx_info->region; - - LOCK_TXNREGION(dbenv->tx_info); - for (td = SH_TAILQ_FIRST(&tmr->active_txn, __txn_detail); - td != NULL; - td = SH_TAILQ_NEXT(td, links, __txn_detail)) - if (memcmp(xid->data, td->xid, XIDDATASIZE) == 0) - break; - UNLOCK_TXNREGION(dbenv->tx_info); - - if (td == NULL) - return (EINVAL); - - *offp = (u_int8_t *)td - (u_int8_t *)tmr; - return (0); -} - -/* - * __db_map_rmid - * Create a mapping between the specified rmid and environment. - * - * PUBLIC: int __db_map_rmid __P((int, DB_ENV *)); - */ -int -__db_map_rmid(rmid, env) - int rmid; - DB_ENV *env; -{ - if (__os_calloc(1, sizeof(DB_TXN), &env->xa_txn) != 0) - return (XAER_RMERR); - env->xa_txn->txnid = TXN_INVALID; - env->xa_rmid = rmid; - TAILQ_INSERT_HEAD(&DB_GLOBAL(db_envq), env, links); - return (XA_OK); -} - -/* - * __db_unmap_rmid - * Destroy the mapping for the given rmid. - * - * PUBLIC: int __db_unmap_rmid __P((int)); - */ -int -__db_unmap_rmid(rmid) - int rmid; -{ - DB_ENV *e; - - for (e = TAILQ_FIRST(&DB_GLOBAL(db_envq)); - e->xa_rmid != rmid; - e = TAILQ_NEXT(e, links)); - - if (e == NULL) - return (EINVAL); - - TAILQ_REMOVE(&DB_GLOBAL(db_envq), e, links); - if (e->xa_txn != NULL) - __os_free(e->xa_txn, sizeof(DB_TXN)); - return (0); -} - -/* - * __db_map_xid - * Create a mapping between this XID and the transaction at - * "off" in the shared region. - * - * PUBLIC: int __db_map_xid __P((DB_ENV *, XID *, size_t)); - */ -int -__db_map_xid(env, xid, off) - DB_ENV *env; - XID *xid; - size_t off; -{ - DB_TXNMGR *tm; - TXN_DETAIL *td; - - tm = env->tx_info; - td = (TXN_DETAIL *)((u_int8_t *)tm->region + off); - - LOCK_TXNREGION(tm); - memcpy(td->xid, xid->data, XIDDATASIZE); - UNLOCK_TXNREGION(tm); - - return (0); -} - -/* - * __db_unmap_xid - * Destroy the mapping for the specified XID. - * - * PUBLIC: void __db_unmap_xid __P((DB_ENV *, XID *, size_t)); - */ - -void -__db_unmap_xid(env, xid, off) - DB_ENV *env; - XID *xid; - size_t off; -{ - TXN_DETAIL *td; - - COMPQUIET(xid, NULL); - - td = (TXN_DETAIL *)((u_int8_t *)env->tx_info->region + off); - memset(td->xid, 0, sizeof(td->xid)); -} - -/* - * __db_map_rmid_name -- - * Create a mapping from an rmid to a name (the xa_info argument). - * We use this during create and then at some later point when we are - * trying to map an rmid, we might indicate that it's OK to do an open - * in which case, we'll get the xa_info parameter from here and then - * free it up. - * - * PUBLIC: int __db_map_rmid_name __P((int, char *)); - */ - -int -__db_map_rmid_name(rmid, dbhome) - int rmid; - char *dbhome; -{ - struct __rmname *entry; - int ret; - - if ((ret = __os_malloc(sizeof(struct __rmname), NULL, &entry)) != 0) - return (ret); - - if ((ret = __os_strdup(dbhome, &entry->dbhome)) != 0) { - __os_free(entry, sizeof(struct __rmname)); - return (ret); - } - - entry->rmid = rmid; - - TAILQ_INSERT_HEAD(&DB_GLOBAL(db_nameq), entry, links); - return (0); -} - -/* - * __db_rmid_to_name -- - * Given an rmid, return the name of the home directory for that - * rmid. - * - * PUBLIC: int __db_rmid_to_name __P((int, char **)); - */ -int -__db_rmid_to_name(rmid, dbhomep) - int rmid; - char **dbhomep; -{ - struct __rmname *np; - - for (np = TAILQ_FIRST(&DB_GLOBAL(db_nameq)); np != NULL; - np = TAILQ_NEXT(np, links)) { - if (np->rmid == rmid) { - *dbhomep = np->dbhome; - return (0); - } - } - return (1); -} - -/* - * __db_unmap_rmid_name -- - * Given an rmid, remove its entry from the name list. - * - * PUBLIC: void __db_unmap_rmid_name __P((int)); - */ -void -__db_unmap_rmid_name(rmid) - int rmid; -{ - struct __rmname *np, *next; - - for (np = TAILQ_FIRST(&DB_GLOBAL(db_nameq)); np != NULL; np = next) { - next = TAILQ_NEXT(np, links); - if (np->rmid == rmid) { - TAILQ_REMOVE(&DB_GLOBAL(db_nameq), np, links); - __os_freestr(np->dbhome); - __os_free(np, sizeof(struct __rmname)); - return; - } - } - return; -} |