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
0877
0878
0879 else if (G_tmsrv_cfg.chkdisk_time > 0 && EXFALSE!=(ret=tms_log_exists_file(tmxid)))
0880 {
0881 if (EXTRUE==ret)
0882 {
0883 atmi_xa_set_error_fmt(p_ub, TPESYSTEM, 0, "Transaction [%s] exists on disk, "
0884 "but not in memory - concurrent run?", tmxid);
0885 }
0886 else
0887 {
0888 atmi_xa_set_error_fmt(p_ub, TPEOS, 0, "Transaction [%s] disk "
0889 "log verification failure", tmxid);
0890 }
0891 }
0892 else
0893 {
0894 atmi_xa_set_error_fmt(p_ub, TPEMATCH, 0, "Transaction not found [%s]",
0895 tmxid);
0896
0897
0898
0899
0900 tms_log_checkpointseq(NULL);
0901 }
0902 EXFAIL_OUT(ret);
0903 }
0904
0905
0906 if (EXSUCCEED!=tms_log_cpy_info_to_fb(p_ub, p_tl, EXFALSE))
0907 {
0908 EXFAIL_OUT(ret);
0909 }
0910
0911 out:
0912
0913 if (NULL!=p_tl)
0914 {
0915 tms_unlock_entry(p_tl);
0916 }
0917
0918 return ret;
0919 }
0920
0921
0922
0923
0924
0925
0926
0927 expublic int tm_committrans(UBFH *p_ub)
0928 {
0929 int ret = EXSUCCEED;
0930 atmi_xa_log_t *p_tl;
0931 char tmxid[NDRX_XID_SERIAL_BUFSIZE+1];
0932 atmi_xa_tx_info_t xai;
0933 int locke;
0934
0935
0936
0937
0938
0939 background_lock();
0940
0941 if (EXSUCCEED!=Bget(p_ub, TMXID, 0, tmxid, 0L))
0942 {
0943 NDRX_LOG(log_error, "Failed to read TMXID: %s",
0944 Bstrerror(Berror));
0945 atmi_xa_set_error_msg(p_ub, TPESYSTEM, 0, "Protocol error, missing TMXID!");
0946 EXFAIL_OUT(ret);
0947 }
0948
0949
0950 if (NULL==(p_tl = tms_log_get_entry(tmxid, NDRX_LOCK_WAIT_TIME, &locke)))
0951 {
0952
0953 if (locke)
0954 {
0955 atmi_xa_set_error_fmt(p_ub, TPETIME, 0, "Lock xid [%s] timed out",
0956 tmxid);
0957 }
0958 else
0959 {
0960 atmi_xa_set_error_fmt(p_ub, TPEMATCH, 0, "Transaction not found [%s]",
0961 tmxid);
0962 }
0963 EXFAIL_OUT(ret);
0964 }
0965
0966
0967 if (XA_TX_STAGE_COMMITTING!=p_tl->txstage)
0968 {
0969 atmi_xa_set_error_fmt(p_ub, TPEINVAL, 0,
0970 "Transaction not in PREPARED stage!");
0971
0972 tms_unlock_entry(p_tl);
0973 EXFAIL_OUT(ret);
0974 }
0975
0976
0977 XA_TX_COPY((&xai), p_tl);
0978
0979 if (EXSUCCEED!=(ret=tm_drive(&xai, p_tl, XA_OP_COMMIT, EXFAIL, 0L)))
0980 {
0981 atmi_xa_set_error_fmt(p_ub, ret, NDRX_XA_ERSN_RMCOMMITFAIL,
0982 "Failed to commit transaction!");
0983 ret=EXFAIL;
0984 goto out;
0985 }
0986
0987 out:
0988 background_unlock();
0989
0990 return ret;
0991 }
0992
0993
0994
0995
0996
0997
0998
0999
1000 expublic int tm_recoverlocal(UBFH *p_ub, int cd)
1001 {
1002 int ret = EXSUCCEED;
1003 long revent;
1004 XID arraxid[XID_RECOVER_BLOCK_SZ];
1005 long flags = TMSTARTRSCAN;
1006 int i;
1007 char tmp[1024];
1008 size_t out_len = sizeof(tmp);
1009
1010 while ((ret = atmi_xa_recover_entry(arraxid, XID_RECOVER_BLOCK_SZ, G_atmi_env.xa_rmid,
1011 flags)) > 0)
1012 {
1013
1014 if (TMNOFLAGS!=flags)
1015 {
1016 flags = TMNOFLAGS;
1017 }
1018
1019 NDRX_LOG(log_debug, "Recovered txns %d flags: %ld", ret, flags);
1020
1021 for (i=0; i<ret; i++)
1022 {
1023
1024 out_len = sizeof(tmp);
1025 if (NULL==ndrx_xa_base64_encode((unsigned char *)&arraxid[i], sizeof(arraxid[i]),
1026 &out_len, tmp))
1027 {
1028 NDRX_LOG(log_error, "Base64 encode failed");
1029 EXFAIL_OUT(ret);
1030 }
1031
1032
1033 NDRX_LOG(log_debug, "Recovered xid: [%s]", tmp);
1034
1035 if (EXSUCCEED!=Bchg(p_ub, TMXID, 0, tmp, 0))
1036 {
1037 NDRX_LOG(log_error, "Failed to set TMXID to [%s]", tmp);
1038 EXFAIL_OUT(ret);
1039 }
1040
1041 if (EXFAIL == tpsend(cd,
1042 (char *)p_ub,
1043 0L,
1044 0,
1045 &revent))
1046 {
1047 NDRX_LOG(log_error, "Send data failed [%s] %ld",
1048 tpstrerror(tperrno), revent);
1049 EXFAIL_OUT(ret);
1050 }
1051 else
1052 {
1053 NDRX_LOG(log_debug,"sent ok");
1054 }
1055 }
1056
1057 if (ret < XID_RECOVER_BLOCK_SZ)
1058 {
1059
1060 break;
1061 }
1062
1063 }
1064
1065 out:
1066
1067
1068
1069
1070
1071 return ret;
1072 }
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083 exprivate int tm_proclocal_single(UBFH *p_ub, int cd, char cmd, XID *xid, long flags)
1084 {
1085 int ret = EXSUCCEED;
1086 char tmp[1024];
1087 size_t out_len = sizeof(tmp);
1088 long revent;
1089
1090 atmi_xa_unset_error(p_ub);
1091 ndrx_TPunset_error();
1092
1093 switch (cmd)
1094 {
1095 case ATMI_XA_COMMITLOCAL:
1096 ret = atmi_xa_commit_entry(xid, TMNOFLAGS);
1097 break;
1098 case ATMI_XA_ABORTLOCAL:
1099 ret = atmi_xa_rollback_entry(xid, TMNOFLAGS);
1100 break;
1101 case ATMI_XA_FORGETLOCAL:
1102 ret = atmi_xa_forget_entry(xid, TMNOFLAGS);
1103 break;
1104 default:
1105 NDRX_LOG(log_error, "Invalid Opcode: %c", cmd);
1106 EXFAIL_OUT(ret);
1107 break;
1108 }
1109
1110
1111
1112
1113
1114
1115
1116 ndrx_TPset_error_ubf(p_ub);
1117
1118
1119 if (flags & TMFLAGS_NOCON)
1120 {
1121 NDRX_LOG(log_debug, "No con call: %d", ret);
1122 goto out;
1123 }
1124
1125 ret = EXSUCCEED;
1126
1127 ndrx_xa_base64_encode((unsigned char *)xid, sizeof(*xid),
1128 &out_len, tmp);
1129
1130
1131 if (EXSUCCEED!=Bchg(p_ub, TMXID, 0, tmp, 0))
1132 {
1133 NDRX_LOG(log_error, "Failed to set TMXID to [%s]", tmp);
1134 EXFAIL_OUT(ret);
1135 }
1136
1137 if (EXFAIL == tpsend(cd,
1138 (char *)p_ub,
1139 0L,
1140 0,
1141 &revent))
1142 {
1143 NDRX_LOG(log_error, "Send data failed [%s] %ld",
1144 tpstrerror(tperrno), revent);
1145 EXFAIL_OUT(ret);
1146 }
1147 else
1148 {
1149 NDRX_LOG(log_debug,"sent ok");
1150 }
1151
1152 out:
1153 return ret;
1154 }
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164 expublic int tm_proclocal(char cmd, UBFH *p_ub, int cd)
1165 {
1166 int ret = EXSUCCEED;
1167
1168 XID one;
1169 char onestr[sizeof(XID)*2];
1170 long flags = TMSTARTRSCAN;
1171 XID arraxid[XID_RECOVER_BLOCK_SZ];
1172 int i;
1173 size_t out_len = 0;
1174 BFLDLEN len;
1175 long tmtxflags=0;
1176
1177
1178
1179 if (Bpres(p_ub, TMTXFLAGS, 0) &&
1180 EXSUCCEED!=Bget(p_ub, TMTXFLAGS, 0, (char *)&tmtxflags, 0L))
1181 {
1182 NDRX_LOG(log_error, "Failed to get TMTXFLAGS: %s", Bstrerror(Berror));
1183 EXFAIL_OUT(ret);
1184 }
1185
1186 if (Bpres(p_ub, TMXID, 0))
1187 {
1188 NDRX_LOG(log_debug, "XID present -> process single");
1189 len = sizeof(onestr);
1190 if (EXSUCCEED!=Bget(p_ub, TMXID, 0, onestr, &len))
1191 {
1192 NDRX_LOG(log_error, "Failed to get TMXID: %s", Bstrerror(Berror));
1193 EXFAIL_OUT(ret);
1194 }
1195
1196 ndrx_xa_base64_decode((unsigned char *)onestr, strlen(onestr),
1197 &out_len, (char *)&one);
1198
1199 if (EXSUCCEED!=tm_proclocal_single(p_ub, cd, cmd, &one, tmtxflags))
1200 {
1201 NDRX_DUMP(log_error, "Failed to process local xid", &one, sizeof(one));
1202 EXFAIL_OUT(ret);
1203 }
1204
1205 }
1206 else while ((ret = atmi_xa_recover_entry(arraxid, XID_RECOVER_BLOCK_SZ, G_atmi_env.xa_rmid,
1207 flags)) > 0)
1208 {
1209
1210 if (TMNOFLAGS!=flags)
1211 {
1212 flags = TMNOFLAGS;
1213 }
1214
1215 NDRX_LOG(log_debug, "Recovered txns %d flags: %ld", ret, flags);
1216
1217
1218
1219
1220 for (i=0; i<ret; i++)
1221 {
1222 if (EXSUCCEED!=tm_proclocal_single(p_ub, cd, cmd, &arraxid[i], tmtxflags))
1223 {
1224 NDRX_DUMP(log_error, "Failed to process local xid", &arraxid[i],
1225 sizeof(arraxid[i]));
1226 EXFAIL_OUT(ret);
1227 }
1228 }
1229
1230 if (ret < XID_RECOVER_BLOCK_SZ)
1231 {
1232
1233 break;
1234 }
1235
1236 }
1237
1238 out:
1239
1240 return ret;
1241 }
1242
1243
1244
1245
1246
1247
1248