0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040 #include <stdio.h>
0041 #include <stdlib.h>
0042 #include <string.h>
0043 #include <errno.h>
0044 #include <regex.h>
0045 #include <utlist.h>
0046
0047 #include <ndebug.h>
0048 #include <atmi.h>
0049 #include <atmi_int.h>
0050 #include <typed_buf.h>
0051 #include <ndrstandard.h>
0052 #include <ubf.h>
0053 #include <Exfields.h>
0054
0055 #include <exnet.h>
0056 #include <ndrxdcmn.h>
0057
0058 #include "tmsrv.h"
0059 #include "../libatmisrv/srv_int.h"
0060 #include "tperror.h"
0061 #include <xa_cmn.h>
0062 #include <exbase64.h>
0063
0064
0065 #define XID_RECOVER_BLOCK_SZ 500
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082 expublic int tm_tpabort(UBFH *p_ub)
0083 {
0084 int ret = EXSUCCEED;
0085 atmi_xa_tx_info_t xai;
0086 atmi_xa_log_t *p_tl = NULL;
0087 int locke;
0088
0089 NDRX_LOG(log_debug, "tm_tpabort() called");
0090
0091
0092 if (EXSUCCEED!=atmi_xa_read_tx_info(p_ub, &xai, XA_TXINFO_NOBTID))
0093 {
0094 NDRX_LOG(log_error, "Failed to read transaction data");
0095
0096
0097
0098
0099 atmi_xa_set_error_fmt(p_ub, TPEINVAL, NDRX_XA_ERSN_NOTX,
0100 "Transaction with xid [%s] not logged - probably was tout+abort",
0101 xai.tmxid);
0102 ret=EXSUCCEED;
0103 goto out;
0104 }
0105
0106
0107 if (NULL==(p_tl = tms_log_get_entry(xai.tmxid, NDRX_LOCK_WAIT_TIME, &locke)))
0108 {
0109 if (locke)
0110 {
0111 NDRX_LOG(log_error, "Lock xid [%s] timed out",
0112 xai.tmxid);
0113 atmi_xa_set_error_fmt(p_ub, TPETIME, NDRX_XA_ERSN_LOCK,
0114 "Lock xid [%s] timed out", xai.tmxid);
0115 }
0116 else
0117 {
0118 NDRX_LOG(log_error, "Transaction with xid [%s] not logged",
0119 xai.tmxid);
0120 atmi_xa_set_error_fmt(p_ub, TPEPROTO, NDRX_XA_ERSN_NOTX,
0121 "Transaction with xid [%s] not logged", xai.tmxid);
0122 }
0123 EXFAIL_OUT(ret);
0124 }
0125
0126
0127
0128
0129 if (p_tl->is_background || XA_TX_STAGE_ACTIVE!=p_tl->txstage)
0130 {
0131 userlog("Cannot abort xid [%s] is_background: (%d) stage: (%hd)",
0132 xai.tmxid, p_tl->is_background, p_tl->txstage);
0133 NDRX_LOG(log_error, "Cannot abort xid [%s] is_background: (%d) stage: (%hd)",
0134 xai.tmxid, p_tl->is_background, p_tl->txstage);
0135
0136 if (p_tl->txstage >=XA_TX_STAGE_PREPARING)
0137 {
0138 atmi_xa_set_error_fmt(p_ub, TPEPROTO, NDRX_XA_ERSN_INPROGRESS,
0139 "Cannot abort xid [%s] is_background: (%d) stage: (%hd) (>=preparing)",
0140 xai.tmxid, p_tl->is_background, p_tl->txstage);
0141 }
0142 else
0143 {
0144
0145 atmi_xa_set_error_fmt(p_ub, TPEHEURISTIC, NDRX_XA_ERSN_INPROGRESS,
0146 "xid [%s] is_background: (%d) stage: (%hd) (is aborting)",
0147 xai.tmxid, p_tl->is_background, p_tl->txstage);
0148 }
0149
0150 tms_unlock_entry(p_tl);
0151
0152 EXFAIL_OUT(ret);
0153 }
0154
0155
0156 tms_log_stage(p_tl, XA_TX_STAGE_ABORTING, EXTRUE);
0157
0158
0159 if (EXSUCCEED!=(ret=tm_drive(&xai, p_tl, XA_OP_ROLLBACK, EXFAIL, 0L)))
0160 {
0161 atmi_xa_set_error_fmt(p_ub, ret, NDRX_XA_ERSN_RMCOMMITFAIL,
0162 "Distributed transaction process did not finish completely");
0163 ret = EXSUCCEED;
0164 }
0165
0166 out:
0167
0168 return ret;
0169 }
0170
0171
0172
0173
0174
0175
0176
0177
0178 expublic int tm_tpcommit(UBFH *p_ub)
0179 {
0180 int ret = EXSUCCEED;
0181 atmi_xa_tx_info_t xai;
0182 atmi_xa_log_t *p_tl = NULL;
0183 int do_abort = EXFALSE;
0184 long tmflags;
0185 int locke;
0186 NDRX_LOG(log_debug, "tm_tpcommit() called");
0187
0188
0189 if (EXSUCCEED!=atmi_xa_read_tx_info(p_ub, &xai, XA_TXINFO_NOBTID))
0190 {
0191 NDRX_LOG(log_error, "Failed to read transaction data");
0192 atmi_xa_set_error_msg(p_ub, TPESYSTEM, NDRX_XA_ERSN_INVPARAM,
0193 "Invalid transaction data (missing fields)");
0194 EXFAIL_OUT(ret);
0195 }
0196
0197
0198 if (EXSUCCEED!=Bget(p_ub, TMTXFLAGS, 0, (char *)&tmflags, 0L))
0199 {
0200 NDRX_LOG(log_error, "Failed to get TMTXFLAGS: %s", Bstrerror(Berror));
0201 atmi_xa_set_error_msg(p_ub, TPESYSTEM, NDRX_XA_ERSN_INVPARAM,
0202 "Failed to read TMTXFLAGS");
0203 EXFAIL_OUT(ret);
0204 }
0205
0206
0207 if (NULL==(p_tl = tms_log_get_entry(xai.tmxid, NDRX_LOCK_WAIT_TIME, &locke)))
0208 {
0209 if (locke)
0210 {
0211 NDRX_LOG(log_error, "Lock xid [%s] timed out",
0212 xai.tmxid);
0213 atmi_xa_set_error_fmt(p_ub, TPETIME, NDRX_XA_ERSN_LOCK,
0214 "Lock xid [%s] timed out", xai.tmxid);
0215 }
0216 else
0217 {
0218 NDRX_LOG(log_error, "Transaction with xid [%s] not logged",
0219 xai.tmxid);
0220 atmi_xa_set_error_fmt(p_ub, TPEABORT, NDRX_XA_ERSN_NOTX,
0221 "Transaction with xid [%s] not logged - probably was tout+abort",
0222 xai.tmxid);
0223 }
0224 EXFAIL_OUT(ret);
0225 }
0226
0227
0228
0229
0230 if (p_tl->is_background || XA_TX_STAGE_ACTIVE!=p_tl->txstage)
0231 {
0232 userlog("Cannot commit xid [%s] is_background: (%d) stage: (%hd)",
0233 xai.tmxid, p_tl->is_background, p_tl->txstage);
0234 NDRX_LOG(log_error, "Cannot commit xid [%s] is_background: (%d) stage: (%hd)",
0235 xai.tmxid, p_tl->is_background, p_tl->txstage);
0236 if (p_tl->txstage >=XA_TX_STAGE_PREPARING )
0237 {
0238 atmi_xa_set_error_fmt(p_ub, TPEPROTO, NDRX_XA_ERSN_INPROGRESS,
0239 "Cannot commit xid [%s] is_background: (%d) stage: (%hd) (>=is preparing)",
0240 xai.tmxid, p_tl->is_background, p_tl->txstage);
0241 }
0242 else
0243 {
0244 atmi_xa_set_error_fmt(p_ub, TPEABORT, NDRX_XA_ERSN_INPROGRESS,
0245 "Cannot commit xid [%s] is_background: (%d) stage: (%hd) (is aborting)",
0246 xai.tmxid, p_tl->is_background, p_tl->txstage);
0247 }
0248
0249 tms_unlock_entry(p_tl);
0250
0251 EXFAIL_OUT(ret);
0252 }
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267 if (EXSUCCEED!=tms_log_stage(p_tl, XA_TX_STAGE_PREPARING, EXFALSE))
0268 {
0269 NDRX_LOG(log_error, "Failed to log preparing stage");
0270 do_abort = EXTRUE;
0271 atmi_xa_set_error_fmt(p_ub, TPEABORT, NDRX_XA_ERSN_LOGFAIL,
0272 "Failed to log preparing stage");
0273 EXFAIL_OUT(ret);
0274 }
0275
0276
0277 if (EXSUCCEED!=(ret=tm_drive(&xai, p_tl, XA_OP_COMMIT, EXFAIL, tmflags)))
0278 {
0279 atmi_xa_set_error_msg(p_ub, ret, NDRX_XA_ERSN_RMCOMMITFAIL,
0280 "Transaction did not complete fully");
0281 ret=EXFAIL;
0282 goto out;
0283 }
0284
0285 out:
0286
0287
0288 if (do_abort)
0289 {
0290 NDRX_LOG(log_warn, "About to rollback transaction!");
0291
0292 tms_log_stage(p_tl, XA_TX_STAGE_ABORTING, EXTRUE);
0293
0294
0295 if (EXSUCCEED!=(ret=tm_drive(&xai, p_tl, XA_OP_ROLLBACK, EXFAIL, 0L)))
0296 {
0297 atmi_xa_override_error(p_ub, ret);
0298 ret=EXFAIL;
0299 }
0300
0301 }
0302
0303 return ret;
0304 }
0305
0306
0307
0308
0309
0310
0311
0312 expublic int tm_tpbegin(UBFH *p_ub)
0313 {
0314 int ret=EXSUCCEED;
0315 XID xid;
0316 atmi_xa_tx_info_t xai;
0317 int do_rollback=EXFALSE;
0318 char xid_str[NDRX_XID_SERIAL_BUFSIZE];
0319 long txtout;
0320 long tmflags;
0321 long btid = EXFAIL;
0322 NDRX_LOG(log_debug, "tm_tpbegin() called");
0323
0324 if (EXSUCCEED!=Bget(p_ub, TMTXFLAGS, 0, (char *)&tmflags, 0L))
0325 {
0326 NDRX_LOG(log_error, "Failed to read TMTXFLAGS!");
0327 EXFAIL_OUT(ret);
0328 }
0329
0330 atmi_xa_new_xid(&xid);
0331
0332 xai.tmknownrms[0] = 0;
0333
0334
0335 if (!(tmflags & TMFLAGS_DYNAMIC_REG))
0336 {
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349 if (!(tmflags & TMFLAGS_TPNOSTARTXID))
0350 {
0351 xai.tmknownrms[0] = G_atmi_env.xa_rmid;
0352 xai.tmknownrms[1] = EXEOS;
0353 }
0354 }
0355
0356 atmi_xa_serialize_xid(&xid, xid_str);
0357
0358
0359 NDRX_STRCPY_SAFE(xai.tmxid, xid_str);
0360 xai.tmrmid = G_atmi_env.xa_rmid;
0361 xai.tmnodeid = G_tmsrv_cfg.vnodeid;
0362 xai.tmsrvid = G_server_conf.srv_id;
0363
0364
0365 if (EXSUCCEED!=Bget(p_ub, TMTXTOUT, 0, (char *)&txtout, 0L) || 0>=txtout)
0366 {
0367 txtout = G_tmsrv_cfg.dflt_timeout;
0368 NDRX_LOG(log_debug, "TX tout defaulted to: %ld", txtout);
0369 }
0370 else
0371 {
0372 NDRX_LOG(log_debug, "TX tout: %ld", txtout);
0373 }
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387
0388
0389 if (EXSUCCEED!=atmi_xa_load_tx_info(p_ub, &xai))
0390 {
0391 NDRX_LOG(log_error, "Failed to load tx info!");
0392 atmi_xa_set_error_fmt(p_ub, TPETRAN, NDRX_XA_ERSN_NONE,
0393 "Failed to return tx info!");
0394 do_rollback = EXTRUE;
0395 ret=EXFAIL;
0396 goto out;
0397 }
0398
0399
0400 if (EXSUCCEED!=tms_log_start(&xai, txtout, tmflags, &btid))
0401 {
0402 NDRX_LOG(log_error, "Failed to log the transaction!");
0403 atmi_xa_set_error_fmt(p_ub, TPETRAN, NDRX_XA_ERSN_LOGFAIL,
0404 "Failed to log the transaction!");
0405 do_rollback = EXTRUE;
0406 ret=EXFAIL;
0407 goto out;
0408 }
0409
0410
0411 if (EXSUCCEED!=Bchg(p_ub, TMTXBTID, 0, (char *)&btid, 0L))
0412 {
0413 NDRX_LOG(log_error, "Failed to set TMTXBTID: %s", Bstrerror(Berror));
0414 atmi_xa_set_error_fmt(p_ub, TPESYSTEM, NDRX_XA_ERSN_UBFERR,
0415 "Failed to set TMTXBTID: %s", Bstrerror(Berror));
0416
0417
0418 do_rollback = EXTRUE;
0419 ret=EXFAIL;
0420 goto out;
0421 }
0422
0423 out:
0424
0425
0426 if (do_rollback)
0427 {
0428 ret = tm_rollback_local(p_ub, &xai, btid);
0429 }
0430
0431 return ret;
0432 }
0433
0434
0435
0436
0437
0438
0439
0440
0441
0442
0443 expublic int tm_tmregister(UBFH *p_ub)
0444 {
0445 int ret = EXSUCCEED;
0446 short callerrm;
0447 int is_already_logged = EXFALSE;
0448 atmi_xa_tx_info_t xai;
0449 long tmflags = 0;
0450 long btid=EXFAIL;
0451
0452
0453
0454
0455 if (EXSUCCEED!=Bget(p_ub, TMCALLERRM, 0, (char *)&callerrm, 0L))
0456 {
0457 atmi_xa_set_error_fmt(p_ub, TPESYSTEM, NDRX_XA_ERSN_INVPARAM,
0458 "Missing TMCALLERRM field: %s!", Bstrerror(Berror));
0459 EXFAIL_OUT(ret);
0460 }
0461
0462 if (EXSUCCEED!=atmi_xa_read_tx_info(p_ub, &xai, XA_TXINFO_NOBTID))
0463 {
0464 atmi_xa_set_error_fmt(p_ub, TPESYSTEM, NDRX_XA_ERSN_INVPARAM,
0465 "Failed to read transaction info!");
0466 EXFAIL_OUT(ret);
0467 }
0468
0469
0470
0471 if (EXSUCCEED!=Bget(p_ub, TMTXBTID, 0, (char *)&btid, NULL) && Berror!=BNOTPRES)
0472 {
0473 NDRX_LOG(log_error, "Failed to get TMTXBTID: %s", Bstrerror(Berror));
0474
0475 atmi_xa_set_error_fmt(p_ub, TPESYSTEM, NDRX_XA_ERSN_UBFERR,
0476 "Failed to get TMTXBTID: %s", Bstrerror(Berror));
0477 EXFAIL_OUT(ret);
0478 }
0479
0480 if (EXSUCCEED!=Bget(p_ub, TMTXFLAGS, 0, (char *)&tmflags, 0L))
0481 {
0482 atmi_xa_set_error_fmt(p_ub, TPESYSTEM, NDRX_XA_ERSN_INVPARAM,
0483 "Missing TMTXFLAGS in buffer");
0484 EXFAIL_OUT(ret);
0485 }
0486
0487 if (EXSUCCEED!=tms_log_addrm(&xai, callerrm, &is_already_logged, &btid, tmflags))
0488 {
0489 atmi_xa_set_error_fmt(p_ub, TPESYSTEM, NDRX_XA_ERSN_RMLOGFAIL,
0490 "Failed to log new RM!");
0491 EXFAIL_OUT(ret);
0492 }
0493
0494 if (is_already_logged)
0495 {
0496 tmflags|=TMFLAGS_RMIDKNOWN;
0497 }
0498
0499
0500 if (!Bpres(p_ub, TMTXBTID, 0) &&
0501 EXSUCCEED!=Bchg(p_ub, TMTXBTID, 0, (char *)&btid, 0L))
0502 {
0503 atmi_xa_set_error_fmt(p_ub, TPESYSTEM, NDRX_XA_ERSN_UBFERR,
0504 "Failed to set TMTXBTID!");
0505 EXFAIL_OUT(ret);
0506 }
0507
0508 if (EXSUCCEED!=Bchg(p_ub, TMTXFLAGS, 0, (char *)&tmflags, 0L))
0509 {
0510 atmi_xa_set_error_fmt(p_ub, TPESYSTEM, NDRX_XA_ERSN_UBFERR,
0511 "Failed to set TMTXFLAGS!");
0512 EXFAIL_OUT(ret);
0513 }
0514
0515 out:
0516 return ret;
0517 }
0518
0519
0520
0521
0522
0523
0524 expublic int tm_rmstatus(UBFH *p_ub)
0525 {
0526 int ret = EXSUCCEED;
0527 short callerrm;
0528 int is_already_logged = EXFALSE;
0529 atmi_xa_tx_info_t xai;
0530 long tmflags = 0;
0531 long btid=EXFAIL;
0532 char rmstatus;
0533
0534
0535
0536
0537 if (EXSUCCEED!=Bget(p_ub, TMCALLERRM, 0, (char *)&callerrm, 0L))
0538 {
0539 atmi_xa_set_error_fmt(p_ub, TPESYSTEM, NDRX_XA_ERSN_INVPARAM,
0540 "Missing TMCALLERRM field: %s!", Bstrerror(Berror));
0541 EXFAIL_OUT(ret);
0542 }
0543
0544 if (EXSUCCEED!=atmi_xa_read_tx_info(p_ub, &xai, XA_TXINFO_NOBTID))
0545 {
0546 atmi_xa_set_error_fmt(p_ub, TPESYSTEM, NDRX_XA_ERSN_INVPARAM,
0547 "Failed to read transaction info!");
0548 EXFAIL_OUT(ret);
0549 }
0550
0551
0552
0553 if (EXSUCCEED!=Bget(p_ub, TMTXBTID, 0, (char *)&btid, NULL))
0554 {
0555 atmi_xa_set_error_fmt(p_ub, TPESYSTEM, NDRX_XA_ERSN_INVPARAM,
0556 "Missing TMTXBTID!");
0557 EXFAIL_OUT(ret);
0558 }
0559
0560 if (EXSUCCEED!=Bget(p_ub, TMTXRMSTATUS, 0, (char *)&rmstatus, 0L))
0561 {
0562 atmi_xa_set_error_fmt(p_ub, TPESYSTEM, NDRX_XA_ERSN_INVPARAM,
0563 "Missing TMTXRMSTATUS in buffer");
0564 EXFAIL_OUT(ret);
0565 }
0566
0567 if (EXSUCCEED!=tms_log_chrmstat(&xai, callerrm, btid, rmstatus, p_ub))
0568 {
0569 atmi_xa_set_error_fmt(p_ub, TPESYSTEM, NDRX_XA_ERSN_RMLOGFAIL,
0570 "Failed to log new RM!");
0571 EXFAIL_OUT(ret);
0572 }
0573
0574 if (is_already_logged)
0575 {
0576 tmflags|=TMFLAGS_RMIDKNOWN;
0577 }
0578
0579
0580 if (!Bpres(p_ub, TMTXBTID, 0) &&
0581 EXSUCCEED!=Bchg(p_ub, TMTXBTID, 0, (char *)&btid, 0L))
0582 {
0583 atmi_xa_set_error_fmt(p_ub, TPESYSTEM, NDRX_XA_ERSN_UBFERR,
0584 "Failed to set TMTXBTID!");
0585 EXFAIL_OUT(ret);
0586 }
0587
0588 if (EXSUCCEED!=Bchg(p_ub, TMTXFLAGS, 0, (char *)&tmflags, 0L))
0589 {
0590 atmi_xa_set_error_fmt(p_ub, TPESYSTEM, NDRX_XA_ERSN_UBFERR,
0591 "Failed to set TMTXFLAGS!");
0592 EXFAIL_OUT(ret);
0593 }
0594
0595 out:
0596 return ret;
0597 }
0598
0599
0600
0601
0602
0603
0604
0605 expublic int tm_tmprepare(UBFH *p_ub)
0606 {
0607 int ret = EXSUCCEED;
0608 atmi_xa_tx_info_t xai;
0609
0610 NDRX_LOG(log_debug, "tm_tmprepare called.");
0611
0612 if (EXSUCCEED!=atmi_xa_read_tx_info(p_ub, &xai, 0))
0613 {
0614 atmi_xa_set_error_fmt(p_ub, TPESYSTEM, NDRX_XA_ERSN_INVPARAM,
0615 "Failed to read transaction info!");
0616 EXFAIL_OUT(ret);
0617 }
0618
0619 if (EXSUCCEED!=(ret = tm_prepare_local(p_ub, &xai, xai.btid)))
0620 {
0621 EXFAIL_OUT(ret);
0622 }
0623
0624 out:
0625 return ret;
0626 }
0627
0628
0629
0630
0631
0632
0633 expublic int tm_tmcommit(UBFH *p_ub)
0634 {
0635 int ret = EXSUCCEED;
0636 atmi_xa_tx_info_t xai;
0637
0638 NDRX_LOG(log_debug, "tm_tmcommit called.");
0639
0640 if (EXSUCCEED!=atmi_xa_read_tx_info(p_ub, &xai, 0))
0641 {
0642 atmi_xa_set_error_fmt(p_ub, TPESYSTEM, NDRX_XA_ERSN_INVPARAM,
0643 "Failed to read transaction info!");
0644 EXFAIL_OUT(ret);
0645 }
0646
0647 if (EXSUCCEED!=(ret = tm_commit_local(p_ub, &xai, xai.btid)))
0648 {
0649 EXFAIL_OUT(ret);
0650 }
0651
0652 out:
0653 return ret;
0654 }
0655
0656
0657
0658
0659
0660
0661 expublic int tm_tmabort(UBFH *p_ub)
0662 {
0663 int ret = EXSUCCEED;
0664 atmi_xa_tx_info_t xai;
0665
0666 NDRX_LOG(log_debug, "tm_tmabort called.");
0667 if (EXSUCCEED!=atmi_xa_read_tx_info(p_ub, &xai, 0))
0668 {
0669 atmi_xa_set_error_fmt(p_ub, TPESYSTEM, NDRX_XA_ERSN_INVPARAM,
0670 "Failed to read transaction info!");
0671 EXFAIL_OUT(ret);
0672 }
0673
0674
0675 if (EXSUCCEED!=(ret = tm_rollback_local(p_ub, &xai, xai.btid)))
0676 {
0677 EXFAIL_OUT(ret);
0678 }
0679
0680 out:
0681 return ret;
0682 }
0683
0684
0685
0686
0687
0688
0689 expublic int tm_tmforget(UBFH *p_ub)
0690 {
0691 int ret = EXSUCCEED;
0692 atmi_xa_tx_info_t xai;
0693
0694 NDRX_LOG(log_debug, "tm_tmforget called.");
0695 if (EXSUCCEED!=atmi_xa_read_tx_info(p_ub, &xai, 0))
0696 {
0697 atmi_xa_set_error_fmt(p_ub, TPESYSTEM, NDRX_XA_ERSN_INVPARAM,
0698 "Failed to read transaction info!");
0699 EXFAIL_OUT(ret);
0700 }
0701
0702
0703 if (EXSUCCEED!=(ret = tm_forget_local(p_ub, &xai, xai.btid)))
0704 {
0705 EXFAIL_OUT(ret);
0706 }
0707
0708 out:
0709 return ret;
0710 }
0711
0712
0713
0714
0715
0716
0717
0718
0719
0720
0721 expublic int tm_tpprinttrans(UBFH *p_ub, int cd)
0722 {
0723 int ret = EXSUCCEED;
0724 long revent;
0725 atmi_xa_log_list_t *tx_list;
0726 atmi_xa_log_list_t *el, *tmp;
0727
0728
0729 tms_tx_hash_lock();
0730
0731 tx_list = tms_copy_hash2list(COPY_MODE_FOREGROUND | COPY_MODE_BACKGROUND);
0732
0733 LL_FOREACH_SAFE(tx_list,el,tmp)
0734 {
0735
0736
0737 Bproj(p_ub, NULL);
0738 if (EXSUCCEED!=tms_log_cpy_info_to_fb(p_ub, &(el->p_tl), EXTRUE))
0739 {
0740 EXFAIL_OUT(ret);
0741 }
0742
0743
0744
0745
0746 if (EXFAIL == tpsend(cd,
0747 (char *)p_ub,
0748 0L,
0749 0,
0750 &revent))
0751 {
0752 NDRX_LOG(log_error, "Send data failed [%s] %ld",
0753 tpstrerror(tperrno), revent);
0754 EXFAIL_OUT(ret);
0755 }
0756 else
0757 {
0758 NDRX_LOG(log_debug,"sent ok");
0759 }
0760
0761 LL_DELETE(tx_list, el);
0762 NDRX_FREE(el);
0763 }
0764
0765 out:
0766
0767 tms_tx_hash_unlock();
0768
0769 return ret;
0770 }
0771
0772
0773
0774
0775
0776
0777
0778 expublic int tm_aborttrans(UBFH *p_ub)
0779 {
0780 int ret = EXSUCCEED;
0781 atmi_xa_log_t *p_tl;
0782 char tmxid[NDRX_XID_SERIAL_BUFSIZE+1];
0783 short tmrmid = EXFAIL;
0784 atmi_xa_tx_info_t xai;
0785 int locke;
0786
0787
0788
0789
0790 background_lock();
0791
0792 if (EXSUCCEED!=Bget(p_ub, TMXID, 0, tmxid, 0L))
0793 {
0794 NDRX_LOG(log_error, "Failed to read TMXID: %s",
0795 Bstrerror(Berror));
0796 atmi_xa_set_error_msg(p_ub, TPESYSTEM, 0, "Protocol error, missing TMXID!");
0797 EXFAIL_OUT(ret);
0798 }
0799
0800
0801 Bget(p_ub, TMTXRMID, 0, (char *)&tmrmid, 0L);
0802
0803
0804 if (NULL==(p_tl = tms_log_get_entry(tmxid, NDRX_LOCK_WAIT_TIME, &locke)))
0805 {
0806
0807 if (locke)
0808 {
0809 atmi_xa_set_error_fmt(p_ub, TPETIME, 0, "Lock xid [%s] timed out",
0810 tmxid);
0811 }
0812 else
0813 {
0814 atmi_xa_set_error_fmt(p_ub, TPEMATCH, 0, "Transaction not found [%s]",
0815 tmxid);
0816 }
0817 EXFAIL_OUT(ret);
0818 }
0819
0820
0821
0822
0823 XA_TX_COPY((&xai), p_tl);
0824
0825 NDRX_LOG(log_debug, "Got RMID: [%hd]", tmrmid);
0826
0827
0828 tms_log_stage(p_tl, XA_TX_STAGE_ABORTING, EXTRUE);
0829
0830 if (EXSUCCEED!=(ret=tm_drive(&xai, p_tl, XA_OP_ROLLBACK, tmrmid, 0L)))
0831 {
0832 atmi_xa_set_error_fmt(p_ub, ret, NDRX_XA_ERSN_RMERR,
0833 "Failed to abort transaction");
0834 EXFAIL_OUT(ret);
0835 }
0836
0837 out:
0838 background_unlock();
0839
0840 return ret;
0841 }
0842
0843
0844
0845
0846
0847
0848 expublic int tm_status(UBFH *p_ub)
0849 {
0850 int ret = EXSUCCEED;
0851 atmi_xa_log_t *p_tl = NULL;
0852 char tmxid[NDRX_XID_SERIAL_BUFSIZE+1];
0853 int locke;
0854
0855 if (EXSUCCEED!=Bget(p_ub, TMXID, 0, tmxid, 0L))
0856 {
0857 NDRX_LOG(log_error, "Failed to read TMXID: %s",
0858 Bstrerror(Berror));
0859 atmi_xa_set_error_msg(p_ub, TPESYSTEM, 0, "Protocol error, missing TMXID!");
0860 EXFAIL_OUT(ret);
0861 }
0862
0863
0864
0865
0866
0867 if (NULL==(p_tl = tms_log_get_entry(tmxid, NDRX_LOCK_WAIT_TIME, &locke)))
0868 {
0869
0870 if (locke)
0871 {
0872 atmi_xa_set_error_fmt(p_ub, TPETIME, 0, "Lock xid [%s] timed out",
0873 tmxid);
0874 }
0875
0876 else if (EXFALSE!=(ret=tms_log_exists_file(tmxid)))
0877 {
0878 if (EXTRUE==ret)
0879 {
0880 atmi_xa_set_error_fmt(p_ub, TPESYSTEM, 0, "Transaction [%s] exists on disk, "
0881 "but not in memory - concurrent run?", tmxid);
0882 }
0883 else
0884 {
0885 atmi_xa_set_error_fmt(p_ub, TPEOS, 0, "Transaction [%s] disk "
0886 "log verification failure", tmxid);
0887 }
0888 }
0889 else
0890 {
0891 atmi_xa_set_error_fmt(p_ub, TPEMATCH, 0, "Transaction not found [%s]",
0892 tmxid);
0893 }
0894 EXFAIL_OUT(ret);
0895 }
0896
0897
0898 if (EXSUCCEED!=tms_log_cpy_info_to_fb(p_ub, p_tl, EXFALSE))
0899 {
0900 EXFAIL_OUT(ret);
0901 }
0902
0903 out:
0904
0905 if (NULL!=p_tl)
0906 {
0907 tms_unlock_entry(p_tl);
0908 }
0909
0910 return ret;
0911 }
0912
0913
0914
0915
0916
0917
0918
0919 expublic int tm_committrans(UBFH *p_ub)
0920 {
0921 int ret = EXSUCCEED;
0922 atmi_xa_log_t *p_tl;
0923 char tmxid[NDRX_XID_SERIAL_BUFSIZE+1];
0924 atmi_xa_tx_info_t xai;
0925 int locke;
0926
0927
0928
0929
0930
0931 background_lock();
0932
0933 if (EXSUCCEED!=Bget(p_ub, TMXID, 0, tmxid, 0L))
0934 {
0935 NDRX_LOG(log_error, "Failed to read TMXID: %s",
0936 Bstrerror(Berror));
0937 atmi_xa_set_error_msg(p_ub, TPESYSTEM, 0, "Protocol error, missing TMXID!");
0938 EXFAIL_OUT(ret);
0939 }
0940
0941
0942 if (NULL==(p_tl = tms_log_get_entry(tmxid, NDRX_LOCK_WAIT_TIME, &locke)))
0943 {
0944
0945 if (locke)
0946 {
0947 atmi_xa_set_error_fmt(p_ub, TPETIME, 0, "Lock xid [%s] timed out",
0948 tmxid);
0949 }
0950 else
0951 {
0952 atmi_xa_set_error_fmt(p_ub, TPEMATCH, 0, "Transaction not found [%s]",
0953 tmxid);
0954 }
0955 EXFAIL_OUT(ret);
0956 }
0957
0958
0959 if (XA_TX_STAGE_COMMITTING!=p_tl->txstage)
0960 {
0961 atmi_xa_set_error_fmt(p_ub, TPEINVAL, 0,
0962 "Transaction not in PREPARED stage!");
0963
0964 tms_unlock_entry(p_tl);
0965 EXFAIL_OUT(ret);
0966 }
0967
0968
0969 XA_TX_COPY((&xai), p_tl);
0970
0971 if (EXSUCCEED!=(ret=tm_drive(&xai, p_tl, XA_OP_COMMIT, EXFAIL, 0L)))
0972 {
0973 atmi_xa_set_error_fmt(p_ub, ret, NDRX_XA_ERSN_RMCOMMITFAIL,
0974 "Failed to commit transaction!");
0975 ret=EXFAIL;
0976 goto out;
0977 }
0978
0979 out:
0980 background_unlock();
0981
0982 return ret;
0983 }
0984
0985
0986
0987
0988
0989
0990
0991
0992 expublic int tm_recoverlocal(UBFH *p_ub, int cd)
0993 {
0994 int ret = EXSUCCEED;
0995 long revent;
0996 XID arraxid[XID_RECOVER_BLOCK_SZ];
0997 long flags = TMSTARTRSCAN;
0998 int i;
0999 char tmp[1024];
1000 size_t out_len = sizeof(tmp);
1001
1002 while ((ret = atmi_xa_recover_entry(arraxid, XID_RECOVER_BLOCK_SZ, G_atmi_env.xa_rmid,
1003 flags)) > 0)
1004 {
1005
1006 if (TMNOFLAGS!=flags)
1007 {
1008 flags = TMNOFLAGS;
1009 }
1010
1011 NDRX_LOG(log_debug, "Recovered txns %d flags: %ld", ret, flags);
1012
1013 for (i=0; i<ret; i++)
1014 {
1015
1016 out_len = sizeof(tmp);
1017 if (NULL==ndrx_xa_base64_encode((unsigned char *)&arraxid[i], sizeof(arraxid[i]),
1018 &out_len, tmp))
1019 {
1020 NDRX_LOG(log_error, "Base64 encode failed");
1021 EXFAIL_OUT(ret);
1022 }
1023
1024
1025 NDRX_LOG(log_debug, "Recovered xid: [%s]", tmp);
1026
1027 if (EXSUCCEED!=Bchg(p_ub, TMXID, 0, tmp, 0))
1028 {
1029 NDRX_LOG(log_error, "Failed to set TMXID to [%s]", tmp);
1030 EXFAIL_OUT(ret);
1031 }
1032
1033 if (EXFAIL == tpsend(cd,
1034 (char *)p_ub,
1035 0L,
1036 0,
1037 &revent))
1038 {
1039 NDRX_LOG(log_error, "Send data failed [%s] %ld",
1040 tpstrerror(tperrno), revent);
1041 EXFAIL_OUT(ret);
1042 }
1043 else
1044 {
1045 NDRX_LOG(log_debug,"sent ok");
1046 }
1047 }
1048
1049 if (ret < XID_RECOVER_BLOCK_SZ)
1050 {
1051
1052 break;
1053 }
1054
1055 }
1056
1057 out:
1058
1059
1060
1061
1062
1063 return ret;
1064 }
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075 exprivate int tm_proclocal_single(UBFH *p_ub, int cd, char cmd, XID *xid, long flags)
1076 {
1077 int ret = EXSUCCEED;
1078 char tmp[1024];
1079 size_t out_len = sizeof(tmp);
1080 long revent;
1081
1082 atmi_xa_unset_error(p_ub);
1083 ndrx_TPunset_error();
1084
1085 switch (cmd)
1086 {
1087 case ATMI_XA_COMMITLOCAL:
1088 ret = atmi_xa_commit_entry(xid, TMNOFLAGS);
1089 break;
1090 case ATMI_XA_ABORTLOCAL:
1091 ret = atmi_xa_rollback_entry(xid, TMNOFLAGS);
1092 break;
1093 case ATMI_XA_FORGETLOCAL:
1094 ret = atmi_xa_forget_entry(xid, TMNOFLAGS);
1095 break;
1096 default:
1097 NDRX_LOG(log_error, "Invalid Opcode: %c", cmd);
1098 EXFAIL_OUT(ret);
1099 break;
1100 }
1101
1102
1103
1104
1105
1106
1107
1108 ndrx_TPset_error_ubf(p_ub);
1109
1110
1111 if (flags & TMFLAGS_NOCON)
1112 {
1113 NDRX_LOG(log_debug, "No con call: %d", ret);
1114 goto out;
1115 }
1116
1117 ret = EXSUCCEED;
1118
1119 ndrx_xa_base64_encode((unsigned char *)xid, sizeof(*xid),
1120 &out_len, tmp);
1121
1122
1123 if (EXSUCCEED!=Bchg(p_ub, TMXID, 0, tmp, 0))
1124 {
1125 NDRX_LOG(log_error, "Failed to set TMXID to [%s]", tmp);
1126 EXFAIL_OUT(ret);
1127 }
1128
1129 if (EXFAIL == tpsend(cd,
1130 (char *)p_ub,
1131 0L,
1132 0,
1133 &revent))
1134 {
1135 NDRX_LOG(log_error, "Send data failed [%s] %ld",
1136 tpstrerror(tperrno), revent);
1137 EXFAIL_OUT(ret);
1138 }
1139 else
1140 {
1141 NDRX_LOG(log_debug,"sent ok");
1142 }
1143
1144 out:
1145 return ret;
1146 }
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156 expublic int tm_proclocal(char cmd, UBFH *p_ub, int cd)
1157 {
1158 int ret = EXSUCCEED;
1159
1160 XID one;
1161 char onestr[sizeof(XID)*2];
1162 long flags = TMSTARTRSCAN;
1163 XID arraxid[XID_RECOVER_BLOCK_SZ];
1164 int i;
1165 size_t out_len = 0;
1166 BFLDLEN len;
1167 long tmtxflags=0;
1168
1169
1170
1171 if (Bpres(p_ub, TMTXFLAGS, 0) &&
1172 EXSUCCEED!=Bget(p_ub, TMTXFLAGS, 0, (char *)&tmtxflags, 0L))
1173 {
1174 NDRX_LOG(log_error, "Failed to get TMTXFLAGS: %s", Bstrerror(Berror));
1175 EXFAIL_OUT(ret);
1176 }
1177
1178 if (Bpres(p_ub, TMXID, 0))
1179 {
1180 NDRX_LOG(log_debug, "XID present -> process single");
1181 len = sizeof(onestr);
1182 if (EXSUCCEED!=Bget(p_ub, TMXID, 0, onestr, &len))
1183 {
1184 NDRX_LOG(log_error, "Failed to get TMXID: %s", Bstrerror(Berror));
1185 EXFAIL_OUT(ret);
1186 }
1187
1188 ndrx_xa_base64_decode((unsigned char *)onestr, strlen(onestr),
1189 &out_len, (char *)&one);
1190
1191 if (EXSUCCEED!=tm_proclocal_single(p_ub, cd, cmd, &one, tmtxflags))
1192 {
1193 NDRX_DUMP(log_error, "Failed to process local xid", &one, sizeof(one));
1194 EXFAIL_OUT(ret);
1195 }
1196
1197 }
1198 else while ((ret = atmi_xa_recover_entry(arraxid, XID_RECOVER_BLOCK_SZ, G_atmi_env.xa_rmid,
1199 flags)) > 0)
1200 {
1201
1202 if (TMNOFLAGS!=flags)
1203 {
1204 flags = TMNOFLAGS;
1205 }
1206
1207 NDRX_LOG(log_debug, "Recovered txns %d flags: %ld", ret, flags);
1208
1209
1210
1211
1212 for (i=0; i<ret; i++)
1213 {
1214 if (EXSUCCEED!=tm_proclocal_single(p_ub, cd, cmd, &arraxid[i], tmtxflags))
1215 {
1216 NDRX_DUMP(log_error, "Failed to process local xid", &arraxid[i],
1217 sizeof(arraxid[i]));
1218 EXFAIL_OUT(ret);
1219 }
1220 }
1221
1222 if (ret < XID_RECOVER_BLOCK_SZ)
1223 {
1224
1225 break;
1226 }
1227
1228 }
1229
1230 out:
1231
1232 return ret;
1233 }
1234
1235
1236
1237
1238
1239
1240