00001
00002
00003 #include "db_config.h"
00004
00005 #ifndef NO_SYSTEM_INCLUDES
00006 #include <sys/types.h>
00007
00008 #if TIME_WITH_SYS_TIME
00009 #include <sys/time.h>
00010 #include <time.h>
00011 #else
00012 #if HAVE_SYS_TIME_H
00013 #include <sys/time.h>
00014 #else
00015 #include <time.h>
00016 #endif
00017 #endif
00018
00019 #include <ctype.h>
00020 #include <string.h>
00021 #endif
00022
00023 #include "db_int.h"
00024 #include "dbinc/crypto.h"
00025 #include "dbinc/db_page.h"
00026 #include "dbinc/db_dispatch.h"
00027 #include "dbinc/db_am.h"
00028 #include "dbinc/db_shash.h"
00029 #include "dbinc/lock.h"
00030 #include "dbinc/log.h"
00031 #include "dbinc/txn.h"
00032
00033
00034
00035
00036
00037 int
00038 __txn_regop_log(dbenv, txnid, ret_lsnp, flags,
00039 opcode, timestamp, envid, locks)
00040 DB_ENV *dbenv;
00041 DB_TXN *txnid;
00042 DB_LSN *ret_lsnp;
00043 u_int32_t flags;
00044 u_int32_t opcode;
00045 int32_t timestamp;
00046 u_int32_t envid;
00047 const DBT *locks;
00048 {
00049 DBT logrec;
00050 DB_TXNLOGREC *lr;
00051 DB_LSN *lsnp, null_lsn, *rlsnp;
00052 u_int32_t zero, uinttmp, rectype, txn_num;
00053 u_int npad;
00054 u_int8_t *bp;
00055 int is_durable, ret;
00056
00057 COMPQUIET(lr, NULL);
00058
00059 rectype = DB___txn_regop;
00060 npad = 0;
00061 rlsnp = ret_lsnp;
00062
00063 ret = 0;
00064
00065 if (LF_ISSET(DB_LOG_NOT_DURABLE)) {
00066 if (txnid == NULL)
00067 return (0);
00068 is_durable = 0;
00069 } else
00070 is_durable = 1;
00071
00072 if (txnid == NULL) {
00073 txn_num = 0;
00074 lsnp = &null_lsn;
00075 null_lsn.file = null_lsn.offset = 0;
00076 } else {
00077 if (TAILQ_FIRST(&txnid->kids) != NULL &&
00078 (ret = __txn_activekids(dbenv, rectype, txnid)) != 0)
00079 return (ret);
00080
00081
00082
00083
00084
00085
00086 DB_SET_TXN_LSNP(txnid, &rlsnp, &lsnp);
00087 txn_num = txnid->txnid;
00088 }
00089
00090 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
00091 + sizeof(u_int32_t)
00092 + sizeof(u_int32_t)
00093 + sizeof(u_int32_t)
00094 + sizeof(u_int32_t) + (locks == NULL ? 0 : locks->size);
00095 if (CRYPTO_ON(dbenv)) {
00096 npad =
00097 ((DB_CIPHER *)dbenv->crypto_handle)->adj_size(logrec.size);
00098 logrec.size += npad;
00099 }
00100
00101 if (is_durable || txnid == NULL) {
00102 if ((ret =
00103 __os_malloc(dbenv, logrec.size, &logrec.data)) != 0)
00104 return (ret);
00105 } else {
00106 if ((ret = __os_malloc(dbenv,
00107 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
00108 return (ret);
00109 #ifdef DIAGNOSTIC
00110 if ((ret =
00111 __os_malloc(dbenv, logrec.size, &logrec.data)) != 0) {
00112 __os_free(dbenv, lr);
00113 return (ret);
00114 }
00115 #else
00116 logrec.data = lr->data;
00117 #endif
00118 }
00119 if (npad > 0)
00120 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
00121
00122 bp = logrec.data;
00123
00124 memcpy(bp, &rectype, sizeof(rectype));
00125 bp += sizeof(rectype);
00126
00127 memcpy(bp, &txn_num, sizeof(txn_num));
00128 bp += sizeof(txn_num);
00129
00130 memcpy(bp, lsnp, sizeof(DB_LSN));
00131 bp += sizeof(DB_LSN);
00132
00133 uinttmp = (u_int32_t)opcode;
00134 memcpy(bp, &uinttmp, sizeof(uinttmp));
00135 bp += sizeof(uinttmp);
00136
00137 uinttmp = (u_int32_t)timestamp;
00138 memcpy(bp, &uinttmp, sizeof(uinttmp));
00139 bp += sizeof(uinttmp);
00140
00141 uinttmp = (u_int32_t)envid;
00142 memcpy(bp, &uinttmp, sizeof(uinttmp));
00143 bp += sizeof(uinttmp);
00144
00145 if (locks == NULL) {
00146 zero = 0;
00147 memcpy(bp, &zero, sizeof(u_int32_t));
00148 bp += sizeof(u_int32_t);
00149 } else {
00150 memcpy(bp, &locks->size, sizeof(locks->size));
00151 bp += sizeof(locks->size);
00152 memcpy(bp, locks->data, locks->size);
00153 bp += locks->size;
00154 }
00155
00156 DB_ASSERT((u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
00157
00158 if (is_durable || txnid == NULL) {
00159 if ((ret = __log_put(dbenv, rlsnp,(DBT *)&logrec,
00160 flags | DB_LOG_NOCOPY)) == 0 && txnid != NULL) {
00161 *lsnp = *rlsnp;
00162 if (rlsnp != ret_lsnp)
00163 *ret_lsnp = *rlsnp;
00164 }
00165 } else {
00166 #ifdef DIAGNOSTIC
00167
00168
00169
00170
00171 memcpy(lr->data, logrec.data, logrec.size);
00172 rectype |= DB_debug_FLAG;
00173 memcpy(logrec.data, &rectype, sizeof(rectype));
00174
00175 ret = __log_put(dbenv,
00176 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
00177 #else
00178 ret = 0;
00179 #endif
00180 STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
00181 F_SET((TXN_DETAIL *)txnid->td, TXN_DTL_INMEMORY);
00182 LSN_NOT_LOGGED(*ret_lsnp);
00183 }
00184
00185 #ifdef LOG_DIAGNOSTIC
00186 if (ret != 0)
00187 (void)__txn_regop_print(dbenv,
00188 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL);
00189 #endif
00190
00191 #ifdef DIAGNOSTIC
00192 __os_free(dbenv, logrec.data);
00193 #else
00194 if (is_durable || txnid == NULL)
00195 __os_free(dbenv, logrec.data);
00196 #endif
00197 return (ret);
00198 }
00199
00200
00201
00202
00203 int
00204 __txn_regop_read(dbenv, recbuf, argpp)
00205 DB_ENV *dbenv;
00206 void *recbuf;
00207 __txn_regop_args **argpp;
00208 {
00209 __txn_regop_args *argp;
00210 u_int32_t uinttmp;
00211 u_int8_t *bp;
00212 int ret;
00213
00214 if ((ret = __os_malloc(dbenv,
00215 sizeof(__txn_regop_args) + sizeof(DB_TXN), &argp)) != 0)
00216 return (ret);
00217 bp = recbuf;
00218 argp->txnid = (DB_TXN *)&argp[1];
00219
00220 memcpy(&argp->type, bp, sizeof(argp->type));
00221 bp += sizeof(argp->type);
00222
00223 memcpy(&argp->txnid->txnid, bp, sizeof(argp->txnid->txnid));
00224 bp += sizeof(argp->txnid->txnid);
00225
00226 memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
00227 bp += sizeof(DB_LSN);
00228
00229 memcpy(&uinttmp, bp, sizeof(uinttmp));
00230 argp->opcode = (u_int32_t)uinttmp;
00231 bp += sizeof(uinttmp);
00232
00233 memcpy(&uinttmp, bp, sizeof(uinttmp));
00234 argp->timestamp = (int32_t)uinttmp;
00235 bp += sizeof(uinttmp);
00236
00237 memcpy(&uinttmp, bp, sizeof(uinttmp));
00238 argp->envid = (u_int32_t)uinttmp;
00239 bp += sizeof(uinttmp);
00240
00241 memset(&argp->locks, 0, sizeof(argp->locks));
00242 memcpy(&argp->locks.size, bp, sizeof(u_int32_t));
00243 bp += sizeof(u_int32_t);
00244 argp->locks.data = bp;
00245 bp += argp->locks.size;
00246
00247 *argpp = argp;
00248 return (0);
00249 }
00250
00251
00252
00253
00254
00255 int
00256 __txn_ckp_log(dbenv, txnid, ret_lsnp, flags,
00257 ckp_lsn, last_ckp, timestamp, envid, rep_gen)
00258 DB_ENV *dbenv;
00259 DB_TXN *txnid;
00260 DB_LSN *ret_lsnp;
00261 u_int32_t flags;
00262 DB_LSN * ckp_lsn;
00263 DB_LSN * last_ckp;
00264 int32_t timestamp;
00265 u_int32_t envid;
00266 u_int32_t rep_gen;
00267 {
00268 DBT logrec;
00269 DB_TXNLOGREC *lr;
00270 DB_LSN *lsnp, null_lsn, *rlsnp;
00271 u_int32_t uinttmp, rectype, txn_num;
00272 u_int npad;
00273 u_int8_t *bp;
00274 int is_durable, ret;
00275
00276 COMPQUIET(lr, NULL);
00277
00278 rectype = DB___txn_ckp;
00279 npad = 0;
00280 rlsnp = ret_lsnp;
00281
00282 ret = 0;
00283
00284 if (LF_ISSET(DB_LOG_NOT_DURABLE)) {
00285 if (txnid == NULL)
00286 return (0);
00287 is_durable = 0;
00288 } else
00289 is_durable = 1;
00290
00291 if (txnid == NULL) {
00292 txn_num = 0;
00293 lsnp = &null_lsn;
00294 null_lsn.file = null_lsn.offset = 0;
00295 } else {
00296 if (TAILQ_FIRST(&txnid->kids) != NULL &&
00297 (ret = __txn_activekids(dbenv, rectype, txnid)) != 0)
00298 return (ret);
00299
00300
00301
00302
00303
00304
00305 DB_SET_TXN_LSNP(txnid, &rlsnp, &lsnp);
00306 txn_num = txnid->txnid;
00307 }
00308
00309 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
00310 + sizeof(*ckp_lsn)
00311 + sizeof(*last_ckp)
00312 + sizeof(u_int32_t)
00313 + sizeof(u_int32_t)
00314 + sizeof(u_int32_t);
00315 if (CRYPTO_ON(dbenv)) {
00316 npad =
00317 ((DB_CIPHER *)dbenv->crypto_handle)->adj_size(logrec.size);
00318 logrec.size += npad;
00319 }
00320
00321 if (is_durable || txnid == NULL) {
00322 if ((ret =
00323 __os_malloc(dbenv, logrec.size, &logrec.data)) != 0)
00324 return (ret);
00325 } else {
00326 if ((ret = __os_malloc(dbenv,
00327 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
00328 return (ret);
00329 #ifdef DIAGNOSTIC
00330 if ((ret =
00331 __os_malloc(dbenv, logrec.size, &logrec.data)) != 0) {
00332 __os_free(dbenv, lr);
00333 return (ret);
00334 }
00335 #else
00336 logrec.data = lr->data;
00337 #endif
00338 }
00339 if (npad > 0)
00340 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
00341
00342 bp = logrec.data;
00343
00344 memcpy(bp, &rectype, sizeof(rectype));
00345 bp += sizeof(rectype);
00346
00347 memcpy(bp, &txn_num, sizeof(txn_num));
00348 bp += sizeof(txn_num);
00349
00350 memcpy(bp, lsnp, sizeof(DB_LSN));
00351 bp += sizeof(DB_LSN);
00352
00353 if (ckp_lsn != NULL)
00354 memcpy(bp, ckp_lsn, sizeof(*ckp_lsn));
00355 else
00356 memset(bp, 0, sizeof(*ckp_lsn));
00357 bp += sizeof(*ckp_lsn);
00358
00359 if (last_ckp != NULL)
00360 memcpy(bp, last_ckp, sizeof(*last_ckp));
00361 else
00362 memset(bp, 0, sizeof(*last_ckp));
00363 bp += sizeof(*last_ckp);
00364
00365 uinttmp = (u_int32_t)timestamp;
00366 memcpy(bp, &uinttmp, sizeof(uinttmp));
00367 bp += sizeof(uinttmp);
00368
00369 uinttmp = (u_int32_t)envid;
00370 memcpy(bp, &uinttmp, sizeof(uinttmp));
00371 bp += sizeof(uinttmp);
00372
00373 uinttmp = (u_int32_t)rep_gen;
00374 memcpy(bp, &uinttmp, sizeof(uinttmp));
00375 bp += sizeof(uinttmp);
00376
00377 DB_ASSERT((u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
00378
00379 if (is_durable || txnid == NULL) {
00380 if ((ret = __log_put(dbenv, rlsnp,(DBT *)&logrec,
00381 flags | DB_LOG_NOCOPY)) == 0 && txnid != NULL) {
00382 *lsnp = *rlsnp;
00383 if (rlsnp != ret_lsnp)
00384 *ret_lsnp = *rlsnp;
00385 }
00386 } else {
00387 #ifdef DIAGNOSTIC
00388
00389
00390
00391
00392 memcpy(lr->data, logrec.data, logrec.size);
00393 rectype |= DB_debug_FLAG;
00394 memcpy(logrec.data, &rectype, sizeof(rectype));
00395
00396 ret = __log_put(dbenv,
00397 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
00398 #else
00399 ret = 0;
00400 #endif
00401 STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
00402 F_SET((TXN_DETAIL *)txnid->td, TXN_DTL_INMEMORY);
00403 LSN_NOT_LOGGED(*ret_lsnp);
00404 }
00405
00406 #ifdef LOG_DIAGNOSTIC
00407 if (ret != 0)
00408 (void)__txn_ckp_print(dbenv,
00409 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL);
00410 #endif
00411
00412 #ifdef DIAGNOSTIC
00413 __os_free(dbenv, logrec.data);
00414 #else
00415 if (is_durable || txnid == NULL)
00416 __os_free(dbenv, logrec.data);
00417 #endif
00418 return (ret);
00419 }
00420
00421
00422
00423
00424 int
00425 __txn_ckp_read(dbenv, recbuf, argpp)
00426 DB_ENV *dbenv;
00427 void *recbuf;
00428 __txn_ckp_args **argpp;
00429 {
00430 __txn_ckp_args *argp;
00431 u_int32_t uinttmp;
00432 u_int8_t *bp;
00433 int ret;
00434
00435 if ((ret = __os_malloc(dbenv,
00436 sizeof(__txn_ckp_args) + sizeof(DB_TXN), &argp)) != 0)
00437 return (ret);
00438 bp = recbuf;
00439 argp->txnid = (DB_TXN *)&argp[1];
00440
00441 memcpy(&argp->type, bp, sizeof(argp->type));
00442 bp += sizeof(argp->type);
00443
00444 memcpy(&argp->txnid->txnid, bp, sizeof(argp->txnid->txnid));
00445 bp += sizeof(argp->txnid->txnid);
00446
00447 memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
00448 bp += sizeof(DB_LSN);
00449
00450 memcpy(&argp->ckp_lsn, bp, sizeof(argp->ckp_lsn));
00451 bp += sizeof(argp->ckp_lsn);
00452
00453 memcpy(&argp->last_ckp, bp, sizeof(argp->last_ckp));
00454 bp += sizeof(argp->last_ckp);
00455
00456 memcpy(&uinttmp, bp, sizeof(uinttmp));
00457 argp->timestamp = (int32_t)uinttmp;
00458 bp += sizeof(uinttmp);
00459
00460 memcpy(&uinttmp, bp, sizeof(uinttmp));
00461 argp->envid = (u_int32_t)uinttmp;
00462 bp += sizeof(uinttmp);
00463
00464 memcpy(&uinttmp, bp, sizeof(uinttmp));
00465 argp->rep_gen = (u_int32_t)uinttmp;
00466 bp += sizeof(uinttmp);
00467
00468 *argpp = argp;
00469 return (0);
00470 }
00471
00472
00473
00474
00475
00476 int
00477 __txn_child_log(dbenv, txnid, ret_lsnp, flags,
00478 child, c_lsn)
00479 DB_ENV *dbenv;
00480 DB_TXN *txnid;
00481 DB_LSN *ret_lsnp;
00482 u_int32_t flags;
00483 u_int32_t child;
00484 DB_LSN * c_lsn;
00485 {
00486 DBT logrec;
00487 DB_TXNLOGREC *lr;
00488 DB_LSN *lsnp, null_lsn, *rlsnp;
00489 u_int32_t uinttmp, rectype, txn_num;
00490 u_int npad;
00491 u_int8_t *bp;
00492 int is_durable, ret;
00493
00494 COMPQUIET(lr, NULL);
00495
00496 rectype = DB___txn_child;
00497 npad = 0;
00498 rlsnp = ret_lsnp;
00499
00500 ret = 0;
00501
00502 if (LF_ISSET(DB_LOG_NOT_DURABLE)) {
00503 if (txnid == NULL)
00504 return (0);
00505 is_durable = 0;
00506 } else
00507 is_durable = 1;
00508
00509 if (txnid == NULL) {
00510 txn_num = 0;
00511 lsnp = &null_lsn;
00512 null_lsn.file = null_lsn.offset = 0;
00513 } else {
00514 if (TAILQ_FIRST(&txnid->kids) != NULL &&
00515 (ret = __txn_activekids(dbenv, rectype, txnid)) != 0)
00516 return (ret);
00517
00518
00519
00520
00521
00522
00523 DB_SET_TXN_LSNP(txnid, &rlsnp, &lsnp);
00524 txn_num = txnid->txnid;
00525 }
00526
00527 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
00528 + sizeof(u_int32_t)
00529 + sizeof(*c_lsn);
00530 if (CRYPTO_ON(dbenv)) {
00531 npad =
00532 ((DB_CIPHER *)dbenv->crypto_handle)->adj_size(logrec.size);
00533 logrec.size += npad;
00534 }
00535
00536 if (is_durable || txnid == NULL) {
00537 if ((ret =
00538 __os_malloc(dbenv, logrec.size, &logrec.data)) != 0)
00539 return (ret);
00540 } else {
00541 if ((ret = __os_malloc(dbenv,
00542 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
00543 return (ret);
00544 #ifdef DIAGNOSTIC
00545 if ((ret =
00546 __os_malloc(dbenv, logrec.size, &logrec.data)) != 0) {
00547 __os_free(dbenv, lr);
00548 return (ret);
00549 }
00550 #else
00551 logrec.data = lr->data;
00552 #endif
00553 }
00554 if (npad > 0)
00555 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
00556
00557 bp = logrec.data;
00558
00559 memcpy(bp, &rectype, sizeof(rectype));
00560 bp += sizeof(rectype);
00561
00562 memcpy(bp, &txn_num, sizeof(txn_num));
00563 bp += sizeof(txn_num);
00564
00565 memcpy(bp, lsnp, sizeof(DB_LSN));
00566 bp += sizeof(DB_LSN);
00567
00568 uinttmp = (u_int32_t)child;
00569 memcpy(bp, &uinttmp, sizeof(uinttmp));
00570 bp += sizeof(uinttmp);
00571
00572 if (c_lsn != NULL)
00573 memcpy(bp, c_lsn, sizeof(*c_lsn));
00574 else
00575 memset(bp, 0, sizeof(*c_lsn));
00576 bp += sizeof(*c_lsn);
00577
00578 DB_ASSERT((u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
00579
00580 if (is_durable || txnid == NULL) {
00581 if ((ret = __log_put(dbenv, rlsnp,(DBT *)&logrec,
00582 flags | DB_LOG_NOCOPY)) == 0 && txnid != NULL) {
00583 *lsnp = *rlsnp;
00584 if (rlsnp != ret_lsnp)
00585 *ret_lsnp = *rlsnp;
00586 }
00587 } else {
00588 #ifdef DIAGNOSTIC
00589
00590
00591
00592
00593 memcpy(lr->data, logrec.data, logrec.size);
00594 rectype |= DB_debug_FLAG;
00595 memcpy(logrec.data, &rectype, sizeof(rectype));
00596
00597 ret = __log_put(dbenv,
00598 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
00599 #else
00600 ret = 0;
00601 #endif
00602 STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
00603 F_SET((TXN_DETAIL *)txnid->td, TXN_DTL_INMEMORY);
00604 LSN_NOT_LOGGED(*ret_lsnp);
00605 }
00606
00607 #ifdef LOG_DIAGNOSTIC
00608 if (ret != 0)
00609 (void)__txn_child_print(dbenv,
00610 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL);
00611 #endif
00612
00613 #ifdef DIAGNOSTIC
00614 __os_free(dbenv, logrec.data);
00615 #else
00616 if (is_durable || txnid == NULL)
00617 __os_free(dbenv, logrec.data);
00618 #endif
00619 return (ret);
00620 }
00621
00622
00623
00624
00625 int
00626 __txn_child_read(dbenv, recbuf, argpp)
00627 DB_ENV *dbenv;
00628 void *recbuf;
00629 __txn_child_args **argpp;
00630 {
00631 __txn_child_args *argp;
00632 u_int32_t uinttmp;
00633 u_int8_t *bp;
00634 int ret;
00635
00636 if ((ret = __os_malloc(dbenv,
00637 sizeof(__txn_child_args) + sizeof(DB_TXN), &argp)) != 0)
00638 return (ret);
00639 bp = recbuf;
00640 argp->txnid = (DB_TXN *)&argp[1];
00641
00642 memcpy(&argp->type, bp, sizeof(argp->type));
00643 bp += sizeof(argp->type);
00644
00645 memcpy(&argp->txnid->txnid, bp, sizeof(argp->txnid->txnid));
00646 bp += sizeof(argp->txnid->txnid);
00647
00648 memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
00649 bp += sizeof(DB_LSN);
00650
00651 memcpy(&uinttmp, bp, sizeof(uinttmp));
00652 argp->child = (u_int32_t)uinttmp;
00653 bp += sizeof(uinttmp);
00654
00655 memcpy(&argp->c_lsn, bp, sizeof(argp->c_lsn));
00656 bp += sizeof(argp->c_lsn);
00657
00658 *argpp = argp;
00659 return (0);
00660 }
00661
00662
00663
00664
00665
00666
00667 int
00668 __txn_xa_regop_log(dbenv, txnid, ret_lsnp, flags,
00669 opcode, xid, formatID, gtrid, bqual, begin_lsn,
00670 locks)
00671 DB_ENV *dbenv;
00672 DB_TXN *txnid;
00673 DB_LSN *ret_lsnp;
00674 u_int32_t flags;
00675 u_int32_t opcode;
00676 const DBT *xid;
00677 int32_t formatID;
00678 u_int32_t gtrid;
00679 u_int32_t bqual;
00680 DB_LSN * begin_lsn;
00681 const DBT *locks;
00682 {
00683 DBT logrec;
00684 DB_TXNLOGREC *lr;
00685 DB_LSN *lsnp, null_lsn, *rlsnp;
00686 u_int32_t zero, uinttmp, rectype, txn_num;
00687 u_int npad;
00688 u_int8_t *bp;
00689 int is_durable, ret;
00690
00691 COMPQUIET(lr, NULL);
00692
00693 rectype = DB___txn_xa_regop;
00694 npad = 0;
00695 rlsnp = ret_lsnp;
00696
00697 ret = 0;
00698
00699 if (LF_ISSET(DB_LOG_NOT_DURABLE)) {
00700 if (txnid == NULL)
00701 return (0);
00702 is_durable = 0;
00703 } else
00704 is_durable = 1;
00705
00706 if (txnid == NULL) {
00707 txn_num = 0;
00708 lsnp = &null_lsn;
00709 null_lsn.file = null_lsn.offset = 0;
00710 } else {
00711 if (TAILQ_FIRST(&txnid->kids) != NULL &&
00712 (ret = __txn_activekids(dbenv, rectype, txnid)) != 0)
00713 return (ret);
00714
00715
00716
00717
00718
00719
00720 DB_SET_TXN_LSNP(txnid, &rlsnp, &lsnp);
00721 txn_num = txnid->txnid;
00722 }
00723
00724 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
00725 + sizeof(u_int32_t)
00726 + sizeof(u_int32_t) + (xid == NULL ? 0 : xid->size)
00727 + sizeof(u_int32_t)
00728 + sizeof(u_int32_t)
00729 + sizeof(u_int32_t)
00730 + sizeof(*begin_lsn)
00731 + sizeof(u_int32_t) + (locks == NULL ? 0 : locks->size);
00732 if (CRYPTO_ON(dbenv)) {
00733 npad =
00734 ((DB_CIPHER *)dbenv->crypto_handle)->adj_size(logrec.size);
00735 logrec.size += npad;
00736 }
00737
00738 if (is_durable || txnid == NULL) {
00739 if ((ret =
00740 __os_malloc(dbenv, logrec.size, &logrec.data)) != 0)
00741 return (ret);
00742 } else {
00743 if ((ret = __os_malloc(dbenv,
00744 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
00745 return (ret);
00746 #ifdef DIAGNOSTIC
00747 if ((ret =
00748 __os_malloc(dbenv, logrec.size, &logrec.data)) != 0) {
00749 __os_free(dbenv, lr);
00750 return (ret);
00751 }
00752 #else
00753 logrec.data = lr->data;
00754 #endif
00755 }
00756 if (npad > 0)
00757 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
00758
00759 bp = logrec.data;
00760
00761 memcpy(bp, &rectype, sizeof(rectype));
00762 bp += sizeof(rectype);
00763
00764 memcpy(bp, &txn_num, sizeof(txn_num));
00765 bp += sizeof(txn_num);
00766
00767 memcpy(bp, lsnp, sizeof(DB_LSN));
00768 bp += sizeof(DB_LSN);
00769
00770 uinttmp = (u_int32_t)opcode;
00771 memcpy(bp, &uinttmp, sizeof(uinttmp));
00772 bp += sizeof(uinttmp);
00773
00774 if (xid == NULL) {
00775 zero = 0;
00776 memcpy(bp, &zero, sizeof(u_int32_t));
00777 bp += sizeof(u_int32_t);
00778 } else {
00779 memcpy(bp, &xid->size, sizeof(xid->size));
00780 bp += sizeof(xid->size);
00781 memcpy(bp, xid->data, xid->size);
00782 bp += xid->size;
00783 }
00784
00785 uinttmp = (u_int32_t)formatID;
00786 memcpy(bp, &uinttmp, sizeof(uinttmp));
00787 bp += sizeof(uinttmp);
00788
00789 uinttmp = (u_int32_t)gtrid;
00790 memcpy(bp, &uinttmp, sizeof(uinttmp));
00791 bp += sizeof(uinttmp);
00792
00793 uinttmp = (u_int32_t)bqual;
00794 memcpy(bp, &uinttmp, sizeof(uinttmp));
00795 bp += sizeof(uinttmp);
00796
00797 if (begin_lsn != NULL)
00798 memcpy(bp, begin_lsn, sizeof(*begin_lsn));
00799 else
00800 memset(bp, 0, sizeof(*begin_lsn));
00801 bp += sizeof(*begin_lsn);
00802
00803 if (locks == NULL) {
00804 zero = 0;
00805 memcpy(bp, &zero, sizeof(u_int32_t));
00806 bp += sizeof(u_int32_t);
00807 } else {
00808 memcpy(bp, &locks->size, sizeof(locks->size));
00809 bp += sizeof(locks->size);
00810 memcpy(bp, locks->data, locks->size);
00811 bp += locks->size;
00812 }
00813
00814 DB_ASSERT((u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
00815
00816 if (is_durable || txnid == NULL) {
00817 if ((ret = __log_put(dbenv, rlsnp,(DBT *)&logrec,
00818 flags | DB_LOG_NOCOPY)) == 0 && txnid != NULL) {
00819 *lsnp = *rlsnp;
00820 if (rlsnp != ret_lsnp)
00821 *ret_lsnp = *rlsnp;
00822 }
00823 } else {
00824 #ifdef DIAGNOSTIC
00825
00826
00827
00828
00829 memcpy(lr->data, logrec.data, logrec.size);
00830 rectype |= DB_debug_FLAG;
00831 memcpy(logrec.data, &rectype, sizeof(rectype));
00832
00833 ret = __log_put(dbenv,
00834 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
00835 #else
00836 ret = 0;
00837 #endif
00838 STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
00839 F_SET((TXN_DETAIL *)txnid->td, TXN_DTL_INMEMORY);
00840 LSN_NOT_LOGGED(*ret_lsnp);
00841 }
00842
00843 #ifdef LOG_DIAGNOSTIC
00844 if (ret != 0)
00845 (void)__txn_xa_regop_print(dbenv,
00846 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL);
00847 #endif
00848
00849 #ifdef DIAGNOSTIC
00850 __os_free(dbenv, logrec.data);
00851 #else
00852 if (is_durable || txnid == NULL)
00853 __os_free(dbenv, logrec.data);
00854 #endif
00855 return (ret);
00856 }
00857
00858
00859
00860
00861
00862 int
00863 __txn_xa_regop_read(dbenv, recbuf, argpp)
00864 DB_ENV *dbenv;
00865 void *recbuf;
00866 __txn_xa_regop_args **argpp;
00867 {
00868 __txn_xa_regop_args *argp;
00869 u_int32_t uinttmp;
00870 u_int8_t *bp;
00871 int ret;
00872
00873 if ((ret = __os_malloc(dbenv,
00874 sizeof(__txn_xa_regop_args) + sizeof(DB_TXN), &argp)) != 0)
00875 return (ret);
00876 bp = recbuf;
00877 argp->txnid = (DB_TXN *)&argp[1];
00878
00879 memcpy(&argp->type, bp, sizeof(argp->type));
00880 bp += sizeof(argp->type);
00881
00882 memcpy(&argp->txnid->txnid, bp, sizeof(argp->txnid->txnid));
00883 bp += sizeof(argp->txnid->txnid);
00884
00885 memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
00886 bp += sizeof(DB_LSN);
00887
00888 memcpy(&uinttmp, bp, sizeof(uinttmp));
00889 argp->opcode = (u_int32_t)uinttmp;
00890 bp += sizeof(uinttmp);
00891
00892 memset(&argp->xid, 0, sizeof(argp->xid));
00893 memcpy(&argp->xid.size, bp, sizeof(u_int32_t));
00894 bp += sizeof(u_int32_t);
00895 argp->xid.data = bp;
00896 bp += argp->xid.size;
00897
00898 memcpy(&uinttmp, bp, sizeof(uinttmp));
00899 argp->formatID = (int32_t)uinttmp;
00900 bp += sizeof(uinttmp);
00901
00902 memcpy(&uinttmp, bp, sizeof(uinttmp));
00903 argp->gtrid = (u_int32_t)uinttmp;
00904 bp += sizeof(uinttmp);
00905
00906 memcpy(&uinttmp, bp, sizeof(uinttmp));
00907 argp->bqual = (u_int32_t)uinttmp;
00908 bp += sizeof(uinttmp);
00909
00910 memcpy(&argp->begin_lsn, bp, sizeof(argp->begin_lsn));
00911 bp += sizeof(argp->begin_lsn);
00912
00913 memset(&argp->locks, 0, sizeof(argp->locks));
00914 memcpy(&argp->locks.size, bp, sizeof(u_int32_t));
00915 bp += sizeof(u_int32_t);
00916 argp->locks.data = bp;
00917 bp += argp->locks.size;
00918
00919 *argpp = argp;
00920 return (0);
00921 }
00922
00923
00924
00925
00926
00927 int
00928 __txn_recycle_log(dbenv, txnid, ret_lsnp, flags,
00929 min, max)
00930 DB_ENV *dbenv;
00931 DB_TXN *txnid;
00932 DB_LSN *ret_lsnp;
00933 u_int32_t flags;
00934 u_int32_t min;
00935 u_int32_t max;
00936 {
00937 DBT logrec;
00938 DB_TXNLOGREC *lr;
00939 DB_LSN *lsnp, null_lsn, *rlsnp;
00940 u_int32_t uinttmp, rectype, txn_num;
00941 u_int npad;
00942 u_int8_t *bp;
00943 int is_durable, ret;
00944
00945 COMPQUIET(lr, NULL);
00946
00947 rectype = DB___txn_recycle;
00948 npad = 0;
00949 rlsnp = ret_lsnp;
00950
00951 ret = 0;
00952
00953 if (LF_ISSET(DB_LOG_NOT_DURABLE)) {
00954 if (txnid == NULL)
00955 return (0);
00956 is_durable = 0;
00957 } else
00958 is_durable = 1;
00959
00960 if (txnid == NULL) {
00961 txn_num = 0;
00962 lsnp = &null_lsn;
00963 null_lsn.file = null_lsn.offset = 0;
00964 } else {
00965 if (TAILQ_FIRST(&txnid->kids) != NULL &&
00966 (ret = __txn_activekids(dbenv, rectype, txnid)) != 0)
00967 return (ret);
00968
00969
00970
00971
00972
00973
00974 DB_SET_TXN_LSNP(txnid, &rlsnp, &lsnp);
00975 txn_num = txnid->txnid;
00976 }
00977
00978 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
00979 + sizeof(u_int32_t)
00980 + sizeof(u_int32_t);
00981 if (CRYPTO_ON(dbenv)) {
00982 npad =
00983 ((DB_CIPHER *)dbenv->crypto_handle)->adj_size(logrec.size);
00984 logrec.size += npad;
00985 }
00986
00987 if (is_durable || txnid == NULL) {
00988 if ((ret =
00989 __os_malloc(dbenv, logrec.size, &logrec.data)) != 0)
00990 return (ret);
00991 } else {
00992 if ((ret = __os_malloc(dbenv,
00993 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
00994 return (ret);
00995 #ifdef DIAGNOSTIC
00996 if ((ret =
00997 __os_malloc(dbenv, logrec.size, &logrec.data)) != 0) {
00998 __os_free(dbenv, lr);
00999 return (ret);
01000 }
01001 #else
01002 logrec.data = lr->data;
01003 #endif
01004 }
01005 if (npad > 0)
01006 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
01007
01008 bp = logrec.data;
01009
01010 memcpy(bp, &rectype, sizeof(rectype));
01011 bp += sizeof(rectype);
01012
01013 memcpy(bp, &txn_num, sizeof(txn_num));
01014 bp += sizeof(txn_num);
01015
01016 memcpy(bp, lsnp, sizeof(DB_LSN));
01017 bp += sizeof(DB_LSN);
01018
01019 uinttmp = (u_int32_t)min;
01020 memcpy(bp, &uinttmp, sizeof(uinttmp));
01021 bp += sizeof(uinttmp);
01022
01023 uinttmp = (u_int32_t)max;
01024 memcpy(bp, &uinttmp, sizeof(uinttmp));
01025 bp += sizeof(uinttmp);
01026
01027 DB_ASSERT((u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
01028
01029 if (is_durable || txnid == NULL) {
01030 if ((ret = __log_put(dbenv, rlsnp,(DBT *)&logrec,
01031 flags | DB_LOG_NOCOPY)) == 0 && txnid != NULL) {
01032 *lsnp = *rlsnp;
01033 if (rlsnp != ret_lsnp)
01034 *ret_lsnp = *rlsnp;
01035 }
01036 } else {
01037 #ifdef DIAGNOSTIC
01038
01039
01040
01041
01042 memcpy(lr->data, logrec.data, logrec.size);
01043 rectype |= DB_debug_FLAG;
01044 memcpy(logrec.data, &rectype, sizeof(rectype));
01045
01046 ret = __log_put(dbenv,
01047 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
01048 #else
01049 ret = 0;
01050 #endif
01051 STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
01052 F_SET((TXN_DETAIL *)txnid->td, TXN_DTL_INMEMORY);
01053 LSN_NOT_LOGGED(*ret_lsnp);
01054 }
01055
01056 #ifdef LOG_DIAGNOSTIC
01057 if (ret != 0)
01058 (void)__txn_recycle_print(dbenv,
01059 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL);
01060 #endif
01061
01062 #ifdef DIAGNOSTIC
01063 __os_free(dbenv, logrec.data);
01064 #else
01065 if (is_durable || txnid == NULL)
01066 __os_free(dbenv, logrec.data);
01067 #endif
01068 return (ret);
01069 }
01070
01071
01072
01073
01074
01075 int
01076 __txn_recycle_read(dbenv, recbuf, argpp)
01077 DB_ENV *dbenv;
01078 void *recbuf;
01079 __txn_recycle_args **argpp;
01080 {
01081 __txn_recycle_args *argp;
01082 u_int32_t uinttmp;
01083 u_int8_t *bp;
01084 int ret;
01085
01086 if ((ret = __os_malloc(dbenv,
01087 sizeof(__txn_recycle_args) + sizeof(DB_TXN), &argp)) != 0)
01088 return (ret);
01089 bp = recbuf;
01090 argp->txnid = (DB_TXN *)&argp[1];
01091
01092 memcpy(&argp->type, bp, sizeof(argp->type));
01093 bp += sizeof(argp->type);
01094
01095 memcpy(&argp->txnid->txnid, bp, sizeof(argp->txnid->txnid));
01096 bp += sizeof(argp->txnid->txnid);
01097
01098 memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
01099 bp += sizeof(DB_LSN);
01100
01101 memcpy(&uinttmp, bp, sizeof(uinttmp));
01102 argp->min = (u_int32_t)uinttmp;
01103 bp += sizeof(uinttmp);
01104
01105 memcpy(&uinttmp, bp, sizeof(uinttmp));
01106 argp->max = (u_int32_t)uinttmp;
01107 bp += sizeof(uinttmp);
01108
01109 *argpp = argp;
01110 return (0);
01111 }
01112
01113
01114
01115
01116
01117 int
01118 __txn_init_recover(dbenv, dtabp, dtabsizep)
01119 DB_ENV *dbenv;
01120 int (***dtabp)__P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
01121 size_t *dtabsizep;
01122 {
01123 int ret;
01124
01125 if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
01126 __txn_regop_recover, DB___txn_regop)) != 0)
01127 return (ret);
01128 if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
01129 __txn_ckp_recover, DB___txn_ckp)) != 0)
01130 return (ret);
01131 if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
01132 __txn_child_recover, DB___txn_child)) != 0)
01133 return (ret);
01134 if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
01135 __txn_xa_regop_recover, DB___txn_xa_regop)) != 0)
01136 return (ret);
01137 if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
01138 __txn_recycle_recover, DB___txn_recycle)) != 0)
01139 return (ret);
01140 return (0);
01141 }