1/* Do not edit: automatically built by gen_rec.awk. */ 2 3#include "db_config.h" 4#include "db_int.h" 5#include "dbinc/crypto.h" 6#include "dbinc/db_page.h" 7#include "dbinc/db_dispatch.h" 8#include "dbinc/db_am.h" 9#include "dbinc/lock.h" 10#include "dbinc/log.h" 11#include "dbinc/txn.h" 12 13/* 14 * PUBLIC: int __txn_regop_42_read __P((ENV *, void *, 15 * PUBLIC: __txn_regop_42_args **)); 16 */ 17int 18__txn_regop_42_read(env, recbuf, argpp) 19 ENV *env; 20 void *recbuf; 21 __txn_regop_42_args **argpp; 22{ 23 __txn_regop_42_args *argp; 24 u_int32_t uinttmp; 25 u_int8_t *bp; 26 int ret; 27 28 if ((ret = __os_malloc(env, 29 sizeof(__txn_regop_42_args) + sizeof(DB_TXN), &argp)) != 0) 30 return (ret); 31 bp = recbuf; 32 argp->txnp = (DB_TXN *)&argp[1]; 33 memset(argp->txnp, 0, sizeof(DB_TXN)); 34 35 LOGCOPY_32(env, &argp->type, bp); 36 bp += sizeof(argp->type); 37 38 LOGCOPY_32(env, &argp->txnp->txnid, bp); 39 bp += sizeof(argp->txnp->txnid); 40 41 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 42 bp += sizeof(DB_LSN); 43 44 LOGCOPY_32(env, &argp->opcode, bp); 45 bp += sizeof(argp->opcode); 46 47 LOGCOPY_32(env, &uinttmp, bp); 48 argp->timestamp = (int32_t)uinttmp; 49 bp += sizeof(uinttmp); 50 51 memset(&argp->locks, 0, sizeof(argp->locks)); 52 LOGCOPY_32(env,&argp->locks.size, bp); 53 bp += sizeof(u_int32_t); 54 argp->locks.data = bp; 55 bp += argp->locks.size; 56 57 *argpp = argp; 58 return (ret); 59} 60 61/* 62 * PUBLIC: int __txn_regop_read __P((ENV *, void *, __txn_regop_args **)); 63 */ 64int 65__txn_regop_read(env, recbuf, argpp) 66 ENV *env; 67 void *recbuf; 68 __txn_regop_args **argpp; 69{ 70 __txn_regop_args *argp; 71 u_int32_t uinttmp; 72 u_int8_t *bp; 73 int ret; 74 75 if ((ret = __os_malloc(env, 76 sizeof(__txn_regop_args) + sizeof(DB_TXN), &argp)) != 0) 77 return (ret); 78 bp = recbuf; 79 argp->txnp = (DB_TXN *)&argp[1]; 80 memset(argp->txnp, 0, sizeof(DB_TXN)); 81 82 LOGCOPY_32(env, &argp->type, bp); 83 bp += sizeof(argp->type); 84 85 LOGCOPY_32(env, &argp->txnp->txnid, bp); 86 bp += sizeof(argp->txnp->txnid); 87 88 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 89 bp += sizeof(DB_LSN); 90 91 LOGCOPY_32(env, &argp->opcode, bp); 92 bp += sizeof(argp->opcode); 93 94 LOGCOPY_32(env, &uinttmp, bp); 95 argp->timestamp = (int32_t)uinttmp; 96 bp += sizeof(uinttmp); 97 98 LOGCOPY_32(env, &argp->envid, bp); 99 bp += sizeof(argp->envid); 100 101 memset(&argp->locks, 0, sizeof(argp->locks)); 102 LOGCOPY_32(env,&argp->locks.size, bp); 103 bp += sizeof(u_int32_t); 104 argp->locks.data = bp; 105 bp += argp->locks.size; 106 107 *argpp = argp; 108 return (ret); 109} 110 111/* 112 * PUBLIC: int __txn_regop_log __P((ENV *, DB_TXN *, DB_LSN *, 113 * PUBLIC: u_int32_t, u_int32_t, int32_t, u_int32_t, const DBT *)); 114 */ 115int 116__txn_regop_log(env, txnp, ret_lsnp, flags, 117 opcode, timestamp, envid, locks) 118 ENV *env; 119 DB_TXN *txnp; 120 DB_LSN *ret_lsnp; 121 u_int32_t flags; 122 u_int32_t opcode; 123 int32_t timestamp; 124 u_int32_t envid; 125 const DBT *locks; 126{ 127 DBT logrec; 128 DB_LSN *lsnp, null_lsn, *rlsnp; 129 DB_TXNLOGREC *lr; 130 u_int32_t zero, uinttmp, rectype, txn_num; 131 u_int npad; 132 u_int8_t *bp; 133 int is_durable, ret; 134 135 COMPQUIET(lr, NULL); 136 137 rlsnp = ret_lsnp; 138 rectype = DB___txn_regop; 139 npad = 0; 140 ret = 0; 141 142 if (LF_ISSET(DB_LOG_NOT_DURABLE)) { 143 if (txnp == NULL) 144 return (0); 145 if (txnp == NULL) 146 return (0); 147 is_durable = 0; 148 } else 149 is_durable = 1; 150 151 if (txnp == NULL) { 152 txn_num = 0; 153 lsnp = &null_lsn; 154 null_lsn.file = null_lsn.offset = 0; 155 } else { 156 if (TAILQ_FIRST(&txnp->kids) != NULL && 157 (ret = __txn_activekids(env, rectype, txnp)) != 0) 158 return (ret); 159 /* 160 * We need to assign begin_lsn while holding region mutex. 161 * That assignment is done inside the DbEnv->log_put call, 162 * so pass in the appropriate memory location to be filled 163 * in by the log_put code. 164 */ 165 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); 166 txn_num = txnp->txnid; 167 } 168 169 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) 170 + sizeof(u_int32_t) 171 + sizeof(u_int32_t) 172 + sizeof(u_int32_t) 173 + sizeof(u_int32_t) + (locks == NULL ? 0 : locks->size); 174 if (CRYPTO_ON(env)) { 175 npad = env->crypto_handle->adj_size(logrec.size); 176 logrec.size += npad; 177 } 178 179 if (is_durable || txnp == NULL) { 180 if ((ret = 181 __os_malloc(env, logrec.size, &logrec.data)) != 0) 182 return (ret); 183 } else { 184 if ((ret = __os_malloc(env, 185 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) 186 return (ret); 187#ifdef DIAGNOSTIC 188 if ((ret = 189 __os_malloc(env, logrec.size, &logrec.data)) != 0) { 190 __os_free(env, lr); 191 return (ret); 192 } 193#else 194 logrec.data = lr->data; 195#endif 196 } 197 if (npad > 0) 198 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); 199 200 bp = logrec.data; 201 202 LOGCOPY_32(env, bp, &rectype); 203 bp += sizeof(rectype); 204 205 LOGCOPY_32(env, bp, &txn_num); 206 bp += sizeof(txn_num); 207 208 LOGCOPY_FROMLSN(env, bp, lsnp); 209 bp += sizeof(DB_LSN); 210 211 LOGCOPY_32(env, bp, &opcode); 212 bp += sizeof(opcode); 213 214 uinttmp = (u_int32_t)timestamp; 215 LOGCOPY_32(env,bp, &uinttmp); 216 bp += sizeof(uinttmp); 217 218 LOGCOPY_32(env, bp, &envid); 219 bp += sizeof(envid); 220 221 if (locks == NULL) { 222 zero = 0; 223 LOGCOPY_32(env, bp, &zero); 224 bp += sizeof(u_int32_t); 225 } else { 226 LOGCOPY_32(env, bp, &locks->size); 227 bp += sizeof(locks->size); 228 memcpy(bp, locks->data, locks->size); 229 bp += locks->size; 230 } 231 232 DB_ASSERT(env, 233 (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); 234 235 if (is_durable || txnp == NULL) { 236 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, 237 flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { 238 *lsnp = *rlsnp; 239 if (rlsnp != ret_lsnp) 240 *ret_lsnp = *rlsnp; 241 } 242 } else { 243 ret = 0; 244#ifdef DIAGNOSTIC 245 /* 246 * Set the debug bit if we are going to log non-durable 247 * transactions so they will be ignored by recovery. 248 */ 249 memcpy(lr->data, logrec.data, logrec.size); 250 rectype |= DB_debug_FLAG; 251 LOGCOPY_32(env, logrec.data, &rectype); 252 253 if (!IS_REP_CLIENT(env)) 254 ret = __log_put(env, 255 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); 256#endif 257 STAILQ_INSERT_HEAD(&txnp->logs, lr, links); 258 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); 259 LSN_NOT_LOGGED(*ret_lsnp); 260 } 261 262#ifdef LOG_DIAGNOSTIC 263 if (ret != 0) 264 (void)__txn_regop_print(env, 265 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); 266#endif 267 268#ifdef DIAGNOSTIC 269 __os_free(env, logrec.data); 270#else 271 if (is_durable || txnp == NULL) 272 __os_free(env, logrec.data); 273#endif 274 return (ret); 275} 276 277/* 278 * PUBLIC: int __txn_ckp_42_read __P((ENV *, void *, __txn_ckp_42_args **)); 279 */ 280int 281__txn_ckp_42_read(env, recbuf, argpp) 282 ENV *env; 283 void *recbuf; 284 __txn_ckp_42_args **argpp; 285{ 286 __txn_ckp_42_args *argp; 287 u_int32_t uinttmp; 288 u_int8_t *bp; 289 int ret; 290 291 if ((ret = __os_malloc(env, 292 sizeof(__txn_ckp_42_args) + sizeof(DB_TXN), &argp)) != 0) 293 return (ret); 294 bp = recbuf; 295 argp->txnp = (DB_TXN *)&argp[1]; 296 memset(argp->txnp, 0, sizeof(DB_TXN)); 297 298 LOGCOPY_32(env, &argp->type, bp); 299 bp += sizeof(argp->type); 300 301 LOGCOPY_32(env, &argp->txnp->txnid, bp); 302 bp += sizeof(argp->txnp->txnid); 303 304 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 305 bp += sizeof(DB_LSN); 306 307 LOGCOPY_TOLSN(env, &argp->ckp_lsn, bp); 308 bp += sizeof(DB_LSN); 309 310 LOGCOPY_TOLSN(env, &argp->last_ckp, bp); 311 bp += sizeof(DB_LSN); 312 313 LOGCOPY_32(env, &uinttmp, bp); 314 argp->timestamp = (int32_t)uinttmp; 315 bp += sizeof(uinttmp); 316 317 LOGCOPY_32(env, &argp->rep_gen, bp); 318 bp += sizeof(argp->rep_gen); 319 320 *argpp = argp; 321 return (ret); 322} 323 324/* 325 * PUBLIC: int __txn_ckp_read __P((ENV *, void *, __txn_ckp_args **)); 326 */ 327int 328__txn_ckp_read(env, recbuf, argpp) 329 ENV *env; 330 void *recbuf; 331 __txn_ckp_args **argpp; 332{ 333 __txn_ckp_args *argp; 334 u_int32_t uinttmp; 335 u_int8_t *bp; 336 int ret; 337 338 if ((ret = __os_malloc(env, 339 sizeof(__txn_ckp_args) + sizeof(DB_TXN), &argp)) != 0) 340 return (ret); 341 bp = recbuf; 342 argp->txnp = (DB_TXN *)&argp[1]; 343 memset(argp->txnp, 0, sizeof(DB_TXN)); 344 345 LOGCOPY_32(env, &argp->type, bp); 346 bp += sizeof(argp->type); 347 348 LOGCOPY_32(env, &argp->txnp->txnid, bp); 349 bp += sizeof(argp->txnp->txnid); 350 351 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 352 bp += sizeof(DB_LSN); 353 354 LOGCOPY_TOLSN(env, &argp->ckp_lsn, bp); 355 bp += sizeof(DB_LSN); 356 357 LOGCOPY_TOLSN(env, &argp->last_ckp, bp); 358 bp += sizeof(DB_LSN); 359 360 LOGCOPY_32(env, &uinttmp, bp); 361 argp->timestamp = (int32_t)uinttmp; 362 bp += sizeof(uinttmp); 363 364 LOGCOPY_32(env, &argp->envid, bp); 365 bp += sizeof(argp->envid); 366 367 LOGCOPY_32(env, &argp->spare, bp); 368 bp += sizeof(argp->spare); 369 370 *argpp = argp; 371 return (ret); 372} 373 374/* 375 * PUBLIC: int __txn_ckp_log __P((ENV *, DB_TXN *, DB_LSN *, 376 * PUBLIC: u_int32_t, DB_LSN *, DB_LSN *, int32_t, u_int32_t, u_int32_t)); 377 */ 378int 379__txn_ckp_log(env, txnp, ret_lsnp, flags, 380 ckp_lsn, last_ckp, timestamp, envid, spare) 381 ENV *env; 382 DB_TXN *txnp; 383 DB_LSN *ret_lsnp; 384 u_int32_t flags; 385 DB_LSN * ckp_lsn; 386 DB_LSN * last_ckp; 387 int32_t timestamp; 388 u_int32_t envid; 389 u_int32_t spare; 390{ 391 DBT logrec; 392 DB_LSN *lsnp, null_lsn, *rlsnp; 393 DB_TXNLOGREC *lr; 394 u_int32_t uinttmp, rectype, txn_num; 395 u_int npad; 396 u_int8_t *bp; 397 int is_durable, ret; 398 399 COMPQUIET(lr, NULL); 400 401 rlsnp = ret_lsnp; 402 rectype = DB___txn_ckp; 403 npad = 0; 404 ret = 0; 405 406 if (LF_ISSET(DB_LOG_NOT_DURABLE)) { 407 if (txnp == NULL) 408 return (0); 409 if (txnp == NULL) 410 return (0); 411 is_durable = 0; 412 } else 413 is_durable = 1; 414 415 if (txnp == NULL) { 416 txn_num = 0; 417 lsnp = &null_lsn; 418 null_lsn.file = null_lsn.offset = 0; 419 } else { 420 if (TAILQ_FIRST(&txnp->kids) != NULL && 421 (ret = __txn_activekids(env, rectype, txnp)) != 0) 422 return (ret); 423 /* 424 * We need to assign begin_lsn while holding region mutex. 425 * That assignment is done inside the DbEnv->log_put call, 426 * so pass in the appropriate memory location to be filled 427 * in by the log_put code. 428 */ 429 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); 430 txn_num = txnp->txnid; 431 } 432 433 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) 434 + sizeof(*ckp_lsn) 435 + sizeof(*last_ckp) 436 + sizeof(u_int32_t) 437 + sizeof(u_int32_t) 438 + sizeof(u_int32_t); 439 if (CRYPTO_ON(env)) { 440 npad = env->crypto_handle->adj_size(logrec.size); 441 logrec.size += npad; 442 } 443 444 if (is_durable || txnp == NULL) { 445 if ((ret = 446 __os_malloc(env, logrec.size, &logrec.data)) != 0) 447 return (ret); 448 } else { 449 if ((ret = __os_malloc(env, 450 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) 451 return (ret); 452#ifdef DIAGNOSTIC 453 if ((ret = 454 __os_malloc(env, logrec.size, &logrec.data)) != 0) { 455 __os_free(env, lr); 456 return (ret); 457 } 458#else 459 logrec.data = lr->data; 460#endif 461 } 462 if (npad > 0) 463 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); 464 465 bp = logrec.data; 466 467 LOGCOPY_32(env, bp, &rectype); 468 bp += sizeof(rectype); 469 470 LOGCOPY_32(env, bp, &txn_num); 471 bp += sizeof(txn_num); 472 473 LOGCOPY_FROMLSN(env, bp, lsnp); 474 bp += sizeof(DB_LSN); 475 476 if (ckp_lsn != NULL) 477 LOGCOPY_FROMLSN(env, bp, ckp_lsn); 478 else 479 memset(bp, 0, sizeof(*ckp_lsn)); 480 bp += sizeof(*ckp_lsn); 481 482 if (last_ckp != NULL) 483 LOGCOPY_FROMLSN(env, bp, last_ckp); 484 else 485 memset(bp, 0, sizeof(*last_ckp)); 486 bp += sizeof(*last_ckp); 487 488 uinttmp = (u_int32_t)timestamp; 489 LOGCOPY_32(env,bp, &uinttmp); 490 bp += sizeof(uinttmp); 491 492 LOGCOPY_32(env, bp, &envid); 493 bp += sizeof(envid); 494 495 LOGCOPY_32(env, bp, &spare); 496 bp += sizeof(spare); 497 498 DB_ASSERT(env, 499 (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); 500 501 if (is_durable || txnp == NULL) { 502 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, 503 flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { 504 *lsnp = *rlsnp; 505 if (rlsnp != ret_lsnp) 506 *ret_lsnp = *rlsnp; 507 } 508 } else { 509 ret = 0; 510#ifdef DIAGNOSTIC 511 /* 512 * Set the debug bit if we are going to log non-durable 513 * transactions so they will be ignored by recovery. 514 */ 515 memcpy(lr->data, logrec.data, logrec.size); 516 rectype |= DB_debug_FLAG; 517 LOGCOPY_32(env, logrec.data, &rectype); 518 519 if (!IS_REP_CLIENT(env)) 520 ret = __log_put(env, 521 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); 522#endif 523 STAILQ_INSERT_HEAD(&txnp->logs, lr, links); 524 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); 525 LSN_NOT_LOGGED(*ret_lsnp); 526 } 527 528#ifdef LOG_DIAGNOSTIC 529 if (ret != 0) 530 (void)__txn_ckp_print(env, 531 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); 532#endif 533 534#ifdef DIAGNOSTIC 535 __os_free(env, logrec.data); 536#else 537 if (is_durable || txnp == NULL) 538 __os_free(env, logrec.data); 539#endif 540 return (ret); 541} 542 543/* 544 * PUBLIC: int __txn_child_read __P((ENV *, void *, __txn_child_args **)); 545 */ 546int 547__txn_child_read(env, recbuf, argpp) 548 ENV *env; 549 void *recbuf; 550 __txn_child_args **argpp; 551{ 552 __txn_child_args *argp; 553 u_int8_t *bp; 554 int ret; 555 556 if ((ret = __os_malloc(env, 557 sizeof(__txn_child_args) + sizeof(DB_TXN), &argp)) != 0) 558 return (ret); 559 bp = recbuf; 560 argp->txnp = (DB_TXN *)&argp[1]; 561 memset(argp->txnp, 0, sizeof(DB_TXN)); 562 563 LOGCOPY_32(env, &argp->type, bp); 564 bp += sizeof(argp->type); 565 566 LOGCOPY_32(env, &argp->txnp->txnid, bp); 567 bp += sizeof(argp->txnp->txnid); 568 569 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 570 bp += sizeof(DB_LSN); 571 572 LOGCOPY_32(env, &argp->child, bp); 573 bp += sizeof(argp->child); 574 575 LOGCOPY_TOLSN(env, &argp->c_lsn, bp); 576 bp += sizeof(DB_LSN); 577 578 *argpp = argp; 579 return (ret); 580} 581 582/* 583 * PUBLIC: int __txn_child_log __P((ENV *, DB_TXN *, DB_LSN *, 584 * PUBLIC: u_int32_t, u_int32_t, DB_LSN *)); 585 */ 586int 587__txn_child_log(env, txnp, ret_lsnp, flags, 588 child, c_lsn) 589 ENV *env; 590 DB_TXN *txnp; 591 DB_LSN *ret_lsnp; 592 u_int32_t flags; 593 u_int32_t child; 594 DB_LSN * c_lsn; 595{ 596 DBT logrec; 597 DB_LSN *lsnp, null_lsn, *rlsnp; 598 DB_TXNLOGREC *lr; 599 u_int32_t rectype, txn_num; 600 u_int npad; 601 u_int8_t *bp; 602 int is_durable, ret; 603 604 COMPQUIET(lr, NULL); 605 606 rlsnp = ret_lsnp; 607 rectype = DB___txn_child; 608 npad = 0; 609 ret = 0; 610 611 if (LF_ISSET(DB_LOG_NOT_DURABLE)) { 612 if (txnp == NULL) 613 return (0); 614 if (txnp == NULL) 615 return (0); 616 is_durable = 0; 617 } else 618 is_durable = 1; 619 620 if (txnp == NULL) { 621 txn_num = 0; 622 lsnp = &null_lsn; 623 null_lsn.file = null_lsn.offset = 0; 624 } else { 625 if (TAILQ_FIRST(&txnp->kids) != NULL && 626 (ret = __txn_activekids(env, rectype, txnp)) != 0) 627 return (ret); 628 /* 629 * We need to assign begin_lsn while holding region mutex. 630 * That assignment is done inside the DbEnv->log_put call, 631 * so pass in the appropriate memory location to be filled 632 * in by the log_put code. 633 */ 634 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); 635 txn_num = txnp->txnid; 636 } 637 638 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) 639 + sizeof(u_int32_t) 640 + sizeof(*c_lsn); 641 if (CRYPTO_ON(env)) { 642 npad = env->crypto_handle->adj_size(logrec.size); 643 logrec.size += npad; 644 } 645 646 if (is_durable || txnp == NULL) { 647 if ((ret = 648 __os_malloc(env, logrec.size, &logrec.data)) != 0) 649 return (ret); 650 } else { 651 if ((ret = __os_malloc(env, 652 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) 653 return (ret); 654#ifdef DIAGNOSTIC 655 if ((ret = 656 __os_malloc(env, logrec.size, &logrec.data)) != 0) { 657 __os_free(env, lr); 658 return (ret); 659 } 660#else 661 logrec.data = lr->data; 662#endif 663 } 664 if (npad > 0) 665 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); 666 667 bp = logrec.data; 668 669 LOGCOPY_32(env, bp, &rectype); 670 bp += sizeof(rectype); 671 672 LOGCOPY_32(env, bp, &txn_num); 673 bp += sizeof(txn_num); 674 675 LOGCOPY_FROMLSN(env, bp, lsnp); 676 bp += sizeof(DB_LSN); 677 678 LOGCOPY_32(env, bp, &child); 679 bp += sizeof(child); 680 681 if (c_lsn != NULL) 682 LOGCOPY_FROMLSN(env, bp, c_lsn); 683 else 684 memset(bp, 0, sizeof(*c_lsn)); 685 bp += sizeof(*c_lsn); 686 687 DB_ASSERT(env, 688 (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); 689 690 if (is_durable || txnp == NULL) { 691 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, 692 flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { 693 *lsnp = *rlsnp; 694 if (rlsnp != ret_lsnp) 695 *ret_lsnp = *rlsnp; 696 } 697 } else { 698 ret = 0; 699#ifdef DIAGNOSTIC 700 /* 701 * Set the debug bit if we are going to log non-durable 702 * transactions so they will be ignored by recovery. 703 */ 704 memcpy(lr->data, logrec.data, logrec.size); 705 rectype |= DB_debug_FLAG; 706 LOGCOPY_32(env, logrec.data, &rectype); 707 708 if (!IS_REP_CLIENT(env)) 709 ret = __log_put(env, 710 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); 711#endif 712 STAILQ_INSERT_HEAD(&txnp->logs, lr, links); 713 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); 714 LSN_NOT_LOGGED(*ret_lsnp); 715 } 716 717#ifdef LOG_DIAGNOSTIC 718 if (ret != 0) 719 (void)__txn_child_print(env, 720 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); 721#endif 722 723#ifdef DIAGNOSTIC 724 __os_free(env, logrec.data); 725#else 726 if (is_durable || txnp == NULL) 727 __os_free(env, logrec.data); 728#endif 729 return (ret); 730} 731 732/* 733 * PUBLIC: int __txn_xa_regop_read __P((ENV *, void *, 734 * PUBLIC: __txn_xa_regop_args **)); 735 */ 736int 737__txn_xa_regop_read(env, recbuf, argpp) 738 ENV *env; 739 void *recbuf; 740 __txn_xa_regop_args **argpp; 741{ 742 __txn_xa_regop_args *argp; 743 u_int32_t uinttmp; 744 u_int8_t *bp; 745 int ret; 746 747 if ((ret = __os_malloc(env, 748 sizeof(__txn_xa_regop_args) + sizeof(DB_TXN), &argp)) != 0) 749 return (ret); 750 bp = recbuf; 751 argp->txnp = (DB_TXN *)&argp[1]; 752 memset(argp->txnp, 0, sizeof(DB_TXN)); 753 754 LOGCOPY_32(env, &argp->type, bp); 755 bp += sizeof(argp->type); 756 757 LOGCOPY_32(env, &argp->txnp->txnid, bp); 758 bp += sizeof(argp->txnp->txnid); 759 760 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 761 bp += sizeof(DB_LSN); 762 763 LOGCOPY_32(env, &argp->opcode, bp); 764 bp += sizeof(argp->opcode); 765 766 memset(&argp->xid, 0, sizeof(argp->xid)); 767 LOGCOPY_32(env,&argp->xid.size, bp); 768 bp += sizeof(u_int32_t); 769 argp->xid.data = bp; 770 bp += argp->xid.size; 771 772 LOGCOPY_32(env, &uinttmp, bp); 773 argp->formatID = (int32_t)uinttmp; 774 bp += sizeof(uinttmp); 775 776 LOGCOPY_32(env, &argp->gtrid, bp); 777 bp += sizeof(argp->gtrid); 778 779 LOGCOPY_32(env, &argp->bqual, bp); 780 bp += sizeof(argp->bqual); 781 782 LOGCOPY_TOLSN(env, &argp->begin_lsn, bp); 783 bp += sizeof(DB_LSN); 784 785 memset(&argp->locks, 0, sizeof(argp->locks)); 786 LOGCOPY_32(env,&argp->locks.size, bp); 787 bp += sizeof(u_int32_t); 788 argp->locks.data = bp; 789 bp += argp->locks.size; 790 791 *argpp = argp; 792 return (ret); 793} 794 795/* 796 * PUBLIC: int __txn_xa_regop_log __P((ENV *, DB_TXN *, DB_LSN *, 797 * PUBLIC: u_int32_t, u_int32_t, const DBT *, int32_t, u_int32_t, u_int32_t, 798 * PUBLIC: DB_LSN *, const DBT *)); 799 */ 800int 801__txn_xa_regop_log(env, txnp, ret_lsnp, flags, 802 opcode, xid, formatID, gtrid, bqual, begin_lsn, 803 locks) 804 ENV *env; 805 DB_TXN *txnp; 806 DB_LSN *ret_lsnp; 807 u_int32_t flags; 808 u_int32_t opcode; 809 const DBT *xid; 810 int32_t formatID; 811 u_int32_t gtrid; 812 u_int32_t bqual; 813 DB_LSN * begin_lsn; 814 const DBT *locks; 815{ 816 DBT logrec; 817 DB_LSN *lsnp, null_lsn, *rlsnp; 818 DB_TXNLOGREC *lr; 819 u_int32_t zero, uinttmp, rectype, txn_num; 820 u_int npad; 821 u_int8_t *bp; 822 int is_durable, ret; 823 824 COMPQUIET(lr, NULL); 825 826 rlsnp = ret_lsnp; 827 rectype = DB___txn_xa_regop; 828 npad = 0; 829 ret = 0; 830 831 if (LF_ISSET(DB_LOG_NOT_DURABLE)) { 832 if (txnp == NULL) 833 return (0); 834 if (txnp == NULL) 835 return (0); 836 is_durable = 0; 837 } else 838 is_durable = 1; 839 840 if (txnp == NULL) { 841 txn_num = 0; 842 lsnp = &null_lsn; 843 null_lsn.file = null_lsn.offset = 0; 844 } else { 845 if (TAILQ_FIRST(&txnp->kids) != NULL && 846 (ret = __txn_activekids(env, rectype, txnp)) != 0) 847 return (ret); 848 /* 849 * We need to assign begin_lsn while holding region mutex. 850 * That assignment is done inside the DbEnv->log_put call, 851 * so pass in the appropriate memory location to be filled 852 * in by the log_put code. 853 */ 854 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); 855 txn_num = txnp->txnid; 856 } 857 858 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) 859 + sizeof(u_int32_t) 860 + sizeof(u_int32_t) + (xid == NULL ? 0 : xid->size) 861 + sizeof(u_int32_t) 862 + sizeof(u_int32_t) 863 + sizeof(u_int32_t) 864 + sizeof(*begin_lsn) 865 + sizeof(u_int32_t) + (locks == NULL ? 0 : locks->size); 866 if (CRYPTO_ON(env)) { 867 npad = env->crypto_handle->adj_size(logrec.size); 868 logrec.size += npad; 869 } 870 871 if (is_durable || txnp == NULL) { 872 if ((ret = 873 __os_malloc(env, logrec.size, &logrec.data)) != 0) 874 return (ret); 875 } else { 876 if ((ret = __os_malloc(env, 877 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) 878 return (ret); 879#ifdef DIAGNOSTIC 880 if ((ret = 881 __os_malloc(env, logrec.size, &logrec.data)) != 0) { 882 __os_free(env, lr); 883 return (ret); 884 } 885#else 886 logrec.data = lr->data; 887#endif 888 } 889 if (npad > 0) 890 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); 891 892 bp = logrec.data; 893 894 LOGCOPY_32(env, bp, &rectype); 895 bp += sizeof(rectype); 896 897 LOGCOPY_32(env, bp, &txn_num); 898 bp += sizeof(txn_num); 899 900 LOGCOPY_FROMLSN(env, bp, lsnp); 901 bp += sizeof(DB_LSN); 902 903 LOGCOPY_32(env, bp, &opcode); 904 bp += sizeof(opcode); 905 906 if (xid == NULL) { 907 zero = 0; 908 LOGCOPY_32(env, bp, &zero); 909 bp += sizeof(u_int32_t); 910 } else { 911 LOGCOPY_32(env, bp, &xid->size); 912 bp += sizeof(xid->size); 913 memcpy(bp, xid->data, xid->size); 914 bp += xid->size; 915 } 916 917 uinttmp = (u_int32_t)formatID; 918 LOGCOPY_32(env,bp, &uinttmp); 919 bp += sizeof(uinttmp); 920 921 LOGCOPY_32(env, bp, >rid); 922 bp += sizeof(gtrid); 923 924 LOGCOPY_32(env, bp, &bqual); 925 bp += sizeof(bqual); 926 927 if (begin_lsn != NULL) 928 LOGCOPY_FROMLSN(env, bp, begin_lsn); 929 else 930 memset(bp, 0, sizeof(*begin_lsn)); 931 bp += sizeof(*begin_lsn); 932 933 if (locks == NULL) { 934 zero = 0; 935 LOGCOPY_32(env, bp, &zero); 936 bp += sizeof(u_int32_t); 937 } else { 938 LOGCOPY_32(env, bp, &locks->size); 939 bp += sizeof(locks->size); 940 memcpy(bp, locks->data, locks->size); 941 bp += locks->size; 942 } 943 944 DB_ASSERT(env, 945 (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); 946 947 if (is_durable || txnp == NULL) { 948 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, 949 flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { 950 *lsnp = *rlsnp; 951 if (rlsnp != ret_lsnp) 952 *ret_lsnp = *rlsnp; 953 } 954 } else { 955 ret = 0; 956#ifdef DIAGNOSTIC 957 /* 958 * Set the debug bit if we are going to log non-durable 959 * transactions so they will be ignored by recovery. 960 */ 961 memcpy(lr->data, logrec.data, logrec.size); 962 rectype |= DB_debug_FLAG; 963 LOGCOPY_32(env, logrec.data, &rectype); 964 965 if (!IS_REP_CLIENT(env)) 966 ret = __log_put(env, 967 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); 968#endif 969 STAILQ_INSERT_HEAD(&txnp->logs, lr, links); 970 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); 971 LSN_NOT_LOGGED(*ret_lsnp); 972 } 973 974#ifdef LOG_DIAGNOSTIC 975 if (ret != 0) 976 (void)__txn_xa_regop_print(env, 977 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); 978#endif 979 980#ifdef DIAGNOSTIC 981 __os_free(env, logrec.data); 982#else 983 if (is_durable || txnp == NULL) 984 __os_free(env, logrec.data); 985#endif 986 return (ret); 987} 988 989/* 990 * PUBLIC: int __txn_recycle_read __P((ENV *, void *, __txn_recycle_args **)); 991 */ 992int 993__txn_recycle_read(env, recbuf, argpp) 994 ENV *env; 995 void *recbuf; 996 __txn_recycle_args **argpp; 997{ 998 __txn_recycle_args *argp; 999 u_int8_t *bp; 1000 int ret; 1001 1002 if ((ret = __os_malloc(env, 1003 sizeof(__txn_recycle_args) + sizeof(DB_TXN), &argp)) != 0) 1004 return (ret); 1005 bp = recbuf; 1006 argp->txnp = (DB_TXN *)&argp[1]; 1007 memset(argp->txnp, 0, sizeof(DB_TXN)); 1008 1009 LOGCOPY_32(env, &argp->type, bp); 1010 bp += sizeof(argp->type); 1011 1012 LOGCOPY_32(env, &argp->txnp->txnid, bp); 1013 bp += sizeof(argp->txnp->txnid); 1014 1015 LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); 1016 bp += sizeof(DB_LSN); 1017 1018 LOGCOPY_32(env, &argp->min, bp); 1019 bp += sizeof(argp->min); 1020 1021 LOGCOPY_32(env, &argp->max, bp); 1022 bp += sizeof(argp->max); 1023 1024 *argpp = argp; 1025 return (ret); 1026} 1027 1028/* 1029 * PUBLIC: int __txn_recycle_log __P((ENV *, DB_TXN *, DB_LSN *, 1030 * PUBLIC: u_int32_t, u_int32_t, u_int32_t)); 1031 */ 1032int 1033__txn_recycle_log(env, txnp, ret_lsnp, flags, 1034 min, max) 1035 ENV *env; 1036 DB_TXN *txnp; 1037 DB_LSN *ret_lsnp; 1038 u_int32_t flags; 1039 u_int32_t min; 1040 u_int32_t max; 1041{ 1042 DBT logrec; 1043 DB_LSN *lsnp, null_lsn, *rlsnp; 1044 DB_TXNLOGREC *lr; 1045 u_int32_t rectype, txn_num; 1046 u_int npad; 1047 u_int8_t *bp; 1048 int is_durable, ret; 1049 1050 COMPQUIET(lr, NULL); 1051 1052 rlsnp = ret_lsnp; 1053 rectype = DB___txn_recycle; 1054 npad = 0; 1055 ret = 0; 1056 1057 if (LF_ISSET(DB_LOG_NOT_DURABLE)) { 1058 if (txnp == NULL) 1059 return (0); 1060 if (txnp == NULL) 1061 return (0); 1062 is_durable = 0; 1063 } else 1064 is_durable = 1; 1065 1066 if (txnp == NULL) { 1067 txn_num = 0; 1068 lsnp = &null_lsn; 1069 null_lsn.file = null_lsn.offset = 0; 1070 } else { 1071 if (TAILQ_FIRST(&txnp->kids) != NULL && 1072 (ret = __txn_activekids(env, rectype, txnp)) != 0) 1073 return (ret); 1074 /* 1075 * We need to assign begin_lsn while holding region mutex. 1076 * That assignment is done inside the DbEnv->log_put call, 1077 * so pass in the appropriate memory location to be filled 1078 * in by the log_put code. 1079 */ 1080 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); 1081 txn_num = txnp->txnid; 1082 } 1083 1084 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) 1085 + sizeof(u_int32_t) 1086 + sizeof(u_int32_t); 1087 if (CRYPTO_ON(env)) { 1088 npad = env->crypto_handle->adj_size(logrec.size); 1089 logrec.size += npad; 1090 } 1091 1092 if (is_durable || txnp == NULL) { 1093 if ((ret = 1094 __os_malloc(env, logrec.size, &logrec.data)) != 0) 1095 return (ret); 1096 } else { 1097 if ((ret = __os_malloc(env, 1098 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) 1099 return (ret); 1100#ifdef DIAGNOSTIC 1101 if ((ret = 1102 __os_malloc(env, logrec.size, &logrec.data)) != 0) { 1103 __os_free(env, lr); 1104 return (ret); 1105 } 1106#else 1107 logrec.data = lr->data; 1108#endif 1109 } 1110 if (npad > 0) 1111 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); 1112 1113 bp = logrec.data; 1114 1115 LOGCOPY_32(env, bp, &rectype); 1116 bp += sizeof(rectype); 1117 1118 LOGCOPY_32(env, bp, &txn_num); 1119 bp += sizeof(txn_num); 1120 1121 LOGCOPY_FROMLSN(env, bp, lsnp); 1122 bp += sizeof(DB_LSN); 1123 1124 LOGCOPY_32(env, bp, &min); 1125 bp += sizeof(min); 1126 1127 LOGCOPY_32(env, bp, &max); 1128 bp += sizeof(max); 1129 1130 DB_ASSERT(env, 1131 (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); 1132 1133 if (is_durable || txnp == NULL) { 1134 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, 1135 flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { 1136 *lsnp = *rlsnp; 1137 if (rlsnp != ret_lsnp) 1138 *ret_lsnp = *rlsnp; 1139 } 1140 } else { 1141 ret = 0; 1142#ifdef DIAGNOSTIC 1143 /* 1144 * Set the debug bit if we are going to log non-durable 1145 * transactions so they will be ignored by recovery. 1146 */ 1147 memcpy(lr->data, logrec.data, logrec.size); 1148 rectype |= DB_debug_FLAG; 1149 LOGCOPY_32(env, logrec.data, &rectype); 1150 1151 if (!IS_REP_CLIENT(env)) 1152 ret = __log_put(env, 1153 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); 1154#endif 1155 STAILQ_INSERT_HEAD(&txnp->logs, lr, links); 1156 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); 1157 LSN_NOT_LOGGED(*ret_lsnp); 1158 } 1159 1160#ifdef LOG_DIAGNOSTIC 1161 if (ret != 0) 1162 (void)__txn_recycle_print(env, 1163 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); 1164#endif 1165 1166#ifdef DIAGNOSTIC 1167 __os_free(env, logrec.data); 1168#else 1169 if (is_durable || txnp == NULL) 1170 __os_free(env, logrec.data); 1171#endif 1172 return (ret); 1173} 1174 1175/* 1176 * PUBLIC: int __txn_init_recover __P((ENV *, DB_DISTAB *)); 1177 */ 1178int 1179__txn_init_recover(env, dtabp) 1180 ENV *env; 1181 DB_DISTAB *dtabp; 1182{ 1183 int ret; 1184 1185 if ((ret = __db_add_recovery_int(env, dtabp, 1186 __txn_regop_recover, DB___txn_regop)) != 0) 1187 return (ret); 1188 if ((ret = __db_add_recovery_int(env, dtabp, 1189 __txn_ckp_recover, DB___txn_ckp)) != 0) 1190 return (ret); 1191 if ((ret = __db_add_recovery_int(env, dtabp, 1192 __txn_child_recover, DB___txn_child)) != 0) 1193 return (ret); 1194 if ((ret = __db_add_recovery_int(env, dtabp, 1195 __txn_xa_regop_recover, DB___txn_xa_regop)) != 0) 1196 return (ret); 1197 if ((ret = __db_add_recovery_int(env, dtabp, 1198 __txn_recycle_recover, DB___txn_recycle)) != 0) 1199 return (ret); 1200 return (0); 1201} 1202