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 <stdlib.h>
0041 #include <stdio.h>
0042 #include <errno.h>
0043 #include <string.h>
0044 #include <ndrstandard.h>
0045 #include <atmi.h>
0046 #include <atmi_tls.h>
0047 #include <typed_buf.h>
0048
0049 #include "thlock.h"
0050 #include "userlog.h"
0051 #include "utlist.h"
0052 #include "exregex.h"
0053 #include <exparson.h>
0054 #include <atmi_cache.h>
0055 #include <Exfields.h>
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070 exprivate int ndrx_cache_chkrsprule(ndrx_tpcallcache_t *cache,
0071 long save_tperrno, long save_tpurcode)
0072 {
0073 int ret = EXFALSE;
0074 char buf[512];
0075 UBFH *p_ub = (UBFH *)buf;
0076
0077 if (EXSUCCEED!=Binit(p_ub, sizeof(buf)))
0078 {
0079 NDRX_CACHE_TPERROR(TPESYSTEM, "cache: failed to init response check buffer: %s",
0080 Bstrerror(Berror));
0081 EXFAIL_OUT(ret);
0082 }
0083
0084
0085
0086 if (EXSUCCEED!=Bchg(p_ub, EX_TPERRNO, 0, (char *)&save_tperrno, 0L))
0087 {
0088 NDRX_CACHE_TPERROR(TPESYSTEM, "cache: Failed to set EX_TPERRNO[0] to %ld: %s",
0089 save_tperrno, Bstrerror(Berror));
0090 EXFAIL_OUT(ret);
0091 }
0092
0093 if (EXSUCCEED!=Bchg(p_ub, EX_TPURCODE, 0, (char *)&save_tpurcode, 0L))
0094 {
0095 NDRX_CACHE_TPERROR(TPESYSTEM, "cache: Failed to set EX_TPURCODE[0] to %ld: %s",
0096 save_tpurcode, Bstrerror(Berror));
0097 EXFAIL_OUT(ret);
0098 }
0099
0100
0101
0102 if (EXFAIL==(ret=Bboolev(p_ub, cache->rsprule_tree)))
0103 {
0104 NDRX_CACHE_TPERROR(TPESYSTEM, "cache: Failed to evalute [%s] "
0105 "tree: %p expression: %s",
0106 cache->rsprule, cache->rsprule_tree, Bstrerror(Berror));
0107 EXFAIL_OUT(ret);
0108 }
0109
0110 NDRX_LOG(log_debug, "Response expression [%s]: %s", cache->rsprule,
0111 (EXTRUE==ret?"TRUE":"FALSE"));
0112
0113 out:
0114
0115 return ret;
0116
0117 }
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132 expublic int ndrx_cache_save (char *svc, char *idata,
0133 long ilen, int save_tperrno, long save_tpurcode, int nodeid, long flags,
0134 int tusec, long t, int is_event)
0135 {
0136 int ret = EXSUCCEED;
0137
0138 char *buf=NULL;
0139 size_t buf_len;
0140 ndrx_tpcache_svc_t *svcc = NULL;
0141 typed_buffer_descr_t *buf_type;
0142 buffer_obj_t *buffer_info;
0143 ndrx_tpcallcache_t *cache;
0144 ndrx_tpcache_data_t *exdata;
0145 int tran_started = EXFALSE;
0146 EDB_txn *txn;
0147 char key[NDRX_CACHE_KEY_MAX+1];
0148 char errdet[MAX_TP_ERROR_LEN+1];
0149 EDB_val cachedata;
0150 int is_matched=EXFALSE;
0151
0152 NDRX_SYSBUF_MALLOC_WERR_OUT(buf, buf_len, ret);
0153 exdata = (ndrx_tpcache_data_t *)buf;
0154
0155 memset(exdata, 0, sizeof(ndrx_tpcache_data_t));
0156
0157 exdata->magic = NDRX_CACHE_MAGIC;
0158 NDRX_STRCPY_SAFE(exdata->svcnm, svc);
0159 exdata->nodeid = nodeid;
0160 exdata->saved_tperrno = save_tperrno;
0161 exdata->saved_tpurcode = save_tpurcode;
0162
0163
0164 if (EXFAIL==t)
0165 {
0166 ndrx_utc_tstamp2(&exdata->t, &exdata->tusec);
0167 }
0168 else
0169 {
0170 exdata->t = t;
0171 exdata->tusec = (long)tusec;
0172 }
0173
0174 #ifdef NDRX_TPCACHE_DEBUG
0175 NDRX_LOG(log_debug, "Cache time: t=%ld tusec=%ld",
0176 exdata->t, exdata->tusec);
0177 #endif
0178
0179
0180
0181
0182 EXHASH_FIND_STR(ndrx_G_tpcache_svc, svc, svcc);
0183
0184 if (NULL==svcc)
0185 {
0186 #ifdef NDRX_TPCACHE_DEBUG
0187 NDRX_LOG(log_debug, "No cache defined for [%s]", svc);
0188 #endif
0189 ret = NDRX_TPCACHE_ENOCACHE;
0190 goto out;
0191 }
0192
0193 if (NULL==(buffer_info = ndrx_find_buffer(idata)))
0194 {
0195 ndrx_TPset_error_fmt(TPEINVAL, "%s: Buffer %p not known to system!",
0196 __func__, idata);
0197 EXFAIL_OUT(ret);
0198 }
0199
0200 buf_type = &G_buf_descr[buffer_info->type_id];
0201
0202 DL_FOREACH(svcc->caches, cache)
0203 {
0204 is_matched = EXFALSE;
0205
0206 if (cache->buf_type->type_id == buf_type->type_id)
0207 {
0208 if (ndrx_G_tpcache_types[cache->buf_type->type_id].pf_rule_eval)
0209 {
0210 ret = ndrx_G_tpcache_types[cache->buf_type->type_id].pf_rule_eval(
0211 cache, idata, ilen, errdet, sizeof(errdet));
0212 if (EXFAIL==ret)
0213 {
0214 NDRX_CACHE_TPERROR(TPEINVAL, "%s: Failed to evaluate buffer [%s]: %s",
0215 __func__, cache->rule, errdet);
0216
0217 EXFAIL_OUT(ret);
0218 }
0219 else if (EXFALSE==ret)
0220 {
0221 #ifdef NDRX_TPCACHE_DEBUG
0222 NDRX_LOG(log_debug, "Buffer RULE FALSE [%s] - continue", cache->rule);
0223 #endif
0224 continue;
0225 }
0226
0227 is_matched = EXTRUE;
0228 ret = EXSUCCEED;
0229 }
0230 else
0231 {
0232
0233 NDRX_CACHE_TPERROR(TPEINVAL,"%s: Unsupported buffer type [%s] for cache",
0234 __func__, cache->buf_type->type);
0235 EXFAIL_OUT(ret);
0236 }
0237 }
0238
0239
0240
0241
0242
0243 NDRX_STRCPY_SAFE(key, cache->keyfmt);
0244
0245
0246 if (EXSUCCEED!=(ret = ndrx_G_tpcache_types[buffer_info->type_id].pf_get_key(
0247 cache, idata, ilen, key, sizeof(key), errdet, sizeof(errdet))))
0248 {
0249 if (NDRX_TPCACHE_ENOKEYDATA==ret)
0250 {
0251 NDRX_LOG(log_debug, "Failed to build key (no data for key): %s", errdet);
0252 goto out;
0253 }
0254 else
0255 {
0256 NDRX_CACHE_TPERRORNOU(TPESYSTEM, "%s: Failed to build cache key: %s",
0257 __func__, errdet);
0258 goto out;
0259 }
0260 }
0261
0262 if (cache->flags & NDRX_TPCACHE_TPCF_INVAL)
0263 {
0264
0265 if (EXSUCCEED!=ndrx_cache_inval_their(svc, cache, key, idata, ilen))
0266 {
0267 NDRX_LOG(log_error, "Failed to invalidate their cache!");
0268 }
0269
0270 is_matched=EXFALSE;
0271 }
0272
0273 if (cache->flags & NDRX_TPCACHE_TPCF_NEXT)
0274 {
0275 #ifdef NDRX_TPCACHE_DEBUG
0276 NDRX_LOG(log_debug, "Next flag present, go to next cache (if have one)");
0277 #endif
0278 is_matched=EXFALSE;
0279 continue;
0280 }
0281 else
0282 {
0283 break;
0284 }
0285 }
0286
0287
0288 if (!is_matched)
0289 {
0290
0291 #ifdef NDRX_TPCACHE_DEBUG
0292 NDRX_LOG(log_debug, "No cache defined for [%s], buffer type [%s] "
0293 "or all was invalidate", svc, buf_type->type);
0294 #endif
0295 ret = NDRX_TPCACHE_ENOCACHE;
0296 goto out;
0297 }
0298
0299 exdata->flags = cache->flags;
0300 exdata->cache_idx = cache->idx;
0301 exdata->atmi_type_id = buffer_info->type_id;
0302 exdata->atmi_buf_len = NDRX_MSGSIZEMAX - sizeof(ndrx_tpcache_data_t);
0303
0304 if (NULL==ndrx_G_tpcache_types[cache->buf_type->type_id].pf_cache_put)
0305 {
0306 ret = NDRX_TPCACHE_ENOTYPESUPP;
0307 goto out;
0308
0309 }
0310
0311
0312
0313 if (NULL!=cache->rsprule_tree)
0314 {
0315 if (EXFAIL==(ret=ndrx_cache_chkrsprule(cache, (long)save_tperrno,
0316 save_tpurcode)))
0317 {
0318 NDRX_LOG(log_error, "Failed to test response code");
0319 EXFAIL_OUT(ret);
0320 }
0321
0322 if (EXFALSE==ret)
0323 {
0324 NDRX_LOG(log_info, "Response shall not be saved according to rsp rule");
0325 ret = EXSUCCEED;
0326 goto out;
0327 }
0328
0329 ret = EXSUCCEED;
0330 }
0331 else if (0!=save_tperrno)
0332 {
0333 NDRX_LOG(log_info, "Not storing error responses (by default)");
0334 ret = EXSUCCEED;
0335 goto out;
0336 }
0337
0338 if (EXSUCCEED!=ndrx_G_tpcache_types[cache->buf_type->type_id].pf_cache_put(
0339 cache, exdata, buf_type, idata, ilen, flags))
0340 {
0341
0342 NDRX_LOG(log_error, "Failed to convert to cache format!!!");
0343 EXFAIL_OUT(ret);
0344
0345 }
0346
0347 NDRX_LOG(log_info, "About to cache data for service: [%s]", svc);
0348
0349
0350 NDRX_STRCPY_SAFE(key, cache->keyfmt);
0351
0352
0353 if (EXSUCCEED!=(ret = ndrx_G_tpcache_types[buffer_info->type_id].pf_get_key(cache, idata,
0354 ilen, key, sizeof(key), errdet, sizeof(errdet))))
0355 {
0356 if (NDRX_TPCACHE_ENOKEYDATA==ret)
0357 {
0358 NDRX_LOG(log_debug, "Failed to build key (no data for key): %s", errdet);
0359 goto out;
0360 }
0361 else
0362 {
0363 NDRX_LOG(log_error, "Failed to build key: ", errdet);
0364
0365
0366 ndrx_TPset_error_fmt(TPESYSTEM, "%s: Failed to build cache key: %s",
0367 __func__, errdet);
0368 goto out;
0369 }
0370
0371 }
0372
0373 if (EXSUCCEED!=(ret=ndrx_cache_edb_begin(cache->cachedb, &txn, 0)))
0374 {
0375 NDRX_LOG(log_error, "%s: failed to start tran", __func__);
0376 goto out;
0377 }
0378 tran_started = EXTRUE;
0379
0380
0381
0382 if (cache->flags & NDRX_TPCACHE_TPCF_KEYITEMS)
0383 {
0384 if (EXSUCCEED!=(ret=ndrx_cache_keygrp_addupd(cache, idata, ilen,
0385 key, NULL, EXFALSE, txn)))
0386 {
0387 NDRX_LOG(log_error, "Failed to add keygroup record!");
0388 goto out;
0389 }
0390 }
0391
0392
0393
0394 #if 0
0395 if (cache->cachedb->flags & NDRX_TPCACHE_FLAGS_TIMESYNC)
0396 {
0397 dbflags = EDB_APPENDDUP;
0398 }
0399 else
0400 {
0401 dbflags = 0;
0402 }
0403 #endif
0404
0405 cachedata.mv_data = (void *)exdata;
0406 cachedata.mv_size = exdata->atmi_buf_len + sizeof(ndrx_tpcache_data_t);
0407
0408
0409 NDRX_LOG(log_info, "About to put to cache: svc: [%s] key: [%s]: size: %ld",
0410 svcc->svcnm, key, (long)cachedata.mv_size);
0411
0412 if (EXSUCCEED!=(ret=ndrx_cache_edb_put (cache->cachedb, txn,
0413 key, &cachedata, 0, EXFALSE)))
0414 {
0415 NDRX_LOG(log_debug, "Failed to put DB record!");
0416 goto out;
0417 }
0418
0419 NDRX_LOG(log_debug, "Data cached, key [%s]", key);
0420
0421 if ((cache->cachedb->flags & NDRX_TPCACHE_FLAGS_BCASTPUT)
0422 && !is_event)
0423 {
0424 if (EXSUCCEED!=ndrx_cache_broadcast(cache, svc, idata, ilen,
0425 NDRX_CACHE_BCAST_MODE_PUT, NDRX_TPCACHE_BCAST_DFLT,
0426 (int)exdata->tusec, (long)exdata->t,
0427 save_tperrno, save_tpurcode))
0428 {
0429 NDRX_LOG(log_error, "WARNING ! Failed to broadcast put event - continue");
0430 }
0431 }
0432
0433 out:
0434
0435 if (tran_started)
0436 {
0437
0438 if (EXSUCCEED==ret || NDRX_TPCACHE_ENOCACHE==ret)
0439 {
0440 ndrx_cache_edb_commit(cache->cachedb, txn);
0441 }
0442 else
0443 {
0444 ndrx_cache_edb_abort(cache->cachedb, txn);
0445 }
0446 }
0447
0448 if (NULL!=buf)
0449 {
0450 NDRX_SYSBUF_FREE(buf);
0451 }
0452
0453 return ret;
0454 }
0455
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470 expublic int ndrx_cache_lookup(char *svc, char *idata, long ilen,
0471 char **odata, long *olen, long flags, int *should_cache,
0472 int *saved_tperrno, long *saved_tpurcode, int seterror_not_found,
0473 int noenterr)
0474 {
0475 int ret = EXSUCCEED;
0476 ndrx_tpcache_svc_t *svcc = NULL;
0477 typed_buffer_descr_t *buf_type;
0478 buffer_obj_t *buffer_info;
0479 ndrx_tpcallcache_t *cache;
0480 char key[NDRX_CACHE_KEY_MAX+1];
0481 char errdet[MAX_TP_ERROR_LEN+1];
0482 EDB_txn *txn;
0483 int cursor_open = EXFALSE;
0484 EDB_cursor *cursor;
0485 int tran_started = EXFALSE;
0486 EDB_val cachedata;
0487 EDB_val cachedata_update;
0488 EDB_val cachedata_delete;
0489 ndrx_tpcache_data_t *exdata;
0490 ndrx_tpcache_data_t *exdata_update;
0491 int is_matched;
0492 int align;
0493 char *defer_free = NULL;
0494 unsigned int flagsdb;
0495 int force_abort = EXFALSE;
0496
0497
0498 cachedata_update.mv_size = 0;
0499 cachedata_update.mv_data = NULL;
0500
0501
0502 EXHASH_FIND_STR(ndrx_G_tpcache_svc, svc, svcc);
0503
0504 if (NULL==svcc)
0505 {
0506 #ifdef NDRX_TPCACHE_DEBUG
0507 NDRX_LOG(log_debug, "No cache defined for [%s]", svc);
0508 #endif
0509 ret = NDRX_TPCACHE_ENOCACHE;
0510 goto out;
0511 }
0512
0513 if (NULL==(buffer_info = ndrx_find_buffer(idata)))
0514 {
0515 ndrx_TPset_error_fmt(TPEINVAL, "%s: Buffer %p not known to system!",
0516 __func__, idata);
0517 EXFAIL_OUT(ret);
0518 }
0519
0520
0521
0522
0523 buf_type = &G_buf_descr[buffer_info->type_id];
0524
0525 DL_FOREACH(svcc->caches, cache)
0526 {
0527 is_matched = EXFALSE;
0528
0529 if (cache->buf_type->type_id == buf_type->type_id)
0530 {
0531 if (ndrx_G_tpcache_types[cache->buf_type->type_id].pf_rule_eval)
0532 {
0533 ret = ndrx_G_tpcache_types[cache->buf_type->type_id].pf_rule_eval(
0534 cache, idata, ilen, errdet, sizeof(errdet));
0535 if (EXFAIL==ret)
0536 {
0537 NDRX_CACHE_TPERROR(TPEINVAL, "%s: Failed to evaluate buffer [%s]: %s",
0538 __func__, cache->rule, errdet);
0539
0540 EXFAIL_OUT(ret);
0541 }
0542 else if (EXFALSE==ret)
0543 {
0544 #ifdef NDRX_TPCACHE_DEBUG
0545 NDRX_LOG(log_debug, "Buffer RULE FALSE [%s] - try next",
0546 cache->rule);
0547 #endif
0548 continue;
0549 }
0550
0551 NDRX_LOG(log_debug, "rule [%s] matched", cache->rule);
0552 is_matched = EXTRUE;
0553
0554
0555
0556
0557 *should_cache=EXTRUE;
0558
0559 ret = EXSUCCEED;
0560 }
0561 else
0562 {
0563
0564 NDRX_CACHE_TPERROR(TPEINVAL,"%s: Unsupported buffer type [%s] for cache",
0565 __func__, cache->buf_type->type);
0566 EXFAIL_OUT(ret);
0567 }
0568 }
0569
0570
0571
0572 if (!(cache->flags & NDRX_TPCACHE_TPCF_INVAL))
0573 {
0574
0575 if (NULL!=ndrx_G_tpcache_types[cache->buf_type->type_id].pf_refreshrule_eval &&
0576 EXEOS!=cache->refreshrule[0])
0577 {
0578 ret = ndrx_G_tpcache_types[cache->buf_type->type_id].pf_refreshrule_eval(cache,
0579 idata, ilen, errdet, sizeof(errdet));
0580 if (EXFAIL==ret)
0581 {
0582
0583 NDRX_LOG(log_error, "Failed to eval refresh rule: %s", errdet);
0584
0585 ndrx_TPset_error_fmt(TPESYSTEM, "Failed to eval refresh rule: %s",
0586 errdet);
0587 EXFAIL_OUT(ret);
0588 }
0589 else if (EXTRUE==ret)
0590 {
0591 NDRX_LOG(log_info, "Cache will be refreshed - rule matched "
0592 "(do not continue cache lookup)");
0593 *should_cache=EXTRUE;
0594 ret = NDRX_TPCACHE_ENOCACHEDATA;
0595 goto out;
0596 }
0597 }
0598 }
0599
0600
0601
0602
0603
0604 NDRX_STRCPY_SAFE(key, cache->keyfmt);
0605
0606
0607 if (EXSUCCEED!=(ret = ndrx_G_tpcache_types[buffer_info->type_id].pf_get_key(
0608 cache, idata, ilen, key, sizeof(key), errdet, sizeof(errdet))))
0609 {
0610 if (NDRX_TPCACHE_ENOKEYDATA==ret)
0611 {
0612 NDRX_LOG(log_debug, "Failed to build key (no data for key): %s", errdet);
0613 goto out;
0614 }
0615 else
0616 {
0617 NDRX_LOG(log_error, "Failed to build key: ", errdet);
0618
0619
0620 ndrx_TPset_error_fmt(TPESYSTEM, "%s: Failed to build cache key: %s",
0621 __func__, errdet);
0622 goto out;
0623 }
0624 }
0625
0626 if (cache->flags & NDRX_TPCACHE_TPCF_NEXT)
0627 {
0628 #ifdef NDRX_TPCACHE_DEBUG
0629 NDRX_LOG(log_debug, "Next flag present, go to next cache (if have one)");
0630 #endif
0631 is_matched=EXFALSE;
0632 continue;
0633 }
0634 else
0635 {
0636 break;
0637 }
0638
0639 }
0640
0641
0642 if (!is_matched)
0643 {
0644
0645 #ifdef NDRX_TPCACHE_DEBUG
0646 NDRX_LOG(log_debug, "No cache defined for [%s], buffer type [%s] ",
0647 svc, buf_type->type);
0648 #endif
0649 ret = NDRX_TPCACHE_ENOCACHE;
0650 goto out;
0651 }
0652
0653
0654
0655 *should_cache=EXTRUE;
0656
0657 if (cache->flags & NDRX_TPCACHE_TPCF_INVAL)
0658 {
0659 NDRX_LOG(log_info, "Last was invalidate cache -> let save process to inval!");
0660 ret = NDRX_TPCACHE_ENOCACHEDATA;
0661 goto out;
0662 }
0663
0664 if (flags & TPNOCACHEDDATA)
0665 {
0666
0667
0668 NDRX_LOG(log_info, "No cache data -> request lookup for key [%s]", key);
0669
0670 ret = NDRX_TPCACHE_ENOCACHEDATA;
0671 goto out;
0672 }
0673
0674
0675 if (cache->flags & NDRX_TPCACHE_TPCF_KEYITEMS)
0676 {
0677 if (EXSUCCEED!=(ret = ndrx_cache_keygrp_lookup(cache, idata, ilen,
0678 odata, olen, key, flags)))
0679 {
0680
0681
0682 switch (ret)
0683 {
0684 case NDRX_TPCACHE_ENOCACHEDATA:
0685
0686 goto out;
0687 break;
0688 case NDRX_TPCACHE_ENOTFOUNDLIM:
0689 *saved_tperrno = cache->keygroupmtperrno;
0690 *saved_tpurcode = cache->keygroupmtpurcode;
0691
0692
0693 NDRX_LOG(log_debug, "MAX keygroup reject tperrno: %d "
0694 "tpurcode: %ld", *saved_tperrno, *saved_tpurcode);
0695
0696 ret=EXSUCCEED;
0697 goto out;
0698
0699 break;
0700 default:
0701 goto out;
0702 break;
0703 }
0704 }
0705 }
0706
0707
0708
0709
0710
0711 if ( (cache->cachedb->flags & NDRX_TPCACHE_FLAGS_TIMESYNC) ||
0712 (cache->cachedb->flags & NDRX_TPCACHE_FLAGS_LRU) ||
0713 (cache->cachedb->flags & NDRX_TPCACHE_FLAGS_HITS))
0714 {
0715 flagsdb = 0;
0716 }
0717 else
0718 {
0719 flagsdb = EDB_RDONLY;
0720 }
0721
0722 if (EXSUCCEED!=(ret=ndrx_cache_edb_begin(cache->cachedb, &txn, flagsdb)))
0723 {
0724 NDRX_LOG(log_error, "%s: failed to start tran", __func__);
0725 goto out;
0726 }
0727 tran_started = EXTRUE;
0728
0729 if (cache->cachedb->flags & NDRX_TPCACHE_FLAGS_TIMESYNC)
0730 {
0731 #ifdef NDRX_TPCACHE_DEBUG
0732 NDRX_LOG(log_debug, "Performing timesync based complex lookup");
0733 #endif
0734
0735 if (EXSUCCEED!=ndrx_cache_edb_cursor_open(cache->cachedb, txn, &cursor))
0736 {
0737 NDRX_LOG(log_error, "Failed to open cursor!");
0738 EXFAIL_OUT(ret);
0739 }
0740
0741
0742
0743
0744 if (EXSUCCEED!=(ret=ndrx_cache_edb_cursor_get(cache->cachedb, cursor,
0745 key, &cachedata, EDB_SET_KEY, &align)))
0746 {
0747 if (EDB_NOTFOUND!=ret)
0748 {
0749 NDRX_LOG(log_error, "Failed to scan for data!");
0750 EXFAIL_OUT(ret);
0751 }
0752
0753 ret = NDRX_TPCACHE_ENOCACHEDATA;
0754 goto out;
0755 }
0756
0757 }
0758 else
0759 {
0760 #ifdef NDRX_TPCACHE_DEBUG
0761 NDRX_LOG(log_debug, "Performing simple lookup");
0762 #endif
0763 if (EXSUCCEED!=(ret=ndrx_cache_edb_get(cache->cachedb, txn, key, &cachedata,
0764 seterror_not_found, &align)))
0765 {
0766
0767 NDRX_LOG(log_debug, "%s: failed to get cache by [%s]", __func__, key);
0768 goto out;
0769 }
0770 }
0771
0772 if (align)
0773 {
0774 defer_free = cachedata.mv_data;
0775 }
0776
0777 exdata = (ndrx_tpcache_data_t *) cachedata.mv_data;
0778
0779
0780
0781 NDRX_CACHE_CHECK_DBDATA((&cachedata), exdata, key, TPMINVAL);
0782
0783
0784 #ifdef NDRX_TPCACHE_DEBUG
0785 NDRX_LOG(log_debug, "Got cache record for key [%s] of service [%s]", key, svc);
0786
0787 NDRX_DUMP(6, "Got cache data", (char *)cachedata.mv_data,
0788 (int)cachedata.mv_size);
0789 NDRX_TPCACHETPCALL_DBDATA(log_debug, exdata);
0790 #endif
0791
0792
0793
0794
0795 if (noenterr && !(cache->flags & NDRX_TPCACHE_TPCF_NOSVCOK))
0796 {
0797 ndrx_TPset_error_fmt(TPENOENT, "%s: Data found in cache but nosvcok no present",
0798 __func__, svc);
0799 *should_cache = EXFALSE;
0800 EXFAIL_OUT(ret);
0801 }
0802
0803 if (EXSUCCEED!=ndrx_G_tpcache_types[buffer_info->type_id].pf_cache_get(
0804 cache, exdata, buf_type, idata, ilen, odata, olen, flags))
0805 {
0806 NDRX_LOG(log_error, "%s: Failed to receive data: ", __func__);
0807 EXFAIL_OUT(ret);
0808 }
0809
0810 *saved_tperrno = exdata->saved_tperrno;
0811 *saved_tpurcode = exdata->saved_tpurcode;
0812
0813 NDRX_LOG(log_debug, "cache tperrno: %d tpurcode: %ld",
0814 *saved_tperrno, *saved_tpurcode);
0815
0816
0817
0818
0819
0820 if ((cache->cachedb->flags & NDRX_TPCACHE_FLAGS_LRU) ||
0821 (cache->cachedb->flags & NDRX_TPCACHE_FLAGS_HITS))
0822 {
0823 cachedata_update.mv_size = cachedata.mv_size;
0824 cachedata_update.mv_data = NDRX_MALLOC(cachedata.mv_size);
0825
0826 if (NULL==cachedata_update.mv_data)
0827 {
0828 int err = errno;
0829
0830 NDRX_CACHE_TPERROR(TPEOS, "Failed to allocate %ld bytes: %s",
0831 (long)cachedata_update.mv_size, strerror(err));
0832 }
0833
0834 memcpy(cachedata_update.mv_data, cachedata.mv_data, cachedata.mv_size);
0835
0836 exdata_update = (ndrx_tpcache_data_t *)cachedata_update.mv_data;
0837
0838
0839
0840
0841
0842
0843
0844 if (exdata_update->hits < LONG_MAX - 1)
0845 {
0846 exdata_update->hits++;
0847 }
0848 else
0849 {
0850
0851 exdata_update->hits = LONG_MAX;
0852 }
0853
0854 ndrx_utc_tstamp2(&exdata_update->hit_t, &exdata_update->hit_tusec);
0855
0856 #ifdef NDRX_TPCACHE_DEBUG
0857 NDRX_LOG(log_debug, "hits=%ld t=%ld t=%ld", exdata_update->hits,
0858 exdata_update->hit_t, exdata_update->hit_tusec);
0859 #endif
0860 if (cursor_open)
0861 {
0862 edb_cursor_close(cursor);
0863 }
0864 cursor_open=EXFALSE;
0865
0866
0867
0868
0869 if (EXSUCCEED!=(ret=ndrx_cache_edb_del (cache->cachedb, txn,
0870 key, NULL)))
0871 {
0872 if (EDB_NOTFOUND==ret)
0873 {
0874 ret=EXSUCCEED;
0875 }
0876 else
0877 {
0878 EXFAIL_OUT(ret);
0879 }
0880 }
0881
0882
0883
0884
0885 #if 0
0886 if (cache->cachedb->flags & NDRX_TPCACHE_FLAGS_TIMESYNC)
0887 {
0888 dbflags = EDB_APPENDDUP;
0889 }
0890 else
0891 {
0892 dbflags = 0;
0893 }
0894 #endif
0895 if (EXSUCCEED!=ndrx_cache_edb_put (cache->cachedb, txn,
0896 key, &cachedata_update, 0, EXTRUE))
0897 {
0898 NDRX_LOG(log_debug, "Failed to put/update DB record - ignore error");
0899 force_abort = EXTRUE;
0900 goto out;
0901 }
0902 }
0903 else if (cache->cachedb->flags & NDRX_TPCACHE_FLAGS_TIMESYNC)
0904 {
0905
0906
0907 align = 0;
0908 while (EXSUCCEED==(ret=ndrx_cache_edb_cursor_get(cache->cachedb, cursor,
0909 key, &cachedata_delete, EDB_NEXT_DUP, &align)))
0910 {
0911
0912 NDRX_DUMP(log_debug, "Deleting duplicate record...",
0913 cachedata_delete.mv_data, cachedata_delete.mv_size);
0914
0915 if (EXSUCCEED!=(ret=ndrx_cache_edb_del (cache->cachedb, txn,
0916 key, &cachedata_delete)))
0917 {
0918 if (ret!=EDB_NOTFOUND)
0919 {
0920
0921 break;
0922 }
0923 }
0924
0925 if (align)
0926 {
0927 NDRX_FREE(cachedata_delete.mv_data);
0928 cachedata_delete.mv_data = NULL;
0929 }
0930 }
0931
0932 if (align && NULL!=cachedata_delete.mv_data)
0933 {
0934 NDRX_FREE(cachedata_delete.mv_data);
0935 }
0936
0937 if (ret!=EDB_NOTFOUND)
0938 {
0939 EXFAIL_OUT(ret);
0940 }
0941 else
0942 {
0943 ret = EXSUCCEED;
0944 }
0945 }
0946
0947 out:
0948
0949 if (NULL!=cachedata_update.mv_data)
0950 {
0951 NDRX_FREE(cachedata_update.mv_data);
0952 }
0953
0954 if (cursor_open)
0955 {
0956 edb_cursor_close(cursor);
0957 }
0958
0959 if (tran_started)
0960 {
0961 if (EXSUCCEED==ret && !force_abort)
0962 {
0963 ndrx_cache_edb_commit(cache->cachedb, txn);
0964 }
0965 else
0966 {
0967 ndrx_cache_edb_abort(cache->cachedb, txn);
0968 }
0969 }
0970
0971 if (defer_free)
0972 {
0973 NDRX_FREE(defer_free);
0974 }
0975
0976 return ret;
0977 }
0978
0979