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
0041
0042
0043 #include <string.h>
0044 #include <stdio.h>
0045 #include <stdlib.h>
0046 #include <memory.h>
0047 #include <errno.h>
0048 #include <dlfcn.h>
0049
0050 #include <atmi.h>
0051 #include <atmi_shm.h>
0052 #include <ndrstandard.h>
0053 #include <ndebug.h>
0054 #include <nstdutil.h>
0055 #include <ndrxdcmn.h>
0056 #include <userlog.h>
0057
0058
0059 #include <sys/mman.h>
0060 #include <sys/types.h>
0061
0062 #include <unistd.h>
0063 #include <fcntl.h>
0064 #include <sys/stat.h>
0065 #include <sys/ipc.h>
0066 #include <xa_cmn.h>
0067 #include <tperror.h>
0068 #include <atmi_tls.h>
0069 #include "Exfields.h"
0070 #include "sys_test.h"
0071
0072
0073
0074 #define XA_API_ENTRY(X) {\
0075 ATMI_TLS_ENTRY;\
0076 if (!M_is_xa_init) { \
0077 if (EXSUCCEED!=(ret = atmi_xa_init()))\
0078 {\
0079 goto out;\
0080 }\
0081 }\
0082 if (!G_atmi_tls->M_is_curtx_init)\
0083 {\
0084 if (EXSUCCEED!=(ret=atmi_xa_init_thread(X)))\
0085 {\
0086 goto out;\
0087 }\
0088 }\
0089 }\
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103 #define GENERIC_RETRY_CORE(call, retry_condition, bad_status, do_primary) do {\
0104 \
0105 if (G_atmi_env.xa_recon_times && (retry_condition))\
0106 {\
0107 if (do_primary)\
0108 {\
0109 NDRX_LOG(log_warn, "RECON: Entry of %s() failed with %d", __func__, ret);\
0110 }\
0111 while (tries<G_atmi_env.xa_recon_times)\
0112 {\
0113 tries++;\
0114 NDRX_LOG(log_warn, "RECON: >>> Attempt %d type=%s. Sleeping %ld micro-sec", \
0115 tries, (do_primary?__func__:"conn-only"), G_atmi_env.xa_recon_usleep);\
0116 usleep(G_atmi_env.xa_recon_usleep);\
0117 NDRX_LOG(log_warn, "RECON: Retrying...");\
0118 \
0119 NDRX_LOG(log_warn, "RECON: atmi_xa_close_entry()");\
0120 atmi_xa_close_entry(EXTRUE);\
0121 NDRX_LOG(log_warn, "RECON: atmi_xa_open_entry()");\
0122 \
0123 ndrx_TPunset_error();\
0124 if (XA_OK==(ret=atmi_xa_open_entry()))\
0125 {\
0126 \
0127 NDRX_LOG(log_warn, "RECON: %s() call of atmi_xa_open_entry() OK", __func__);\
0128 if (do_primary)\
0129 {\
0130 NDRX_LOG(log_warn, "RECON: Retry of %s()", __func__);\
0131 \
0132 ndrx_TPunset_error();\
0133 ret = (call);\
0134 if (!(bad_status))\
0135 {\
0136 NDRX_LOG(log_warn, "RECON: <<< Succeed (%s)", __func__);\
0137 break;\
0138 }\
0139 else\
0140 {\
0141 if ((retry_condition))\
0142 {\
0143 NDRX_LOG(log_warn, "RECON: <<< Attempt %d. %s() failed %d", \
0144 tries, __func__, ret);\
0145 }\
0146 else\
0147 { \
0148 NDRX_LOG(log_warn, "RECON: <<< Attempt %d. %s() failed %d, no continue", \
0149 tries, __func__, ret);\
0150 break;\
0151 }\
0152 }\
0153 }\
0154 else\
0155 {\
0156 NDRX_LOG(log_warn, "RECON: <<< Succeed (connection)");\
0157 break;\
0158 }\
0159 }\
0160 else\
0161 {\
0162 NDRX_LOG(log_error, "RECON: <<< Attempt %d. atmi_xa_open_entry() - "\
0163 "fail: %d [%s]", tries, ret, atmi_xa_geterrstr(ret));\
0164 }\
0165 } \
0166 \
0167 if (XAER_RMFAIL==ret)\
0168 {\
0169 atmi_xa_close_entry(EXTRUE);\
0170 }\
0171 } \
0172 } while (0)
0173
0174
0175
0176
0177
0178
0179 #define GENERIC_RETRY(call, retry_condition, bad_status) do {\
0180 GENERIC_RETRY_CORE((call), (retry_condition), (bad_status), EXTRUE);\
0181 if (bad_status)\
0182 {\
0183 NDRX_LOG(log_error, "finally %s - fail: %d [%s]", \
0184 __func__, ret, atmi_xa_geterrstr(ret));\
0185 ndrx_TPset_error_fmt_rsn(TPERMERR, \
0186 ret, "finally %s - fail: %d [%s]", \
0187 __func__, ret, atmi_xa_geterrstr(ret));\
0188 goto out;\
0189 }\
0190 } while (0)
0191
0192
0193
0194
0195
0196 #define GENERIC_RETRY_ENTRY(do_rollback) \
0197 \
0198 GENERIC_RETRY_CORE(0, G_atmi_tls->G_atmi_xa_curtx.is_xa_conn_error, 0, EXFALSE);\
0199 do\
0200 {\
0201 if (XA_OK!=ret)\
0202 {\
0203 if (do_rollback)\
0204 {\
0205 ndrx_xa_join_fail(NULL, EXFALSE);\
0206 atmi_xa_reset_curtx();\
0207 }\
0208 NDRX_LOG(log_error, "finally %s - fail: %d [%s]", \
0209 __func__, ret, atmi_xa_geterrstr(ret));\
0210 ndrx_TPset_error_fmt_rsn(TPERMERR, \
0211 ret, "finally %s - fail: %d [%s]", \
0212 __func__, ret, atmi_xa_geterrstr(ret));\
0213 goto out;\
0214 }\
0215 } while (0)
0216
0217
0218
0219
0220
0221 #define GENERIC_RETRY_DEF \
0222 int tries = 0
0223
0224
0225
0226
0227
0228
0229
0230 exprivate int volatile M_is_xa_init = EXFALSE;
0231
0232
0233 exprivate MUTEX_LOCKDECL(M_is_xa_init_lock);
0234
0235
0236 exprivate int atmi_xa_init_thread(int do_open);
0237 exprivate int ndrx_xa_join_fail(int *did_abort, int force_abort);
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248 exprivate struct xa_switch_t *ndrx_aix_fix(void)
0249 {
0250 return &tmnull_switch;
0251 }
0252
0253
0254
0255
0256 exprivate int atmi_xa_init_thread(int do_open)
0257 {
0258 int ret = EXSUCCEED;
0259
0260
0261
0262 memset(&G_atmi_tls->G_atmi_xa_curtx, 0, sizeof(G_atmi_tls->G_atmi_xa_curtx));
0263 G_atmi_tls->M_is_curtx_init = EXTRUE;
0264
0265 out:
0266 return ret;
0267 }
0268
0269
0270
0271
0272 expublic void atmi_xa_uninit(void)
0273 {
0274 ATMI_TLS_ENTRY;
0275
0276 if (G_atmi_tls->M_is_curtx_init)
0277 {
0278 if (G_atmi_tls->G_atmi_xa_curtx.is_xa_open)
0279 {
0280 atmi_xa_close_entry(EXFALSE);
0281 G_atmi_tls->G_atmi_xa_curtx.is_xa_open = EXFALSE;
0282 }
0283 G_atmi_tls->M_is_curtx_init = EXFALSE;
0284 }
0285 }
0286
0287
0288
0289
0290
0291
0292
0293
0294 expublic int atmi_xa_init(void)
0295 {
0296 int ret=EXSUCCEED;
0297 void *handle;
0298 ndrx_get_xa_switch_loader func;
0299 char *error;
0300 char *xa_flags = NULL;
0301 int has_lock = EXFALSE;
0302
0303
0304 if (!M_is_xa_init)
0305 {
0306 MUTEX_LOCK_V(M_is_xa_init_lock);
0307 has_lock=EXTRUE;
0308
0309
0310 if (M_is_xa_init)
0311 {
0312 goto out;
0313 }
0314 }
0315
0316
0317 NDRX_LOG(log_info, "Loading XA driver: [%s]", G_atmi_env.xa_driverlib);
0318 handle = dlopen (G_atmi_env.xa_driverlib, RTLD_NOW);
0319 if (!handle)
0320 {
0321 error = dlerror();
0322 NDRX_LOG(log_error, "Failed to load XA lib [%s]: %s",
0323 G_atmi_env.xa_driverlib, error?error:"no dlerror provided");
0324
0325 ndrx_TPset_error_fmt(TPEOS, "Failed to load XA lib [%s]: %s",
0326 G_atmi_env.xa_driverlib, error?error:"no dlerror provided");
0327 EXFAIL_OUT(ret);
0328 }
0329
0330 func = (ndrx_get_xa_switch_loader)dlsym(handle, "ndrx_get_xa_switch");
0331
0332
0333
0334
0335
0336
0337 #ifdef EX_OS_AIX
0338 if (ndrx_str_ends_with(G_atmi_env.xa_driverlib, "libndrxxanulls.so"))
0339 {
0340 func = ndrx_aix_fix;
0341 }
0342 #endif
0343
0344 if (!func)
0345 {
0346
0347 error = dlerror();
0348 NDRX_LOG(log_error, "Failed to get symbol `ndrx_get_xa_switch' [%s]: %s",
0349 G_atmi_env.xa_driverlib, error?error:"no dlerror provided");
0350
0351 ndrx_TPset_error_fmt(TPESYSTEM, "Failed to get symbol `ndrx_get_xa_switch' [%s]: %s",
0352 G_atmi_env.xa_driverlib, error?error:"no dlerror provided");
0353 EXFAIL_OUT(ret);
0354 }
0355
0356 NDRX_LOG(log_info, "About to call ndrx_get_xa_switch()");
0357
0358
0359 if (NULL==(G_atmi_env.xa_sw = func()))
0360 {
0361 NDRX_LOG(log_error, "Cannot get XA switch handler - "
0362 "`ndrx_get_xa_switch()' - returns NULL");
0363
0364 ndrx_TPset_error_fmt(TPESYSTEM, "Cannot get XA switch handler - "
0365 "`ndrx_get_xa_switch()' - returns NULL");
0366 EXFAIL_OUT(ret);
0367 }
0368
0369 NDRX_LOG(log_info, "Using XA %s",
0370 (G_atmi_env.xa_sw->flags&TMREGISTER)?"dynamic registration":"static registration");
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387 NDRX_LOG(log_debug, "xa_flags = [%s]", G_atmi_env.xa_flags);
0388 G_atmi_env.xa_fsync_flags=0;
0389
0390
0391 NDRX_STRCPY_SAFE(G_atmi_env.xa_recon_retcodes_other, ",-7,");
0392 if (EXEOS!=G_atmi_env.xa_flags[0])
0393 {
0394 char *tag_ptr;
0395
0396 char *tag_first;
0397 char *tag_token;
0398 int token_nr = 0;
0399
0400 char *value_ptr, *value_first, *value_token;
0401
0402 if (NULL==(xa_flags = NDRX_STRDUP(G_atmi_env.xa_flags)))
0403 {
0404 int err = errno;
0405 ndrx_TPset_error_fmt(TPEOS, "Failed to allocate xa_flags temp buffer: %s",
0406 strerror(err));
0407
0408 userlog("Failed to allocate xa_flags temp buffer: %s", strerror(err));
0409
0410 EXFAIL_OUT(ret);
0411 }
0412
0413 tag_first = xa_flags;
0414 NDRX_LOG(log_debug, "About token: [%s]", tag_first);
0415 while ((tag_token = strtok_r(tag_first, ";", &tag_ptr)))
0416 {
0417 if (NULL!=tag_first)
0418 {
0419 tag_first = NULL;
0420 }
0421
0422 NDRX_LOG(log_debug, "Got tag [%s]", tag_token);
0423
0424
0425
0426
0427
0428
0429
0430
0431 if (0==strncmp(tag_token, NDRX_XA_FLAG_RECON_TEST, strlen(NDRX_XA_FLAG_RECON_TEST)))
0432 {
0433 value_first = tag_token;
0434 G_atmi_env.xa_recon_usleep = EXFAIL;
0435 NDRX_LOG(log_warn, "Parsing RECON tag... [%s]", value_first);
0436
0437 while ((value_token = strtok_r(value_first, ":", &value_ptr)))
0438 {
0439 token_nr++;
0440 if (NULL!=value_first)
0441 {
0442 value_first = NULL;
0443 }
0444
0445 switch (token_nr)
0446 {
0447 case 1:
0448
0449 NDRX_LOG(log_debug, "RECON: 1: [%s]", value_token);
0450 break;
0451 case 2:
0452
0453 NDRX_LOG(log_debug, "RECON: 2: [%s]", value_token);
0454 snprintf(G_atmi_env.xa_recon_retcodes,
0455 sizeof(G_atmi_env.xa_recon_retcodes),
0456 ",%s,", value_token);
0457
0458
0459 ndrx_str_strip(G_atmi_env.xa_recon_retcodes, "\t ");
0460
0461 break;
0462
0463 case 3:
0464 NDRX_LOG(log_debug, "RECON: 3: [%s]", value_token);
0465 G_atmi_env.xa_recon_times = atoi(value_token);
0466 break;
0467 case 4:
0468
0469 NDRX_LOG(log_debug, "RECON: 4: [%s]", value_token);
0470 G_atmi_env.xa_recon_usleep = atol(value_token)*1000;
0471 break;
0472 case 5:
0473
0474 NDRX_LOG(log_debug, "RECON: 5: [%s]", value_token);
0475 snprintf(G_atmi_env.xa_recon_retcodes_other,
0476 sizeof(G_atmi_env.xa_recon_retcodes_other),
0477 ",%s,", value_token);
0478
0479
0480 ndrx_str_strip(G_atmi_env.xa_recon_retcodes_other, "\t ");
0481
0482 break;
0483 }
0484 }
0485
0486 if (G_atmi_env.xa_recon_usleep < 0)
0487 {
0488 NDRX_LOG(log_error, "Invalid [%s] settings in "
0489 "XA_FLAGS [%s] (usleep not set)",
0490 NDRX_XA_FLAG_RECON, G_atmi_env.xa_flags);
0491
0492 ndrx_TPset_error_fmt(TPEINVAL, "Invalid [%s] settings in "
0493 "XA_FLAGS [%s] (usleep not set)",
0494 NDRX_XA_FLAG_RECON, G_atmi_env.xa_flags);
0495
0496 EXFAIL_OUT(ret);
0497 }
0498
0499 NDRX_LOG(log_error, "XA flag: [%s]: on xa_start ret codes: [%s],"
0500 " recon number of %d times, sleep %ld "
0501 "microseconds between attempts",
0502 NDRX_XA_FLAG_RECON,
0503 G_atmi_env.xa_recon_retcodes,
0504 G_atmi_env.xa_recon_times,
0505 G_atmi_env.xa_recon_usleep);
0506 }
0507 else if (0==strcmp(tag_token, NDRX_XA_FLAG_NOJOIN))
0508 {
0509 ndrx_xa_nojoin(EXTRUE);
0510 }
0511 else if (0==strcmp(tag_token, NDRX_XA_FLAG_NOSTARTXID))
0512 {
0513 ndrx_xa_nostartxid(EXTRUE);
0514 }
0515 else if (0==strcmp(tag_token, NDRX_XA_FLAG_NOSUSPEND))
0516 {
0517 ndrx_xa_nosuspend(EXTRUE);
0518 }
0519 else if (0==strcmp(tag_token, NDRX_XA_FLAG_FSYNC))
0520 {
0521 NDRX_LOG(log_warn, "XA FSYNC flag found");
0522 G_atmi_env.xa_fsync_flags|=NDRX_FSYNC_FSYNC;
0523 }
0524 else if (0==strcmp(tag_token, NDRX_XA_FLAG_FDATASYNC))
0525 {
0526 NDRX_LOG(log_warn, "XA FDATASYNC flag found");
0527 G_atmi_env.xa_fsync_flags|=NDRX_FSYNC_FDATASYNC;
0528 }
0529 else if (0==strcmp(tag_token, NDRX_XA_FLAG_DSYNC))
0530 {
0531 NDRX_LOG(log_warn, "XA DSYNC flag found");
0532 G_atmi_env.xa_fsync_flags|=NDRX_FSYNC_DSYNC;
0533 }
0534 else if (0==strcmp(tag_token, NDRX_XA_FLAG_BTIGHT))
0535 {
0536 ndrx_xa_btight(EXTRUE);
0537 }
0538
0539 }
0540 }
0541
0542 M_is_xa_init = EXTRUE;
0543
0544 if (EXSUCCEED==ret)
0545 {
0546 NDRX_LOG(log_info, "XA lib initialized.");
0547
0548 }
0549
0550 out:
0551
0552 if (has_lock)
0553 {
0554 MUTEX_UNLOCK_V(M_is_xa_init_lock);
0555 }
0556
0557 if (NULL!=xa_flags)
0558 {
0559 NDRX_FREE(xa_flags);
0560 }
0561
0562 if (EXSUCCEED!=ret && NULL!=handle)
0563 {
0564
0565 dlclose(handle);
0566 }
0567
0568 return ret;
0569 }
0570
0571
0572
0573
0574
0575
0576
0577
0578
0579 expublic int atmi_xa_open_entry(void)
0580 {
0581 int ret = EXSUCCEED;
0582 XA_API_ENTRY(EXFALSE);
0583
0584 NDRX_LOG(log_debug, "atmi_xa_open_entry RMID=%hd", G_atmi_env.xa_rmid);
0585
0586 if (G_atmi_tls->G_atmi_xa_curtx.is_xa_open
0587 && !G_atmi_tls->G_atmi_xa_curtx.is_xa_conn_error)
0588 {
0589 NDRX_LOG(log_warn, "xa_open_entry already called for context!");
0590 goto out;
0591 }
0592
0593 if (XA_OK!=(ret = G_atmi_env.xa_sw->xa_open_entry(G_atmi_env.xa_open_str,
0594 G_atmi_env.xa_rmid, 0)))
0595 {
0596
0597 if (XAER_RMERR==ret)
0598 {
0599 ret = XAER_RMFAIL;
0600 NDRX_LOG(log_error, "atmi_xa_open_entry ret XAER_RMERR remapping to XAER_RMFAIL");
0601 }
0602
0603 NDRX_LOG(log_error, "atmi_xa_open_entry - fail: %d [%s]",
0604 ret, atmi_xa_geterrstr(ret));
0605
0606
0607 ndrx_TPset_error_fmt_rsn(TPERMERR, ret, "atmi_xa_open_entry - fail: %d [%s]",
0608 ret, atmi_xa_geterrstr(ret));
0609
0610 goto out;
0611 }
0612
0613 G_atmi_tls->G_atmi_xa_curtx.is_xa_open = EXTRUE;
0614
0615
0616 if (G_atmi_tls->G_atmi_xa_curtx.is_xa_conn_error)
0617 {
0618 NDRX_LOG(log_warn, "RECON: Marking resource connection as OK");
0619 G_atmi_tls->G_atmi_xa_curtx.is_xa_conn_error = EXFALSE;
0620 }
0621
0622 NDRX_LOG(log_info, "XA interface open");
0623
0624 out:
0625 return ret;
0626 }
0627
0628
0629
0630
0631
0632
0633
0634 expublic int atmi_xa_close_entry(int for_retry)
0635 {
0636 int ret = EXSUCCEED;
0637 XA_API_ENTRY(EXTRUE);
0638
0639 NDRX_LOG(log_debug, "atmi_xa_close_entry");
0640
0641 if (!G_atmi_tls->G_atmi_xa_curtx.is_xa_open)
0642 {
0643 NDRX_LOG(log_warn, "xa_close_entry already called for context!");
0644 goto out;
0645 }
0646
0647
0648 if (for_retry)
0649 {
0650 NDRX_LOG(log_warn, "RECON: Marking resource connection as ERROR");
0651 G_atmi_tls->G_atmi_xa_curtx.is_xa_conn_error = EXTRUE;
0652 }
0653 else
0654 {
0655 G_atmi_tls->G_atmi_xa_curtx.is_xa_open = EXFALSE;
0656
0657 if (G_atmi_tls->G_atmi_xa_curtx.is_xa_conn_error)
0658 {
0659 NDRX_LOG(log_warn, "RECON: Resource connection was marked as ERROR. "
0660 "Normal close, clearing flag");
0661 G_atmi_tls->G_atmi_xa_curtx.is_xa_conn_error = EXFALSE;
0662 }
0663 }
0664
0665 if (XA_OK!=(ret = G_atmi_env.xa_sw->xa_close_entry(G_atmi_env.xa_close_str,
0666 G_atmi_env.xa_rmid, 0)))
0667 {
0668 NDRX_LOG(log_error, "atmi_xa_close_entry - fail: %d [%s]",
0669 ret, atmi_xa_geterrstr(ret));
0670
0671 if (!for_retry)
0672 {
0673
0674 ndrx_TPset_error_fmt_rsn(TPERMERR, ret, "atmi_xa_close_entry - fail: %d [%s]",
0675 ret, atmi_xa_geterrstr(ret));
0676 }
0677 goto out;
0678 }
0679
0680 out:
0681 return ret;
0682 }
0683
0684
0685
0686
0687
0688
0689
0690 exprivate int is_error_in_recon_list(char *list, int retcode)
0691 {
0692 char scanstr[16];
0693 char scanstr2[4] = ",*,";
0694 int ret = EXFALSE;
0695
0696 snprintf(scanstr, sizeof(scanstr), ",%d,", retcode);
0697
0698 NDRX_LOG(log_warn, "%s testing return code [%s] in recon list [%s]",
0699 __func__, scanstr, list);
0700
0701 if (NULL!=strstr(list, scanstr))
0702 {
0703 NDRX_LOG(log_warn, "matched by code - DO RETRY");
0704 ret = EXTRUE;
0705 goto out;
0706 }
0707 else if (NULL!=strstr(list, scanstr2))
0708 {
0709 NDRX_LOG(log_warn, "matched by wildcard - DO RETRY");
0710 ret = EXTRUE;
0711 goto out;
0712 }
0713
0714 out:
0715 return ret;
0716
0717 }
0718
0719
0720
0721
0722
0723
0724
0725 expublic int atmi_xa_start_entry(XID *xid, long flags, int silent_err)
0726 {
0727 int ret = EXSUCCEED;
0728 int need_retry;
0729 GENERIC_RETRY_DEF;
0730 XA_API_ENTRY(EXTRUE);
0731
0732 NDRX_LOG(log_debug, "%s", __func__);
0733
0734
0735 GENERIC_RETRY_ENTRY(EXFALSE);
0736
0737 if (XA_OK!=(ret = G_atmi_env.xa_sw->xa_start_entry(xid,
0738 G_atmi_env.xa_rmid, flags)))
0739 {
0740 if ((flags & TMJOIN || flags & TMRESUME) && XAER_NOTA==ret)
0741 {
0742 need_retry = EXFALSE;
0743 }
0744 else
0745 {
0746 need_retry = EXTRUE;
0747 }
0748
0749 if (!silent_err || need_retry)
0750 {
0751 NDRX_LOG(log_error, "%s - fail: %d [%s]",
0752 __func__, ret, atmi_xa_geterrstr(ret));
0753 }
0754
0755
0756 GENERIC_RETRY_CORE(
0757 (G_atmi_env.xa_sw->xa_start_entry(xid, G_atmi_env.xa_rmid, flags))
0758 , (need_retry && is_error_in_recon_list(G_atmi_env.xa_recon_retcodes, ret))
0759 , (XA_OK!=ret)
0760 , EXTRUE);
0761
0762 if (XA_OK!=ret)
0763 {
0764 if (silent_err && (XAER_NOTA==ret || XAER_DUPID==ret))
0765 {
0766
0767 ndrx_TPset_error_fmt_rsn_silent(TPERMERR,
0768 ret, "finally %s - fail: %d [%s]",
0769 __func__, ret, atmi_xa_geterrstr(ret));
0770 }
0771 else
0772 {
0773 NDRX_LOG(log_error, "finally %s - fail: %d [%s]",
0774 __func__, ret, atmi_xa_geterrstr(ret));
0775
0776 ndrx_TPset_error_fmt_rsn(TPERMERR,
0777 ret, "finally %s - fail: %d [%s]",
0778 __func__, ret, atmi_xa_geterrstr(ret));
0779 }
0780 goto out;
0781 }
0782 }
0783
0784 out:
0785 return ret;
0786 }
0787
0788
0789
0790
0791
0792
0793
0794
0795
0796
0797
0798 expublic int atmi_xa_end_entry(XID *xid, long flags, int aborting)
0799 {
0800 int ret = EXSUCCEED;
0801 char stat;
0802 UBFH *p_ub = NULL;
0803 int local_rb = EXFALSE;
0804 GENERIC_RETRY_DEF;
0805
0806 XA_API_ENTRY(EXTRUE);
0807
0808 NDRX_LOG(log_debug, "atmi_xa_end_entry flags %ld", flags);
0809
0810 GENERIC_RETRY_ENTRY(EXFALSE);
0811
0812
0813 if (XA_OK!=(ret = G_atmi_env.xa_sw->xa_end_entry(xid,
0814 G_atmi_env.xa_rmid, flags)))
0815 {
0816
0817 GENERIC_RETRY(
0818 (G_atmi_env.xa_sw->xa_end_entry(xid, G_atmi_env.xa_rmid, flags))
0819 , (is_error_in_recon_list(G_atmi_env.xa_recon_retcodes_other, ret))
0820 , (XA_OK!=ret)
0821 );
0822 }
0823
0824
0825
0826 if (G_atmi_env.xa_flags_sys & NDRX_XA_FLAG_SYS_NOSTARTXID)
0827 {
0828 NDRX_LOG(log_debug, "NOSTARTXID - preparing at end!");
0829 if (aborting && G_atmi_env.pf_xa_loctxabort)
0830 {
0831 NDRX_LOG(log_info, "Aborting using local rollback func");
0832 local_rb = EXTRUE;
0833 ret = G_atmi_env.pf_xa_loctxabort(xid, TMNOFLAGS);
0834
0835 if (XA_OK!=ret)
0836 {
0837 NDRX_LOG(log_error, "Failed to disconnect from transaction: %d", ret);
0838 userlog("Failed to disconnect from transaction: %d", ret);
0839 }
0840 }
0841
0842
0843
0844
0845
0846 else if (XA_OK!=(ret=atmi_xa_prepare_entry(xid, TMNOFLAGS)) && XA_RDONLY!=ret)
0847 {
0848 NDRX_LOG(log_error, "Failed to prepare transaction at NOSTARTXID end");
0849 goto out;
0850 }
0851
0852
0853 if ((XA_OK==ret || XA_RDONLY == ret) &&
0854 NDRX_SYSTEST_ENBLD && ndrx_systest_case(NDRX_SYSTEST_ENDPREPFAIL))
0855 {
0856 NDRX_LOG(log_error, "SYSTEST! Generating end-fail error");
0857 atmi_xa_rollback_entry(xid, 0L);
0858 ret = XAER_RMERR;
0859 }
0860
0861
0862
0863
0864
0865 if (local_rb)
0866 {
0867 stat = XA_RM_STATUS_ABORTED;
0868 }
0869 else if (XA_OK==ret)
0870 {
0871 stat = XA_RM_STATUS_PREP;
0872 }
0873 else if (XA_RDONLY==ret)
0874 {
0875 stat = XA_RM_STATUS_COMMITTED_RO;
0876 }
0877 else
0878 {
0879
0880 stat = XA_RM_STATUS_ABORTED;
0881 }
0882
0883
0884
0885
0886
0887
0888
0889
0890 NDRX_LOG(log_debug, "Reporting branch transaction status: %c", stat);
0891 p_ub = atmi_xa_call_tm_rmstatus(G_atmi_tls->G_atmi_xa_curtx.txinfo, stat);
0892
0893
0894 if (TPEMATCH==tperrno)
0895 {
0896 NDRX_LOG(log_error, "Got matching error! Abort transaction");
0897 atmi_xa_rollback_entry(xid, 0L);
0898 }
0899
0900 }
0901
0902
0903 out:
0904 if (NULL!=p_ub)
0905 {
0906 tpfree((char *)p_ub);
0907 }
0908
0909 return ret;
0910 }
0911
0912
0913
0914
0915
0916
0917
0918 expublic int atmi_xa_rollback_entry(XID *xid, long flags)
0919 {
0920 int ret = EXSUCCEED;
0921 GENERIC_RETRY_DEF;
0922 XA_API_ENTRY(EXTRUE);
0923
0924 NDRX_LOG(log_debug, "atmi_xa_rollback_entry");
0925
0926 GENERIC_RETRY_ENTRY(EXFALSE);
0927
0928 if (XA_OK!=(ret = G_atmi_env.xa_sw->xa_rollback_entry(xid,
0929 G_atmi_env.xa_rmid, flags)))
0930 {
0931
0932
0933
0934 GENERIC_RETRY(
0935 (G_atmi_env.xa_sw->xa_rollback_entry(xid, G_atmi_env.xa_rmid, flags))
0936 , (is_error_in_recon_list(G_atmi_env.xa_recon_retcodes_other, ret))
0937 , (XA_OK!=ret)
0938 );
0939 }
0940
0941 out:
0942 return ret;
0943 }
0944
0945
0946
0947
0948
0949
0950
0951 expublic int atmi_xa_prepare_entry(XID *xid, long flags)
0952 {
0953 int ret = EXSUCCEED;
0954 GENERIC_RETRY_DEF;
0955 XA_API_ENTRY(EXTRUE);
0956
0957 NDRX_LOG(log_debug, "atmi_xa_prepare_entry");
0958
0959 GENERIC_RETRY_ENTRY(EXFALSE);
0960
0961 if (XA_OK!=(ret = G_atmi_env.xa_sw->xa_prepare_entry(xid,
0962 G_atmi_env.xa_rmid, flags)))
0963 {
0964
0965 if (XA_RDONLY==ret)
0966 {
0967 NDRX_LOG(log_debug, "xa_prepare_entry - fail: %d [%s]",
0968 ret, atmi_xa_geterrstr(ret));
0969 ndrx_TPset_error_fmt_rsn(TPERMERR, ret, "xa_prepare_entry - fail: %d [%s]",
0970 ret, atmi_xa_geterrstr(ret));
0971 }
0972 else
0973 {
0974 GENERIC_RETRY(
0975 (G_atmi_env.xa_sw->xa_prepare_entry(xid, G_atmi_env.xa_rmid, flags))
0976 , (is_error_in_recon_list(G_atmi_env.xa_recon_retcodes_other, ret))
0977 , (XA_OK!=ret)
0978 );
0979
0980 }
0981
0982
0983 goto out;
0984 }
0985
0986 out:
0987 return ret;
0988 }
0989
0990
0991
0992
0993
0994
0995
0996 expublic int atmi_xa_forget_entry(XID *xid, long flags)
0997 {
0998 int ret = EXSUCCEED;
0999 GENERIC_RETRY_DEF;
1000 XA_API_ENTRY(EXTRUE);
1001
1002 NDRX_LOG(log_debug, "atmi_xa_forget_entry");
1003
1004 GENERIC_RETRY_ENTRY(EXFALSE);
1005
1006 if (XA_OK!=(ret = G_atmi_env.xa_sw->xa_forget_entry(xid,
1007 G_atmi_env.xa_rmid, flags)))
1008 {
1009
1010
1011
1012 GENERIC_RETRY(
1013 (G_atmi_env.xa_sw->xa_forget_entry(xid, G_atmi_env.xa_rmid, flags))
1014 , (is_error_in_recon_list(G_atmi_env.xa_recon_retcodes_other, ret))
1015 , (XA_OK!=ret)
1016 );
1017 }
1018
1019 out:
1020 return ret;
1021 }
1022
1023
1024
1025
1026
1027
1028
1029
1030 expublic int atmi_xa_commit_entry(XID *xid, long flags)
1031 {
1032 int ret = EXSUCCEED;
1033 GENERIC_RETRY_DEF;
1034 XA_API_ENTRY(EXTRUE);
1035
1036 GENERIC_RETRY_ENTRY(EXFALSE);
1037 NDRX_LOG(log_debug, "atmi_xa_commit_entry");
1038 if (XA_OK!=(ret = G_atmi_env.xa_sw->xa_commit_entry(xid,
1039 G_atmi_env.xa_rmid, flags)))
1040 {
1041 GENERIC_RETRY(
1042 (G_atmi_env.xa_sw->xa_commit_entry(xid,G_atmi_env.xa_rmid, flags))
1043 , (XAER_RMFAIL==ret)
1044 , (XA_OK!=ret));
1045 }
1046
1047 out:
1048 return ret;
1049 }
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059 expublic int atmi_xa_recover_entry(XID *xids, long count, int rmid, long flags)
1060 {
1061 int ret = EXSUCCEED;
1062 GENERIC_RETRY_DEF;
1063 XA_API_ENTRY(EXTRUE);
1064
1065 NDRX_LOG(log_debug, "%s", __func__);
1066
1067 GENERIC_RETRY_ENTRY(EXFALSE);
1068
1069 if (0 > (ret = G_atmi_env.xa_sw->xa_recover_entry(xids, count,
1070 G_atmi_env.xa_rmid, flags)))
1071 {
1072 GENERIC_RETRY(
1073 (G_atmi_env.xa_sw->xa_recover_entry(xids, count, G_atmi_env.xa_rmid, flags))
1074 , (is_error_in_recon_list(G_atmi_env.xa_recon_retcodes_other, ret))
1075 , (0 > ret)
1076 );
1077 }
1078
1079 out:
1080 return ret;
1081 }
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097 expublic int ndrx_tpbegin(unsigned long timeout, long flags)
1098 {
1099 int ret=EXSUCCEED;
1100 UBFH *p_ub = atmi_xa_alloc_tm_call(ATMI_XA_TPBEGIN);
1101 atmi_xa_tx_info_t xai;
1102 long tmflags = 0;
1103 GENERIC_RETRY_DEF;
1104 XA_API_ENTRY(EXTRUE);
1105
1106 NDRX_LOG(log_debug, "%s enter", __func__);
1107
1108 memset(&xai, 0, sizeof(atmi_xa_tx_info_t));
1109
1110
1111 if (!G_atmi_tls->G_atmi_xa_curtx.is_xa_open)
1112 {
1113 NDRX_LOG(log_error, "tpbegin: - tpopen() was not called!");
1114 ndrx_TPset_error_msg(TPEPROTO, "tpbegin - tpopen() was not called!");
1115 EXFAIL_OUT(ret);
1116 }
1117
1118 if (0!=flags)
1119 {
1120 NDRX_LOG(log_error, "tpbegin: flags != 0");
1121 ndrx_TPset_error_msg(TPEINVAL, "tpbegin: flags != 0");
1122 EXFAIL_OUT(ret);
1123 }
1124
1125
1126 if (G_atmi_tls->G_atmi_xa_curtx.txinfo)
1127 {
1128 NDRX_LOG(log_error, "tpbegin: - already in transaction mode XID: [%s]",
1129 G_atmi_tls->G_atmi_xa_curtx.txinfo->tmxid);
1130 ndrx_TPset_error_fmt(TPEPROTO, "tpbegin: - already in transaction mode XID: [%s]",
1131 G_atmi_tls->G_atmi_xa_curtx.txinfo->tmxid);
1132 EXFAIL_OUT(ret);
1133 }
1134
1135 NDRX_LOG(log_debug, "About to call TM");
1136
1137 if (EXSUCCEED!=Bchg(p_ub, TMTXTOUT, 0, (char *)&timeout, 0L))
1138 {
1139 ndrx_TPset_error_fmt(TPESYSTEM, "tpbegin: - failed to fill FB - set TMTXTOUT!");
1140 EXFAIL_OUT(ret);
1141 }
1142
1143 if (XA_IS_DYNAMIC_REG)
1144 {
1145
1146
1147
1148 tmflags|=TMFLAGS_DYNAMIC_REG;
1149 }
1150
1151 if (G_atmi_env.xa_flags_sys & NDRX_XA_FLAG_SYS_NOSTARTXID)
1152 {
1153 tmflags|=TMFLAGS_TPNOSTARTXID;
1154 }
1155
1156 if (EXSUCCEED!=Bchg(p_ub, TMTXFLAGS, 0, (char *)&tmflags, 0L))
1157 {
1158 ndrx_TPset_error_fmt(TPESYSTEM, "tpbegin: - failed to fill FB - set TMTXFLAGS!");
1159 EXFAIL_OUT(ret);
1160 }
1161
1162
1163 if (NULL==(p_ub=atmi_xa_call_tm_generic_fb(ATMI_XA_TPBEGIN, NULL, EXTRUE, EXFAIL,
1164 NULL, p_ub)))
1165 {
1166 NDRX_LOG(log_error, "Failed to execute TM command [%c]",
1167 ATMI_XA_TPBEGIN);
1168
1169 EXFAIL_OUT(ret);
1170 }
1171
1172
1173
1174
1175 if (EXSUCCEED!=atmi_xa_read_tx_info(p_ub, &xai, 0))
1176 {
1177 NDRX_LOG(log_error, "tpbegin: - failed to read TM response");
1178 ndrx_TPset_error_msg(TPEPROTO, "tpbegin: - failed to read TM response");
1179 EXFAIL_OUT(ret);
1180 }
1181
1182 NDRX_LOG(log_debug, "About to load tx info");
1183
1184
1185 if (EXSUCCEED!= atmi_xa_set_curtx_from_xai(&xai))
1186 {
1187 NDRX_LOG(log_error, "tpbegin: - failed to set curren tx");
1188 ndrx_TPset_error_msg(TPEPROTO, "tpbegin: - failed to set curren tx");
1189 EXFAIL_OUT(ret);
1190 }
1191
1192 G_atmi_tls->G_atmi_xa_curtx.txinfo->tranid_flags |= XA_TXINFO_INITIATOR;
1193
1194
1195 if (!XA_IS_DYNAMIC_REG)
1196 {
1197 if (EXSUCCEED!=atmi_xa_start_entry(atmi_xa_get_branch_xid(&xai, xai.btid),
1198 TMNOFLAGS, EXFALSE))
1199 {
1200
1201 NDRX_LOG(log_error, "Failed to join transaction!");
1202 ndrx_xa_join_fail(NULL, EXFALSE);
1203 atmi_xa_reset_curtx();
1204 EXFAIL_OUT(ret);
1205 }
1206
1207
1208
1209
1210 }
1211 else
1212 {
1213 NDRX_LOG(log_debug, "Working in dynamic mode...");
1214
1215 GENERIC_RETRY_ENTRY(EXTRUE);
1216 }
1217
1218 NDRX_LOG(log_debug, "Process joined to transaction [%s] OK",
1219 G_atmi_tls->G_atmi_xa_curtx.txinfo->tmxid);
1220
1221 out:
1222
1223
1224 if (NULL!=p_ub)
1225 {
1226
1227 atmi_error_t err;
1228
1229
1230 ndrx_TPsave_error(&err);
1231 tpfree((char *)p_ub);
1232 ndrx_TPrestore_error(&err);
1233 }
1234 return ret;
1235 }
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246 expublic int ndrx_tpscmt(long flags)
1247 {
1248 int ret = EXSUCCEED;
1249
1250 if (TP_CMT_LOGGED!=flags &&
1251 TP_CMT_COMPLETE!=flags)
1252 {
1253 NDRX_LOG(log_error, "Invalid value: commit return %ld", (long)flags);
1254 ndrx_TPset_error_fmt(TPEINVAL, "Invalid value: commit return %ld",
1255 (long)flags);
1256 EXFAIL_OUT(ret);
1257 }
1258
1259 if (TX_COMMIT_COMPLETED==G_atmi_tls->tx_commit_return)
1260 {
1261 ret = TP_CMT_COMPLETE;
1262 }
1263 else
1264 {
1265 ret = TP_CMT_LOGGED;
1266 }
1267
1268 if (TP_CMT_COMPLETE==flags)
1269 {
1270 G_atmi_tls->tx_commit_return = TX_COMMIT_COMPLETED;
1271 }
1272
1273 if (TP_CMT_LOGGED==flags)
1274 {
1275 G_atmi_tls->tx_commit_return = TX_COMMIT_DECISION_LOGGED;
1276 }
1277
1278 NDRX_LOG(log_info, "Commit return set to %ld (TX) ret %d",
1279 (long)G_atmi_tls->tx_commit_return, ret);
1280
1281 out:
1282 return ret;
1283 }
1284
1285
1286
1287
1288
1289
1290
1291
1292 expublic int ndrx_tpcommit(long flags)
1293 {
1294 int ret=EXSUCCEED;
1295 UBFH *p_ub = NULL;
1296 int do_abort = EXFALSE;
1297 XA_API_ENTRY(EXTRUE);
1298
1299 NDRX_LOG(log_debug, "%s enter", __func__);
1300
1301 if (!G_atmi_tls->G_atmi_xa_curtx.is_xa_open)
1302 {
1303 NDRX_LOG(log_error, "tpcommit: - tpopen() was not called!");
1304 ndrx_TPset_error_msg(TPEPROTO, "tpcommit - tpopen() was not called!");
1305 ret=EXFAIL;
1306 goto out_no_reset;
1307 }
1308
1309 if (0!=flags && !(flags & TPTXCOMMITDLOG))
1310 {
1311 NDRX_LOG(log_error, "tpcommit: flags != 0 && !TPTXCOMMITDLOG");
1312 ndrx_TPset_error_msg(TPEINVAL, "tpcommit: flags != 0 && !TPTXCOMMITDLOG");
1313 ret=EXFAIL;
1314 goto out_no_reset;
1315 }
1316
1317 if (!G_atmi_tls->G_atmi_xa_curtx.txinfo)
1318 {
1319 NDRX_LOG(log_error, "tpcommit: Not in global TX");
1320 ndrx_TPset_error_msg(TPEPROTO, "tpcommit: Not in global TX");
1321 ret=EXFAIL;
1322 goto out_no_reset;
1323
1324 }
1325
1326
1327
1328
1329 if (!G_atmi_tls->G_atmi_xa_curtx.txinfo->tranid_flags)
1330 {
1331 NDRX_LOG(log_error, "tpcommit: Not not initiator");
1332 ndrx_TPset_error_msg(TPEPROTO, "tpcommit: Not not initiator");
1333 ret=EXFAIL;
1334 goto out_no_reset;
1335 }
1336
1337
1338 if (TX_COMMIT_DECISION_LOGGED == G_atmi_tls->tx_commit_return)
1339 {
1340 flags|=TPTXCOMMITDLOG;
1341 }
1342
1343
1344 if (atmi_xa_cd_isanyreg(&(G_atmi_tls->G_atmi_xa_curtx.txinfo->call_cds)))
1345 {
1346 NDRX_LOG(log_error, "tpcommit: Open call descriptors found - abort!");
1347 do_abort = EXTRUE;
1348 }
1349
1350 if (atmi_xa_cd_isanyreg(&(G_atmi_tls->G_atmi_xa_curtx.txinfo->conv_cds)))
1351 {
1352 NDRX_LOG(log_error, "tpcommit: Open conversation descriptors found - abort!");
1353 do_abort = EXTRUE;
1354 }
1355
1356 if (G_atmi_tls->G_atmi_xa_curtx.txinfo->tmtxflags & TMTXFLAGS_IS_ABORT_ONLY)
1357 {
1358 NDRX_LOG(log_error, "tpcommit: Transaction marked as abort only!");
1359 do_abort = EXTRUE;
1360 }
1361
1362
1363
1364
1365
1366
1367 if (!XA_IS_DYNAMIC_REG ||
1368 (XA_TXINFO_AXREG_CLD & G_atmi_tls->G_atmi_xa_curtx.txinfo->tranid_flags))
1369 {
1370 if (EXSUCCEED!= (ret=atmi_xa_end_entry(atmi_xa_get_branch_xid(G_atmi_tls->G_atmi_xa_curtx.txinfo,
1371 G_atmi_tls->G_atmi_xa_curtx.txinfo->btid), TMSUCCESS, EXFALSE)))
1372 {
1373 NDRX_LOG(log_error, "Failed to end XA api: %d [%s] - aborting",
1374 ret, atmi_xa_geterrstr(ret));
1375 userlog("Failed to end XA api: %d [%s] - aborting",
1376 ret, atmi_xa_geterrstr(ret));
1377
1378 do_abort = EXTRUE;
1379 }
1380 }
1381
1382 if (do_abort)
1383 {
1384
1385 ret = ndrx_tpabort(0, EXFALSE);
1386
1387
1388
1389
1390 if (EXSUCCEED==ret || TPEPROTO==tperrno)
1391 {
1392
1393 ndrx_TPunset_error();
1394 ndrx_TPset_error_msg(TPEABORT, "tpcommit: Transaction was marked for "
1395 "abort and aborted now!");
1396 ret=EXFAIL;
1397 }
1398
1399 return ret;
1400 }
1401
1402 NDRX_LOG(log_debug, "About to call TM flags=%ld", flags);
1403
1404
1405
1406 if (NULL==(p_ub=atmi_xa_call_tm_generic(ATMI_XA_TPCOMMIT, EXFALSE, EXFAIL,
1407 G_atmi_tls->G_atmi_xa_curtx.txinfo, flags, EXFAIL)))
1408 {
1409 NDRX_LOG(log_error, "Failed to execute TM command [%c]",
1410 ATMI_XA_TPCOMMIT);
1411
1412
1413
1414 EXFAIL_OUT(ret);
1415 }
1416
1417 NDRX_LOG(log_debug, "Transaction [%s] commit OK",
1418 G_atmi_tls->G_atmi_xa_curtx.txinfo->tmxid);
1419
1420 out:
1421
1422
1423 atmi_xa_reset_curtx();
1424
1425 out_no_reset:
1426
1427 if (NULL!=p_ub)
1428 {
1429
1430 atmi_error_t err;
1431
1432
1433 ndrx_TPsave_error(&err);
1434 tpfree((char *)p_ub);
1435 ndrx_TPrestore_error(&err);
1436 }
1437
1438
1439 return ret;
1440 }
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450 expublic int ndrx_tpabort(long flags, int call_xa_end)
1451 {
1452 int ret=EXSUCCEED;
1453 UBFH *p_ub = NULL;
1454 XA_API_ENTRY(EXTRUE);
1455
1456 NDRX_LOG(log_debug, "_tpabort enter");
1457
1458 if (!G_atmi_tls->G_atmi_xa_curtx.is_xa_open)
1459 {
1460 NDRX_LOG(log_error, "tpabort: - tpopen() was not called!");
1461 ndrx_TPset_error_msg(TPEPROTO, "tpabort - tpopen() was not called!");
1462 ret=EXFAIL;
1463 goto out_no_reset;
1464 }
1465
1466 if (0!=flags)
1467 {
1468 NDRX_LOG(log_error, "tpabort: flags != 0");
1469 ndrx_TPset_error_msg(TPEINVAL, "tpabort: flags != 0");
1470 ret=EXFAIL;
1471 goto out_no_reset;
1472 }
1473
1474 if (!G_atmi_tls->G_atmi_xa_curtx.txinfo)
1475 {
1476 NDRX_LOG(log_error, "tpabort: Not in global TX");
1477 ndrx_TPset_error_msg(TPEPROTO, "tpabort: Not in global TX");
1478 ret=EXFAIL;
1479 goto out_no_reset;
1480 }
1481
1482 if (!(XA_TXINFO_INITIATOR & G_atmi_tls->G_atmi_xa_curtx.txinfo->tranid_flags))
1483 {
1484 NDRX_LOG(log_error, "tpabort: Not not initiator");
1485 ndrx_TPset_error_msg(TPEPROTO, "tpabort: Not not initiator");
1486 ret=EXFAIL;
1487 goto out_no_reset;
1488 }
1489
1490
1491 if (call_xa_end)
1492 {
1493 if (!XA_IS_DYNAMIC_REG ||
1494 (XA_TXINFO_AXREG_CLD & G_atmi_tls->G_atmi_xa_curtx.txinfo->tranid_flags))
1495 {
1496
1497 if (EXSUCCEED!= atmi_xa_end_entry(
1498 atmi_xa_get_branch_xid(G_atmi_tls->G_atmi_xa_curtx.txinfo,
1499 G_atmi_tls->G_atmi_xa_curtx.txinfo->btid), TMSUCCESS, EXTRUE))
1500 {
1501 NDRX_LOG(log_error, "Failed to end XA api: %d [%s]",
1502 ret, atmi_xa_geterrstr(ret));
1503 userlog("Failed to end XA api: %d [%s]",
1504 ret, atmi_xa_geterrstr(ret));
1505 }
1506 }
1507 }
1508
1509 NDRX_LOG(log_debug, "About to call TM");
1510
1511 if (NULL==(p_ub=atmi_xa_call_tm_generic(ATMI_XA_TPABORT, EXFALSE, EXFAIL,
1512 G_atmi_tls->G_atmi_xa_curtx.txinfo, 0L, EXFAIL)))
1513 {
1514 NDRX_LOG(log_error, "Failed to execute TM command [%c]",
1515 ATMI_XA_TPBEGIN);
1516
1517
1518
1519 EXFAIL_OUT(ret);
1520 }
1521
1522 NDRX_LOG(log_debug, "Transaction [%s] abort OK",
1523 G_atmi_tls->G_atmi_xa_curtx.txinfo->tmxid);
1524 out:
1525
1526 atmi_xa_reset_curtx();
1527
1528 out_no_reset:
1529
1530 if (NULL!=p_ub)
1531 {
1532
1533 atmi_error_t err;
1534
1535
1536 ndrx_TPsave_error(&err);
1537 tpfree((char *)p_ub);
1538 ndrx_TPrestore_error(&err);
1539 }
1540
1541 return ret;
1542 }
1543
1544
1545
1546
1547
1548 expublic int ndrx_tpopen(void)
1549 {
1550 int ret=EXSUCCEED;
1551 XA_API_ENTRY(EXTRUE);
1552
1553 ret = atmi_xa_open_entry();
1554
1555 out:
1556 return ret;
1557 }
1558
1559
1560
1561
1562
1563 expublic int ndrx_tpclose(void)
1564 {
1565 int ret=EXSUCCEED;
1566
1567 XA_API_ENTRY(EXTRUE);
1568
1569 if (G_atmi_tls->G_atmi_xa_curtx.txinfo)
1570 {
1571 NDRX_LOG(log_error, "tpclose: - cannot close as process in TX: [%s]",
1572 G_atmi_tls->G_atmi_xa_curtx.txinfo->tmxid);
1573 ndrx_TPset_error_fmt(TPEPROTO, "tpclose: - cannot close as process in TX: [%s]",
1574 G_atmi_tls->G_atmi_xa_curtx.txinfo->tmxid);
1575 EXFAIL_OUT(ret);
1576 }
1577
1578 ret = atmi_xa_close_entry(EXFALSE);
1579
1580 out:
1581 return ret;
1582 }
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598 expublic int ndrx_tpsuspend (TPTRANID *tranid, long flags, int is_contexting)
1599 {
1600 int ret=EXSUCCEED;
1601 long xa_flags = TMSUCCESS;
1602
1603 XA_API_ENTRY(EXTRUE);
1604 NDRX_LOG(log_info, "Suspending global transaction: atmi flags %lx", flags);
1605 if (NULL==tranid)
1606 {
1607 ndrx_TPset_error_msg(TPEINVAL, "_tpsuspend: trandid = NULL!");
1608 EXFAIL_OUT(ret);
1609 }
1610
1611 if (0!= (flags & ~TPTXTMSUSPEND) )
1612 {
1613 ndrx_TPset_error_msg(TPEINVAL, "_tpsuspend: flags is not 0, nor TPTXTMSUSPEND");
1614 EXFAIL_OUT(ret);
1615 }
1616
1617 if (!G_atmi_tls->G_atmi_xa_curtx.txinfo)
1618 {
1619 NDRX_LOG(log_error, "_tpsuspend: Not in global TX");
1620 ndrx_TPset_error_msg(TPEPROTO, "_tpsuspend: Not in global TX");
1621 EXFAIL_OUT(ret);
1622 }
1623
1624
1625
1626
1627
1628 if ( (flags & TPTXTMSUSPEND) && !(G_atmi_env.xa_flags_sys & NDRX_XA_FLAG_SYS_NOJOIN))
1629 {
1630 xa_flags = TMSUSPEND;
1631 }
1632
1633 #if 0
1634 - I guess this is not a problem. Must be able to suspend abort only transaction
1635 because of object-api
1636 if (G_atmi_tls->G_atmi_xa_curtx.txinfo->tmtxflags & TMTXFLAGS_IS_ABORT_ONLY)
1637 {
1638 NDRX_LOG(log_error, "_tpsuspend: Abort only transaction!");
1639 ndrx_TPset_error_msg(TPEPROTO, "_tpsuspend: Abort only transaction!");
1640 EXFAIL_OUT(ret);
1641 }
1642 #endif
1643
1644
1645 if (!is_contexting
1646 && atmi_xa_cd_isanyreg(&(G_atmi_tls->G_atmi_xa_curtx.txinfo->call_cds)))
1647 {
1648 NDRX_LOG(log_error, "_tpsuspend: Call descriptors still open!");
1649 ndrx_TPset_error_msg(TPEPROTO, "_tpsuspend: Call descriptors still open!");
1650 EXFAIL_OUT(ret);
1651 }
1652
1653 if (!is_contexting
1654 && atmi_xa_cd_isanyreg(&(G_atmi_tls->G_atmi_xa_curtx.txinfo->conv_cds)))
1655 {
1656 NDRX_LOG(log_error, "_tpsuspend: Conversation descriptors still open!");
1657 ndrx_TPset_error_msg(TPEPROTO, "_tpsuspend: Conversation descriptors still open!");
1658 EXFAIL_OUT(ret);
1659 }
1660
1661
1662
1663 XA_TX_COPY(tranid, G_atmi_tls->G_atmi_xa_curtx.txinfo);
1664 tranid->is_tx_initiator = G_atmi_tls->G_atmi_xa_curtx.txinfo->tranid_flags;
1665
1666
1667
1668
1669
1670
1671
1672
1673 if (!XA_IS_DYNAMIC_REG ||
1674 (XA_TXINFO_AXREG_CLD & G_atmi_tls->G_atmi_xa_curtx.txinfo->tranid_flags))
1675 {
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687 if (EXSUCCEED!= (ret=atmi_xa_end_entry(
1688 atmi_xa_get_branch_xid(G_atmi_tls->G_atmi_xa_curtx.txinfo,
1689 G_atmi_tls->G_atmi_xa_curtx.txinfo->btid), xa_flags, EXFALSE)))
1690 {
1691 int did_abort = EXFALSE;
1692 NDRX_LOG(log_error, "Failed to end XA api: %d [%s] flags: %lx",
1693 ret, atmi_xa_geterrstr(ret), xa_flags);
1694 userlog("Failed to end XA api: %d [%s] flags: %lx",
1695 ret, atmi_xa_geterrstr(ret), xa_flags);
1696
1697
1698 ndrx_xa_join_fail(&did_abort, EXFALSE);
1699
1700 if (did_abort)
1701 {
1702 ndrx_TPoverride_code(TPEABORT);
1703 }
1704 else
1705 {
1706 ndrx_TPoverride_code(TPESYSTEM);
1707 }
1708
1709 goto out;
1710 }
1711 }
1712
1713 atmi_xa_reset_curtx();
1714
1715 NDRX_LOG(log_debug, "Suspend ok xid: [%s] xa flags: %lx",
1716 tranid->tmxid, xa_flags);
1717 out:
1718
1719 return ret;
1720 }
1721
1722
1723
1724
1725
1726
1727
1728 expublic int ndrx_tpresume (TPTRANID *tranid, long flags)
1729 {
1730 int ret=EXSUCCEED;
1731 int was_join = EXFALSE;
1732 long join_flag = TMJOIN;
1733 atmi_xa_tx_info_t xai;
1734
1735 XA_API_ENTRY(EXTRUE);
1736 NDRX_LOG(log_info, "Resuming global transaction...");
1737
1738 if (NULL==tranid)
1739 {
1740 ndrx_TPset_error_msg(TPEINVAL, "_tpresume: trandid = NULL!");
1741 EXFAIL_OUT(ret);
1742 }
1743
1744 if (0!= (flags & ~ (TPTXNOOPTIM | TPTXTMSUSPEND)) )
1745 {
1746 ndrx_TPset_error_msg(TPEINVAL, "_tpresume: flags is not 0, "
1747 "nor TPTXNOOPTIM, nor TPTXTMSUSPEND");
1748 EXFAIL_OUT(ret);
1749 }
1750
1751
1752
1753
1754
1755
1756 if ( (flags & TPTXTMSUSPEND)
1757 && !(G_atmi_env.xa_flags_sys & NDRX_XA_FLAG_SYS_NOJOIN))
1758 {
1759 join_flag = TMRESUME;
1760 }
1761
1762
1763 if (G_atmi_tls->G_atmi_xa_curtx.txinfo)
1764 {
1765 ndrx_TPset_error_msg(TPEPROTO, "_tpresume: Already in global TX!");
1766 EXFAIL_OUT(ret);
1767 }
1768
1769
1770 XA_TX_COPY((&xai), tranid);
1771
1772
1773 if (flags & TPTXNOOPTIM)
1774 {
1775 xai.tmknownrms[0]=EXEOS;
1776 }
1777
1778 if (EXSUCCEED!=_tp_srv_join_or_new(&xai, EXFALSE, &was_join, join_flag,
1779 tranid->is_tx_initiator))
1780 {
1781 ndrx_TPset_error_msg(TPESYSTEM, "_tpresume: Failed to enter in global TX!");
1782 EXFAIL_OUT(ret);
1783 }
1784
1785 NDRX_LOG(log_debug, "Resume ok xid: [%s] is_tx_initiator: %d abort_only: %d",
1786 tranid->tmxid, tranid->is_tx_initiator,
1787 G_atmi_tls->G_atmi_xa_curtx.txinfo->tmtxflags & TMTXFLAGS_IS_ABORT_ONLY);
1788
1789 out:
1790 return ret;
1791 }
1792
1793
1794
1795
1796
1797
1798
1799
1800 expublic int ax_reg(int rmid, XID *xid, long flags)
1801 {
1802 int ret = TM_OK;
1803 int was_join = EXFALSE;
1804 ATMI_TLS_ENTRY;
1805
1806 NDRX_LOG(log_info, "ax_reg called");
1807 if (NULL==G_atmi_tls->G_atmi_xa_curtx.txinfo)
1808 {
1809 NDRX_LOG(log_error, "ERROR: No global transaction registered "
1810 "with process/thread!");
1811 userlog("ERROR: No global transaction registered with process/thread!");
1812 memset(xid, 0, sizeof(XID));
1813 ret = TMER_TMERR;
1814 goto out;
1815 }
1816
1817 if (EXSUCCEED!=_tp_srv_join_or_new(G_atmi_tls->G_atmi_xa_curtx.txinfo,
1818 EXTRUE, &was_join, TMJOIN, G_atmi_tls->G_atmi_xa_curtx.txinfo->tranid_flags))
1819 {
1820 ret = TMER_TMERR;
1821 goto out;
1822 }
1823
1824 if (was_join)
1825 {
1826 ret = TM_JOIN;
1827 }
1828
1829 memcpy(xid, atmi_xa_get_branch_xid(G_atmi_tls->G_atmi_xa_curtx.txinfo,
1830 G_atmi_tls->G_atmi_xa_curtx.txinfo->btid), sizeof(*xid));
1831
1832
1833
1834
1835
1836 out:
1837 NDRX_LOG(log_info, "ax_reg returns: %d", ret);
1838 return ret;
1839 }
1840
1841
1842
1843
1844
1845
1846
1847 int ax_unreg(int rmid, long flags)
1848 {
1849 NDRX_LOG(log_info, "ax_unreg called");
1850 return EXSUCCEED;
1851 }
1852
1853
1854
1855
1856
1857
1858 expublic int _tp_srv_join_or_new_from_call(tp_command_call_t *call,
1859 int is_ax_reg_callback)
1860 {
1861 int is_known = EXFALSE;
1862 atmi_xa_tx_info_t xai;
1863 memset(&xai, 0, sizeof(xai));
1864
1865
1866
1867
1868 XA_TX_COPY((&xai), call)
1869
1870 return _tp_srv_join_or_new(&xai, is_ax_reg_callback, &is_known, TMJOIN,
1871 XA_TXINFO_NOFLAGS);
1872 }
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885 exprivate int ndrx_xa_join_fail(int *did_abort, int force_abort)
1886 {
1887 UBFH *p_ub = NULL;
1888 int ret = EXSUCCEED;
1889
1890 atmi_error_t err;
1891
1892
1893
1894
1895 if (!(G_atmi_tls->G_atmi_xa_curtx.txinfo->tranid_flags & XA_TXINFO_INITIATOR) &&
1896 !force_abort)
1897 {
1898 return EXSUCCEED;
1899 }
1900
1901
1902 ndrx_TPsave_error(&err);
1903
1904 NDRX_LOG(log_error, "xa_start() or xa_end() failed, aborting to TMSRV");
1905
1906 if (NULL==(p_ub=atmi_xa_call_tm_generic(ATMI_XA_TPABORT, EXFALSE, EXFAIL,
1907 G_atmi_tls->G_atmi_xa_curtx.txinfo, 0L, EXFAIL)))
1908 {
1909 NDRX_LOG(log_error, "Failed to execute TM command [%c]",
1910 ATMI_XA_TPABORT);
1911
1912
1913
1914 EXFAIL_OUT(ret);
1915 }
1916
1917 if (NULL!=did_abort)
1918 {
1919 *did_abort = EXTRUE;
1920 }
1921
1922 out:
1923 if (NULL!=p_ub)
1924 {
1925 tpfree((char *)p_ub);
1926
1927 }
1928 ndrx_TPrestore_error(&err);
1929
1930 return ret;
1931 }
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941 expublic int _tp_srv_join_or_new(atmi_xa_tx_info_t *p_xai,
1942 int is_ax_reg_callback, int *p_is_known, long join_flag, int tranid_flags)
1943 {
1944 int ret = EXSUCCEED;
1945 UBFH *p_ub = NULL;
1946 short reason;
1947 int new_rm = EXFALSE;
1948 char src_tmknownrms[2];
1949 long tmflags = 0;
1950 GENERIC_RETRY_DEF;
1951
1952 XA_API_ENTRY(EXTRUE);
1953
1954
1955
1956
1957
1958 if (!(XA_IS_DYNAMIC_REG) || (tranid_flags & XA_TXINFO_AXREG_CLD))
1959 {
1960
1961 if (EXSUCCEED!=atmi_xa_set_curtx_from_xai(p_xai))
1962 {
1963 EXFAIL_OUT(ret);
1964 }
1965
1966
1967 G_atmi_tls->G_atmi_xa_curtx.txinfo->tranid_flags = tranid_flags;
1968 }
1969 else
1970 {
1971
1972
1973
1974
1975
1976 if (!is_ax_reg_callback)
1977 {
1978 NDRX_LOG(log_debug, "Dynamic reg + process start "
1979 "just remember the transaction");
1980
1981
1982 GENERIC_RETRY_ENTRY(EXTRUE);
1983
1984
1985
1986
1987 if (EXSUCCEED!=atmi_xa_set_curtx_from_xai(p_xai))
1988 {
1989 EXFAIL_OUT(ret);
1990 }
1991
1992
1993 G_atmi_tls->G_atmi_xa_curtx.txinfo->tranid_flags = tranid_flags;
1994
1995
1996 GENERIC_RETRY_ENTRY(EXTRUE);
1997
1998
1999 goto out;
2000 }
2001 else
2002 {
2003
2004
2005
2006
2007
2008
2009 NDRX_LOG(log_debug, "Dynamic reg work started");
2010 p_xai->tranid_flags|=XA_TXINFO_AXREG_CLD;
2011 }
2012 }
2013
2014 if (!(G_atmi_env.xa_flags_sys & NDRX_XA_FLAG_SYS_NOJOIN) &&
2015 atmi_xa_is_current_rm_known(p_xai->tmknownrms))
2016 {
2017 *p_is_known=EXTRUE;
2018
2019
2020 G_atmi_tls->G_atmi_xa_curtx.txinfo->btid = 0;
2021
2022
2023 if (XA_IS_DYNAMIC_REG && !(join_flag & TMRESUME))
2024 {
2025 NDRX_LOG(log_debug, "Dynamic reg - no start/join!");
2026 }
2027
2028 else if (EXSUCCEED!=atmi_xa_start_entry(atmi_xa_get_branch_xid(p_xai,
2029 G_atmi_tls->G_atmi_xa_curtx.txinfo->btid),
2030 join_flag, EXFALSE))
2031 {
2032 NDRX_LOG(log_error, "Failed to join transaction!");
2033 ndrx_xa_join_fail(NULL, EXFALSE);
2034 EXFAIL_OUT(ret);
2035 }
2036 else
2037 {
2038 NDRX_LOG(log_debug, "tx join ok!");
2039 }
2040 }
2041 else
2042 {
2043 long btid = EXFAIL;
2044 NDRX_LOG(log_info, "RM not aware of this transaction");
2045
2046
2047
2048
2049 if (!(G_atmi_env.xa_flags_sys & NDRX_XA_FLAG_SYS_NOJOIN))
2050 {
2051 btid = 0;
2052 }
2053
2054 if (G_atmi_env.xa_flags_sys & NDRX_XA_FLAG_SYS_NOSTARTXID)
2055 {
2056 tmflags|=TMFLAGS_TPNOSTARTXID;
2057 }
2058
2059
2060
2061 if (NULL==(p_ub=atmi_xa_call_tm_generic(ATMI_XA_TMREGISTER,
2062 EXFALSE, EXFAIL, p_xai, tmflags, btid)))
2063 {
2064 NDRX_LOG(log_error, "Failed to execute TM command [%c]",
2065 ATMI_XA_TMREGISTER);
2066 EXFAIL_OUT(ret);
2067 }
2068
2069 if (EXSUCCEED!=Bget(p_ub, TMTXFLAGS, 0, (char *)&tmflags, 0L))
2070 {
2071 NDRX_LOG(log_error, "Failed to read TMTXFLAGS!");
2072
2073 EXFAIL_OUT(ret);
2074 }
2075
2076 if (tmflags & TMFLAGS_RMIDKNOWN)
2077 {
2078 *p_is_known = EXTRUE;
2079 }
2080 else
2081 {
2082 if (EXSUCCEED!=Bget(p_ub, TMTXBTID, 0, (char *)&btid, 0L))
2083 {
2084 NDRX_LOG(log_error, "Failed to read TMTXBTID!");
2085
2086 EXFAIL_OUT(ret);
2087 }
2088 }
2089
2090 G_atmi_tls->G_atmi_xa_curtx.txinfo->btid = btid;
2091
2092 if (XA_IS_DYNAMIC_REG)
2093 {
2094
2095 NDRX_LOG(log_debug, "Dynamic reg - no new tx start!");
2096 }
2097
2098 else if (*p_is_known)
2099 {
2100 if (EXSUCCEED!=atmi_xa_start_entry(atmi_xa_get_branch_xid(p_xai, btid),
2101 join_flag, EXFALSE))
2102 {
2103 NDRX_LOG(log_error, "Failed to join transaction!");
2104 ndrx_xa_join_fail(NULL, EXFALSE);
2105 EXFAIL_OUT(ret);
2106 }
2107 else
2108 {
2109 NDRX_LOG(log_debug, "tx join ok!");
2110 }
2111 }
2112
2113 else if (EXSUCCEED!=atmi_xa_start_entry(atmi_xa_get_branch_xid(p_xai, btid),
2114 TMNOFLAGS, EXTRUE))
2115 {
2116 reason=atmi_xa_get_reason();
2117 NDRX_LOG(log_error, "Failed to create new tx under local RM (reason: %hd): %s!",
2118 reason, atmi_xa_geterrstr(reason));
2119 if (XAER_DUPID == (reason=atmi_xa_get_reason()))
2120 {
2121
2122 *p_is_known=EXTRUE;
2123
2124 if (EXSUCCEED!=atmi_xa_start_entry(atmi_xa_get_branch_xid(p_xai, btid),
2125 join_flag, EXFALSE))
2126 {
2127 NDRX_LOG(log_error, "Failed to join transaction!");
2128 ndrx_xa_join_fail(NULL, EXFALSE);
2129 EXFAIL_OUT(ret);
2130 }
2131 else
2132 {
2133 NDRX_LOG(log_debug, "tx join ok!");
2134 }
2135 }
2136 else
2137 {
2138 NDRX_LOG(log_error, "Failed to start transaction!");
2139 ndrx_xa_join_fail(NULL, EXFALSE);
2140 EXFAIL_OUT(ret);
2141 }
2142 }
2143 new_rm = EXTRUE;
2144 }
2145
2146
2147 if (!(G_atmi_env.xa_flags_sys & NDRX_XA_FLAG_SYS_NOJOIN) && new_rm)
2148 {
2149 src_tmknownrms[0] = G_atmi_env.xa_rmid;
2150 src_tmknownrms[1] = EXEOS;
2151
2152 if (EXSUCCEED!=atmi_xa_update_known_rms(
2153 G_atmi_tls->G_atmi_xa_curtx.txinfo->tmknownrms,
2154 src_tmknownrms))
2155 {
2156 EXFAIL_OUT(ret);
2157 }
2158 }
2159
2160 out:
2161
2162 if (EXSUCCEED!=ret)
2163 {
2164
2165 atmi_xa_reset_curtx();
2166 }
2167
2168 if (NULL!=p_ub)
2169 {
2170 tpfree((char *)p_ub);
2171 }
2172
2173 return ret;
2174 }
2175
2176
2177
2178
2179
2180
2181
2182
2183 expublic int _tp_srv_disassoc_tx(int force_rollback, int *end_fail)
2184 {
2185 int ret = EXSUCCEED;
2186 ATMI_TLS_ENTRY;
2187
2188
2189 NDRX_LOG(log_debug, "into %s() force_rollback=%d", __func__, force_rollback);
2190 if (NULL==G_atmi_tls->G_atmi_xa_curtx.txinfo)
2191 {
2192 NDRX_LOG(log_warn, "Not in global tx!");
2193 goto out;
2194 }
2195
2196
2197 if ( !XA_IS_DYNAMIC_REG ||
2198 (XA_TXINFO_AXREG_CLD & G_atmi_tls->G_atmi_xa_curtx.txinfo->tranid_flags))
2199 {
2200 if (EXSUCCEED!= (ret=atmi_xa_end_entry(
2201 atmi_xa_get_branch_xid(G_atmi_tls->G_atmi_xa_curtx.txinfo,
2202 G_atmi_tls->G_atmi_xa_curtx.txinfo->btid), TMSUCCESS, EXFALSE)))
2203 {
2204 NDRX_LOG(log_error, "Failed to end XA api: %d [%s]",
2205 ret, atmi_xa_geterrstr(ret));
2206 userlog("Failed to end XA api: %d [%s]",
2207 ret, atmi_xa_geterrstr(ret));
2208
2209 *end_fail = EXTRUE;
2210 }
2211 }
2212
2213
2214 if (force_rollback)
2215 {
2216 ndrx_xa_join_fail(NULL, EXTRUE);
2217 }
2218
2219
2220 atmi_xa_curtx_del(G_atmi_tls->G_atmi_xa_curtx.txinfo);
2221 G_atmi_tls->G_atmi_xa_curtx.txinfo = NULL;
2222
2223 out:
2224 return ret;
2225 }
2226
2227
2228
2229
2230
2231
2232 expublic int _tp_srv_tell_tx_fail(void)
2233 {
2234 int ret = EXSUCCEED;
2235
2236
2237
2238 out:
2239 return ret;
2240 }
2241
2242
2243
2244
2245
2246 expublic void ndrx_xa_noapisusp(int val)
2247 {
2248 if (val)
2249 {
2250 NDRX_LOG(log_debug, "No Context tran suspend");
2251 G_atmi_env.xa_flags_sys|=NDRX_XA_FLAG_SYS_NOAPISUSP;
2252 }
2253 else
2254 {
2255 G_atmi_env.xa_flags_sys=G_atmi_env.xa_flags_sys & ~NDRX_XA_FLAG_SYS_NOAPISUSP;
2256 }
2257 }
2258
2259
2260
2261
2262
2263
2264 expublic void ndrx_xa_nojoin(int val)
2265 {
2266 if (val)
2267 {
2268 NDRX_LOG(log_debug, "XA No JOIN");
2269 G_atmi_env.xa_flags_sys|=NDRX_XA_FLAG_SYS_NOJOIN;
2270 }
2271 else
2272 {
2273 G_atmi_env.xa_flags_sys=G_atmi_env.xa_flags_sys & ~NDRX_XA_FLAG_SYS_NOJOIN;
2274 }
2275 }
2276
2277
2278
2279
2280
2281
2282
2283 expublic void ndrx_xa_nosuspend(int val)
2284 {
2285 if (val)
2286 {
2287 NDRX_LOG(log_debug, "XA No Automatic suspend");
2288 G_atmi_env.xa_flags_sys|=NDRX_XA_FLAG_SYS_NOSUSPEND;
2289 }
2290 else
2291 {
2292 G_atmi_env.xa_flags_sys=G_atmi_env.xa_flags_sys & ~NDRX_XA_FLAG_SYS_NOSUSPEND;
2293 }
2294 }
2295
2296
2297
2298
2299
2300
2301
2302
2303 expublic void ndrx_xa_nostartxid(int val)
2304 {
2305 if (val)
2306 {
2307 NDRX_LOG(log_debug, "XA No STAR XID");
2308 G_atmi_env.xa_flags_sys|=NDRX_XA_FLAG_SYS_NOSTARTXID;
2309 }
2310 else
2311 {
2312 G_atmi_env.xa_flags_sys=G_atmi_env.xa_flags_sys & ~NDRX_XA_FLAG_SYS_NOSTARTXID;
2313 }
2314 }
2315
2316
2317
2318
2319
2320
2321 expublic void ndrx_xa_setloctxabort(int (*pf_xa_loctxabort)(XID *xid, long flags))
2322 {
2323 G_atmi_env.pf_xa_loctxabort = pf_xa_loctxabort;
2324 NDRX_LOG(log_debug, "xa_loctxabort set to %p", G_atmi_env.pf_xa_loctxabort);
2325 }
2326
2327
2328
2329
2330
2331
2332
2333 expublic void ndrx_xa_setgetconnn(void *(*pf_xa_getconn)(void))
2334 {
2335 G_atmi_env.pf_getconn= pf_xa_getconn;
2336 NDRX_LOG(log_debug, "pf_getconn set to %p", G_atmi_env.pf_getconn);
2337 }
2338
2339
2340
2341
2342
2343 expublic void ndrx_xa_btight(int val)
2344 {
2345 if (val)
2346 {
2347 NDRX_LOG(log_debug, "XA BTIGHT");
2348 G_atmi_env.xa_flags_sys|=NDRX_XA_FLAG_SYS_BTIGHT;
2349 }
2350 else
2351 {
2352 G_atmi_env.xa_flags_sys=G_atmi_env.xa_flags_sys & ~NDRX_XA_FLAG_SYS_BTIGHT;
2353 }
2354 }
2355
2356
2357
2358
2359
2360 expublic struct xa_switch_t* ndrx_xa_sw_get(void)
2361 {
2362 return G_atmi_env.xa_sw;
2363 }
2364
2365