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 #include <ndrx_config.h>
0042 #include <string.h>
0043 #include <stdio.h>
0044 #include <stdlib.h>
0045 #include <memory.h>
0046 #include <errno.h>
0047
0048
0049 #include <sys/mman.h>
0050 #include <sys/types.h>
0051
0052 #include <unistd.h>
0053 #include <fcntl.h>
0054 #include <sys/stat.h>
0055
0056 #include <ndrx_config.h>
0057 #include <ndrstandard.h>
0058 #include <sys_unix.h>
0059 #include <atmi.h>
0060 #include <atmi_shm.h>
0061 #include <atmi_tls.h>
0062 #include <ndebug.h>
0063 #include <ndrx_ddr.h>
0064 #include <ndrxdcmn.h>
0065 #include <userlog.h>
0066 #include <exatomic.h>
0067
0068
0069
0070
0071
0072
0073 expublic ndrx_shm_t G_srvinfo;
0074 expublic ndrx_shm_t G_svcinfo;
0075 expublic ndrx_shm_t G_brinfo;
0076
0077 expublic ndrx_shm_t ndrx_G_routcrit;
0078 expublic ndrx_shm_t ndrx_G_routsvc;
0079
0080 expublic int G_max_servers = EXFAIL;
0081 expublic int G_max_svcs = EXFAIL;
0082
0083 int M_init = EXFALSE;
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096 expublic int ndrx_shm_init(char *q_prefix, int max_servers, int max_svcs,
0097 int rtcrtmax, int rtsvcmax)
0098 {
0099 memset(&G_srvinfo, 0, sizeof(G_srvinfo));
0100 memset(&G_svcinfo, 0, sizeof(G_svcinfo));
0101 memset(&G_brinfo, 0, sizeof(G_brinfo));
0102
0103 memset(&ndrx_G_routcrit, 0, sizeof(G_brinfo));
0104 memset(&ndrx_G_routsvc, 0, sizeof(G_brinfo));
0105
0106 G_svcinfo.fd = EXFAIL;
0107 G_svcinfo.key = G_atmi_env.ipckey + NDRX_SHM_SVCINFO_KEYOFSZ;
0108
0109 G_srvinfo.fd = EXFAIL;
0110 G_srvinfo.key = G_atmi_env.ipckey + NDRX_SHM_SRVINFO_KEYOFSZ;
0111
0112 G_brinfo.fd = EXFAIL;
0113 G_brinfo.key = G_atmi_env.ipckey + NDRX_SHM_BRINFO_KEYOFSZ;
0114
0115 ndrx_G_routcrit.fd = EXFAIL;
0116 ndrx_G_routcrit.key = G_atmi_env.ipckey + NDRX_SHM_ROUTCRIT_KEYOFSZ;
0117
0118
0119 ndrx_G_routsvc.fd = EXFAIL;
0120 ndrx_G_routsvc.key = G_atmi_env.ipckey + NDRX_SHM_ROUTSVC_KEYOFSZ;
0121
0122
0123 snprintf(G_srvinfo.path, sizeof(G_srvinfo.path), NDRX_SHM_SRVINFO, q_prefix);
0124 snprintf(G_svcinfo.path, sizeof(G_svcinfo.path), NDRX_SHM_SVCINFO, q_prefix);
0125 snprintf(G_brinfo.path, sizeof(G_brinfo.path), NDRX_SHM_BRINFO, q_prefix);
0126
0127 snprintf(ndrx_G_routcrit.path, sizeof(G_brinfo.path), NDRX_SHM_ROUTCRIT, q_prefix);
0128 snprintf(ndrx_G_routsvc.path, sizeof(G_brinfo.path), NDRX_SHM_ROUTSVC, q_prefix);
0129
0130 G_max_servers = max_servers;
0131 G_max_svcs = max_svcs;
0132
0133
0134
0135 G_srvinfo.size = sizeof(shm_srvinfo_t)*max_servers;
0136 NDRX_LOG(log_debug, "G_srvinfo.size = %d (%d * %d)",
0137 G_srvinfo.size, sizeof(shm_srvinfo_t), max_servers);
0138
0139 G_svcinfo.size = SHM_SVCINFO_SIZEOF *max_svcs;
0140 NDRX_LOG(log_debug, "G_svcinfo.size = %d (%d * %d)",
0141 G_svcinfo.size, SHM_SVCINFO_SIZEOF, max_svcs);
0142
0143 G_brinfo.size = sizeof(int)*CONF_NDRX_NODEID_COUNT;
0144 NDRX_LOG(log_debug, "G_brinfo.size = %d (%d * %d)",
0145 G_svcinfo.size, sizeof(int), CONF_NDRX_NODEID_COUNT);
0146
0147 ndrx_G_routcrit.size = rtcrtmax*2;
0148 NDRX_LOG(log_debug, "ndrx_G_routcrit.size = %d bytes (%d * 2)",
0149 ndrx_G_routcrit.size, rtcrtmax);
0150
0151 ndrx_G_routsvc.size = rtsvcmax * sizeof(ndrx_services_t) * 2;
0152 NDRX_LOG(log_debug, "ndrx_G_routsvc.size = %d (%d * %d * 2)",
0153 ndrx_G_routsvc.size, rtsvcmax, sizeof(ndrx_services_t));
0154
0155 M_init = EXTRUE;
0156 return EXSUCCEED;
0157 }
0158
0159
0160
0161
0162
0163
0164
0165
0166 expublic void ndrxd_shm_srv_fork_status(int srvid, unsigned execerr)
0167 {
0168 if (EXSUCCEED==ndrx_shm_open(&G_srvinfo, EXTRUE))
0169 {
0170 shm_srvinfo_t* srv = ndrxd_shm_getsrv(srvid);
0171
0172 if (NULL!=srv)
0173 {
0174 srv->execerr=execerr;
0175 }
0176
0177 ndrx_shm_close(&G_srvinfo);
0178 }
0179 }
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190 expublic int ndrxd_shm_close_all(void)
0191 {
0192 int ret=EXSUCCEED;
0193
0194
0195
0196
0197 if (!M_init)
0198 {
0199 NDRX_LOG(log_error, "ndrx shm library not initialized");
0200 ret=EXFAIL;
0201 goto out;
0202 }
0203
0204 ret=ndrx_shm_close(&G_srvinfo);
0205
0206 if (EXFAIL==ndrx_shm_close(&G_svcinfo))
0207 ret=EXFAIL;
0208
0209 if (EXFAIL==ndrx_shm_close(&G_brinfo))
0210 ret=EXFAIL;
0211
0212 if (EXFAIL==ndrx_shm_close(&ndrx_G_routcrit))
0213 ret=EXFAIL;
0214
0215 if (EXFAIL==ndrx_shm_close(&ndrx_G_routsvc))
0216 ret=EXFAIL;
0217 out:
0218 return ret;
0219 }
0220
0221
0222
0223
0224
0225
0226 expublic int ndrxd_shm_delete(void)
0227 {
0228 if (M_init)
0229 {
0230 ndrx_shm_remove(&G_srvinfo);
0231 ndrx_shm_remove(&G_svcinfo);
0232 ndrx_shm_remove(&G_brinfo);
0233
0234 ndrx_shm_remove(&ndrx_G_routcrit);
0235 ndrx_shm_remove(&ndrx_G_routsvc);
0236 }
0237 else
0238 {
0239 NDRX_LOG(log_error, "SHM library not initialized!");
0240 return EXFAIL;
0241 }
0242
0243 return EXSUCCEED;
0244 }
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256 expublic int ndrx_shm_open_all(int lev, int create)
0257 {
0258 int ret=EXSUCCEED;
0259
0260 struct {
0261 int lev;
0262 ndrx_shm_t *shm;
0263 } map [] = {
0264
0265 {NDRX_SHM_LEV_SVC, &G_svcinfo}
0266 ,{NDRX_SHM_LEV_SVC, &ndrx_G_routcrit}
0267 ,{NDRX_SHM_LEV_SVC, &ndrx_G_routsvc}
0268 ,{NDRX_SHM_LEV_SRV, &G_srvinfo}
0269 ,{NDRX_SHM_LEV_BR, &G_brinfo}
0270 };
0271 int i;
0272
0273
0274
0275
0276 if (!M_init)
0277 {
0278 NDRX_LOG(log_error, "ndrx shm library not initialised!");
0279 EXFAIL_OUT(ret);
0280 }
0281
0282 for (i=0; i<N_DIM(map); i++)
0283 {
0284 if (map[i].lev & lev)
0285 {
0286 if (create)
0287 {
0288
0289 if (EXSUCCEED!=ndrx_shm_open(map[i].shm, EXTRUE))
0290 {
0291 EXFAIL_OUT(ret);
0292 }
0293 }
0294 else
0295 {
0296 if (EXSUCCEED!=ndrx_shm_attach(map[i].shm))
0297 {
0298 EXFAIL_OUT(ret);
0299 }
0300 }
0301 }
0302 }
0303
0304 out:
0305 return ret;
0306 }
0307
0308
0309
0310
0311
0312
0313
0314 expublic int ndrx_shm_get_svc(char *svc, char *send_q, int *is_bridge, int *have_shm)
0315 {
0316 int ret=EXSUCCEED;
0317 int pos=EXFAIL;
0318 shm_svcinfo_t *svcinfo = (shm_svcinfo_t *) G_svcinfo.mem;
0319 int use_cluster = EXFAIL;
0320 shm_svcinfo_t *psvcinfo = NULL;
0321 int chosen_node = EXFAIL;
0322 int csrvs;
0323 int srvs;
0324 ATMI_TLS_ENTRY;
0325
0326 *is_bridge=EXFALSE;
0327
0328
0329 sprintf(send_q, NDRX_SVC_QFMT, G_atmi_tls->G_atmi_conf.q_prefix, svc);
0330
0331 if (!ndrx_shm_is_attached(&G_svcinfo))
0332 {
0333 #ifdef EX_USE_POLL
0334
0335
0336
0337 ret = ndrx_get_cached_svc_q(send_q);
0338 #endif
0339 goto out;
0340 }
0341 if (NULL!=have_shm)
0342 {
0343 *have_shm = EXTRUE;
0344 }
0345
0346
0347 if (!_ndrx_shm_get_svc(svc, &pos, NDRX_SVCINSTALL_NOT, NULL))
0348 {
0349 NDRX_LOG(log_error, "Service %s not found in shm", svc);
0350 EXFAIL_OUT(ret);
0351 }
0352
0353 psvcinfo = SHM_SVCINFO_INDEX(svcinfo, pos);
0354
0355 if (psvcinfo->srvs<=0)
0356 {
0357 NDRX_LOG(log_error, "Service %s not available, count of servers: %d",
0358 svc, psvcinfo->srvs);
0359 EXFAIL_OUT(ret);
0360 }
0361
0362
0363
0364
0365 csrvs = psvcinfo->csrvs;
0366 srvs = psvcinfo->srvs;
0367
0368
0369 if (srvs==csrvs && srvs>0)
0370 {
0371 use_cluster=EXTRUE;
0372 }
0373 else if (0==csrvs)
0374 {
0375 use_cluster=EXFALSE;
0376 }
0377
0378 NDRX_LOG(log_debug, "use_cluster=%d srvs=%d csrvs=%d",
0379 use_cluster, srvs, csrvs);
0380
0381 if (EXFAIL==use_cluster)
0382 {
0383 if (0==G_atmi_env.ldbal)
0384 {
0385
0386 use_cluster=EXFALSE;
0387 }
0388 else if (100==G_atmi_env.ldbal)
0389 {
0390
0391 use_cluster=EXTRUE;
0392 }
0393 else
0394 {
0395
0396 int n = ndrx_rand()%100+1;
0397 if (n<=G_atmi_env.ldbal)
0398 {
0399 use_cluster = EXTRUE;
0400 }
0401 else
0402 {
0403 use_cluster = EXFALSE;
0404 }
0405 }
0406 }
0407
0408 NDRX_LOG(log_debug, "use_cluster=%d srvs=%d csrvs=%d",
0409 use_cluster, srvs, csrvs);
0410
0411
0412
0413 if (EXTRUE==use_cluster)
0414 {
0415 int cluster_node;
0416 int i;
0417 int got_node = 0;
0418 int try = 0;
0419
0420
0421
0422
0423
0424 if (csrvs<0 || csrvs>CONF_NDRX_NODEID_COUNT)
0425 {
0426 NDRX_LOG(log_error, "Fixed csrvs to 0");
0427 csrvs=1;
0428 }
0429
0430 cluster_node = ndrx_rand()%csrvs+1;
0431 NDRX_LOG(log_debug, "rnd: cluster_node=%d, cnode_max_id=%d",
0432 cluster_node, psvcinfo->cnodes_max_id);
0433
0434
0435 while (try<2)
0436 {
0437
0438 for (i=0; i<psvcinfo->cnodes_max_id; i++)
0439 {
0440 if (psvcinfo->cnodes[i].srvs)
0441 {
0442 got_node++;
0443 if (1==try)
0444 {
0445
0446 chosen_node=i+1;
0447 NDRX_LOG(log_debug, "try 1, use %d", chosen_node);
0448 break;
0449 }
0450 }
0451
0452 if (got_node==cluster_node)
0453 {
0454 chosen_node=i+1;
0455 NDRX_LOG(log_debug, "one shot: use %d", chosen_node);
0456 break;
0457 }
0458 }
0459
0460
0461 if (EXFAIL!=chosen_node)
0462 {
0463 break;
0464 }
0465
0466 try++;
0467 }
0468
0469 if (EXFAIL!=chosen_node)
0470 {
0471
0472
0473
0474
0475 #if defined(EX_USE_EPOLL) || defined(EX_USE_FDPOLL) || defined(EX_USE_KQUEUE) || defined(EX_USE_SVAPOLL)
0476 sprintf(send_q, NDRX_SVC_QBRDIGE,
0477 G_atmi_tls->G_atmi_conf.q_prefix, chosen_node);
0478 #endif
0479 *is_bridge=EXTRUE;
0480 }
0481 else
0482 {
0483 NDRX_LOG(log_error, "Service [%s] not in cluster!",
0484 svc);
0485 ret=EXFAIL;
0486 }
0487 }
0488 #if defined(EX_USE_POLL) || defined(EX_USE_SYSVQ)
0489 else
0490 {
0491 int resid;
0492 int resrr;
0493 int svc_ok = EXTRUE;
0494 int resnr;
0495
0496
0497
0498
0499
0500
0501
0502 if (EXSUCCEED!=ndrx_lock_svc_nm(svc, __func__, NDRX_SEM_TYP_READ))
0503 {
0504 NDRX_LOG(log_error, "Failed to sem-lock service: %s", svc);
0505 EXFAIL_OUT(ret);
0506 }
0507
0508
0509
0510 NDRX_ATOMIC_ADD(&psvcinfo->resrr, 1);
0511
0512
0513
0514
0515
0516
0517
0518
0519
0520 resnr = psvcinfo->resnr;
0521
0522 if (resnr<=0)
0523 {
0524 NDRX_LOG(log_error, "svc [%s] resnr=%d", svc, resnr);
0525 svc_ok=EXFALSE;
0526 }
0527 else if (0!=strcmp(psvcinfo->service, svc))
0528 {
0529
0530 NDRX_LOG(log_error, "shm reset: [%s] vs [%s]",
0531 psvcinfo->service, svc);
0532 svc_ok=EXFALSE;
0533 }
0534
0535 if (svc_ok)
0536 {
0537 resrr = psvcinfo->resrr % resnr;
0538 resid = psvcinfo->resids[resrr].resid;
0539 }
0540
0541 if (EXSUCCEED!=ndrx_unlock_svc_nm(svc, __func__, NDRX_SEM_TYP_READ))
0542 {
0543 NDRX_LOG(log_error, "Failed to sem-unlock service: %s", svc);
0544 EXFAIL_OUT(ret);
0545 }
0546
0547
0548
0549 if (!svc_ok)
0550 {
0551 NDRX_LOG(log_error, "Service [%s] was removed during lookup", svc);
0552 EXFAIL_OUT(ret);
0553 }
0554
0555
0556
0557
0558
0559
0560
0561 sprintf(send_q, NDRX_SVC_QFMT_SRVID, G_atmi_tls->G_atmi_conf.q_prefix,
0562 svc, resid);
0563
0564 if (EXSUCCEED!=ndrx_epoll_service_translate(send_q,
0565 G_atmi_tls->G_atmi_conf.q_prefix, svc, resid))
0566 {
0567 NDRX_LOG(log_error, "Failed to translate svc [%s] resid=%d to "
0568 "queue resrr=%d",
0569 svc, resid, resrr);
0570 userlog("Failed to translate svc [%s] resid=%d resrr=%d to queue",
0571 svc, resid, resrr);
0572 EXFAIL_OUT(ret);
0573 }
0574
0575 NDRX_LOG(log_debug, "Choosing local service by round-robin mode, "
0576 "rr: %d, srvid: %d, q: [%s]", resrr, resid, send_q);
0577 }
0578
0579 if (*is_bridge && 0!=strncmp(svc, NDRX_SVC_BRIDGE, NDRX_SVC_BRIDGE_STATLEN))
0580 {
0581 char tmpsvc[MAXTIDENT+1];
0582
0583 snprintf(tmpsvc, sizeof(tmpsvc), NDRX_SVC_BRIDGE, chosen_node);
0584
0585 NDRX_LOG(log_debug, "Recursive service lookup: [%s] ret %d", tmpsvc, ret);
0586 ret = ndrx_shm_get_svc(tmpsvc, send_q, is_bridge, NULL);
0587 *is_bridge = EXTRUE;
0588 }
0589
0590 #endif
0591
0592 out:
0593 NDRX_LOG(log_debug, "ndrx_shm_get_svc returns %d", ret);
0594
0595 return ret;
0596 }
0597
0598
0599
0600
0601
0602
0603
0604
0605
0606 expublic int ndrx_shm_get_srvs(char *svc, ndrx_shm_resid_t **srvlist, int *len)
0607 {
0608 int ret=EXSUCCEED;
0609 int pos=EXFAIL;
0610 shm_svcinfo_t *svcinfo = (shm_svcinfo_t *) G_svcinfo.mem;
0611 shm_svcinfo_t *psvcinfo = NULL;
0612 int local_count;
0613
0614 *len = 0;
0615
0616 if (!ndrx_shm_is_attached(&G_svcinfo))
0617 {
0618 ret=EXFAIL;
0619 goto out;
0620 }
0621
0622 if (EXSUCCEED!=ndrx_lock_svc_nm(svc, __func__, NDRX_SEM_TYP_READ))
0623 {
0624 NDRX_LOG(log_error, "Failed to sem-lock service: %s", svc);
0625 EXFAIL_OUT(ret);
0626 }
0627
0628
0629 if (!_ndrx_shm_get_svc(svc, &pos, NDRX_SVCINSTALL_NOT, NULL))
0630 {
0631 NDRX_LOG(log_error, "Service %s not found in shm", svc);
0632 EXFAIL_OUT(ret);
0633 }
0634
0635 psvcinfo = SHM_SVCINFO_INDEX(svcinfo, pos);
0636
0637
0638 local_count = psvcinfo->resnr;
0639
0640 if (local_count<=0)
0641 {
0642 NDRX_LOG(log_error, "Service %s not available, count of servers: %d",
0643 svc, psvcinfo->srvs);
0644 EXFAIL_OUT(ret);
0645 }
0646
0647 if (NULL==(*srvlist = NDRX_MALLOC(sizeof(ndrx_shm_resid_t) *local_count )))
0648 {
0649 NDRX_LOG(log_error, "malloc fail: %s", strerror(errno));
0650 EXFAIL_OUT(ret);
0651 }
0652
0653 memcpy(*srvlist, &(psvcinfo->resids[0]), sizeof(ndrx_shm_resid_t) *local_count);
0654
0655 *len = local_count;
0656
0657 out:
0658
0659 if (EXSUCCEED!=ndrx_unlock_svc_nm(svc, __func__, NDRX_SEM_TYP_READ))
0660 {
0661 NDRX_LOG(log_error, "Failed to sem-unlock service: %s", svc);
0662 }
0663
0664 not_locked:
0665
0666 NDRX_LOG(log_debug, "ndrx_shm_get_srvs: srvlist %p, ret %d, len %d",
0667 *srvlist, ret, *len);
0668
0669 return ret;
0670 }
0671
0672
0673
0674
0675
0676 expublic int ndrx_shm_get_svc_count(void)
0677 {
0678 int ret = 0;
0679 shm_svcinfo_t *svcinfo = (shm_svcinfo_t *) G_svcinfo.mem;
0680 int i;
0681
0682 if (!ndrx_shm_is_attached(&G_svcinfo))
0683 {
0684
0685 NDRX_LOG(log_debug, "SHM not attached -> no service count");
0686 ret=EXFAIL;
0687 goto out;
0688 }
0689
0690 for (i=0; i< G_max_svcs; i++)
0691 {
0692 shm_svcinfo_t* ent = SHM_SVCINFO_INDEX(svcinfo, i);
0693
0694 if (ent->flags & NDRXD_SVCINFO_INIT
0695 && ent->srvs > 0)
0696 {
0697 ret++;
0698 }
0699 }
0700 out:
0701 return ret;
0702 }
0703
0704
0705
0706
0707
0708
0709
0710
0711
0712
0713
0714
0715
0716
0717
0718
0719 expublic int _ndrx_shm_get_svc(char *svc, int *pos, int doing_install, int *p_install_cmd)
0720 {
0721 int ret=EXFALSE;
0722 int try = EXFAIL;
0723 int start = try;
0724 int overflow = EXFALSE;
0725 int iterations = 0;
0726
0727 shm_svcinfo_t *svcinfo = (shm_svcinfo_t *) G_svcinfo.mem;
0728
0729
0730
0731
0732
0733
0734
0735 if (NDRX_SVCINSTALL_DO==doing_install)
0736 {
0737 int try_read = EXFAIL;
0738
0739 if (_ndrx_shm_get_svc(svc, &try_read, NDRX_SVCINSTALL_NOT, NULL))
0740 {
0741 try = try_read;
0742 }
0743 }
0744
0745 if (EXFAIL==try)
0746 {
0747 try = ndrx_hash_fn(svc) % G_max_svcs;
0748 }
0749 else
0750 {
0751 NDRX_LOG(log_debug, "Read only existing service [%s] found at [%d]",
0752 svc, try);
0753 }
0754
0755
0756 start = try;
0757 *pos=EXFAIL;
0758
0759 NDRX_LOG(log_debug, "Key for [%s] is %d, shm is: %p",
0760 svc, try, svcinfo);
0761
0762
0763
0764
0765
0766
0767
0768 while ((SHM_SVCINFO_INDEX(svcinfo, try)->flags & NDRXD_SVCINFO_INIT)
0769 && (!overflow || (overflow && try < start)))
0770 {
0771 if (0==strcmp(SHM_SVCINFO_INDEX(svcinfo, try)->service, svc))
0772 {
0773 ret=EXTRUE;
0774 *pos=try;
0775 break;
0776 }
0777
0778
0779
0780
0781
0782
0783
0784
0785
0786
0787 if (NDRX_SVCINSTALL_DO==doing_install)
0788 {
0789 if (SHM_SVCINFO_INDEX(svcinfo, try)->srvs == 0)
0790 {
0791 *p_install_cmd=NDRX_SVCINSTALL_OVERWRITE;
0792 break;
0793 }
0794 }
0795
0796 try++;
0797
0798
0799
0800
0801
0802 if (try>=G_max_svcs)
0803 {
0804 try = 0;
0805 overflow=EXTRUE;
0806 NDRX_LOG(log_debug, "Overflow reached for search of [%s]", svc);
0807 }
0808 iterations++;
0809
0810 NDRX_LOG(log_debug, "Trying %d for [%s]", try, svc);
0811 }
0812
0813
0814
0815
0816
0817
0818 if (NDRX_SVCINSTALL_DO==doing_install &&
0819 *p_install_cmd!=NDRX_SVCINSTALL_OVERWRITE &&
0820 !(SHM_SVCINFO_INDEX(svcinfo, try)->flags & NDRXD_SVCINFO_INIT))
0821 {
0822 *p_install_cmd=NDRX_SVCINSTALL_OVERWRITE;
0823 }
0824
0825 *pos=try;
0826 NDRX_LOG(log_debug, "ndrx_shm_get_svc [%s] - result: %d, "
0827 "iterations: %d, pos: %d, install: %d",
0828 svc, ret, iterations, *pos,
0829 (doing_install?*p_install_cmd:NDRX_SVCINSTALL_NOT));
0830 return ret;
0831 }
0832
0833
0834
0835
0836
0837
0838
0839
0840
0841
0842 expublic int ndrx_shm_install_svc_br(char *svc, int flags,
0843 int is_bridge, int nodeid, int count, char mode, int resid)
0844 {
0845 int ret=EXSUCCEED;
0846 int pos = EXFAIL;
0847 shm_svcinfo_t *svcinfo = (shm_svcinfo_t *) G_svcinfo.mem;
0848 int i;
0849 int is_new;
0850 int shm_install_cmd = NDRX_SVCINSTALL_NOT;
0851 shm_svcinfo_t* el;
0852
0853 #if defined(EX_USE_POLL) || defined(EX_USE_SYSVQ)
0854 if (EXSUCCEED!=ndrx_lock_svc_nm(svc, __func__, NDRX_SEM_TYP_WRITE))
0855 {
0856 NDRX_LOG(log_error, "Failed to sem-lock service: %s", svc);
0857 ret=EXFAIL;
0858 goto lock_fail;
0859 }
0860 #endif
0861
0862 if (_ndrx_shm_get_svc(svc, &pos, NDRX_SVCINSTALL_DO, &shm_install_cmd))
0863 {
0864 NDRX_LOG(log_debug, "Updating flags for [%s] from %d to %d",
0865 svc, SHM_SVCINFO_INDEX(svcinfo, pos)->flags, flags);
0866 el = SHM_SVCINFO_INDEX(svcinfo, pos);
0867
0868 el->flags = flags | NDRXD_SVCINFO_INIT;
0869
0870
0871 if (!is_bridge ||
0872 (0==el->cnodes[nodeid-1].srvs && count>0))
0873 {
0874
0875 #if defined(EX_USE_POLL) || defined(EX_USE_SYSVQ)
0876
0877 if (!is_bridge && (el->resnr+1 > G_atmi_env.maxsvcsrvs))
0878 {
0879 NDRX_LOG(log_error, "Shared mem for svc [%s] is full - "
0880 "max space for servers per service: %d! Currently: "
0881 "srvs: %d csrvs:%d resnr:%hd",
0882 svc, G_atmi_env.maxsvcsrvs,
0883 el->srvs,
0884 el->csrvs,
0885 el->resnr
0886 );
0887 userlog("Shared mem for svc [%s] is full - "
0888 "max space for servers per service: %d! Currently: "
0889 "srvs: %d csrvs:%d resnr:%hd",
0890 svc, G_atmi_env.maxsvcsrvs,
0891 el->srvs,
0892 el->csrvs,
0893 el->resnr);
0894 EXFAIL_OUT(ret);
0895 }
0896 else if (!is_bridge)
0897 {
0898
0899
0900 int idx = EXFAIL;
0901
0902 for (i=0; i < el->resnr; i++)
0903 {
0904 if (el->resids[i].resid==resid)
0905 {
0906 idx = i;
0907 #ifdef EX_USE_POLL
0908
0909
0910
0911 NDRX_LOG(log_debug, "resource resid/srvid %d at %d "
0912 "already exists", resid, idx);
0913 #else
0914 el->resids[i].cnt++;
0915 NDRX_LOG(log_debug, "installed resid/srvid %d at %d "
0916 "increased to %hd",
0917 resid, idx, el->resids[i].cnt);
0918 #endif
0919 }
0920 }
0921
0922 if (EXFAIL==idx)
0923 {
0924 el->resids[el->resnr].resid = resid;
0925 el->resids[el->resnr].cnt = 1;
0926 NDRX_LOG(log_debug, "installed resid/srvid %d at %d",
0927 resid, el->resnr);
0928 el->resnr++;
0929 }
0930 }
0931 #endif
0932 el->srvs++;
0933
0934 if (is_bridge)
0935 {
0936 el->csrvs++;
0937 }
0938
0939 }
0940 }
0941
0942 else if (NDRX_SVCINSTALL_OVERWRITE==shm_install_cmd)
0943 {
0944 el = SHM_SVCINFO_INDEX(svcinfo, pos);
0945 is_new=EXTRUE;
0946 if (is_bridge && 0==count)
0947 {
0948 NDRX_LOG(log_debug, "Svc [%s] not found in shm, "
0949 "and will not install bridged 0", svc);
0950 goto out;
0951 }
0952 else
0953 {
0954 NDRX_STRCPY_SAFE(el->service, svc);
0955
0956 el->flags = flags | NDRXD_SVCINFO_INIT;
0957 NDRX_LOG(log_debug, "Svc [%s] not found in shm, "
0958 "installed with flags %d",
0959 el->service,
0960 el->flags);
0961
0962 el->srvs++;
0963
0964 if (is_bridge)
0965 {
0966 el->csrvs++;
0967 }
0968 else
0969 {
0970 #if defined(EX_USE_POLL) || defined(EX_USE_SYSVQ)
0971 int idx = 0;
0972 el->resids[idx].resid = resid;
0973 el->resids[idx].cnt = 1;
0974 NDRX_LOG(log_debug, "installed resid/srvid %d at idx %d",
0975 resid, idx);
0976 el->resnr++;
0977 #endif
0978 }
0979 }
0980 }
0981 else
0982 {
0983 NDRX_LOG(log_debug, "Cannot install [%s]!! There is no "
0984 "space in SHM! Try to increase %s",
0985 svc, CONF_NDRX_SVCMAX);
0986 userlog("Cannot install [%s]!! There is no "
0987 "space in SHM! Try to increase %s",
0988 svc, CONF_NDRX_SVCMAX);
0989 EXFAIL_OUT(ret);
0990 }
0991
0992
0993 if (is_bridge)
0994 {
0995 int was_installed;
0996 el = SHM_SVCINFO_INDEX(svcinfo, pos);
0997 was_installed = (el->cnodes[nodeid-1].srvs > 0);
0998
0999 if (BRIDGE_REFRESH_MODE_FULL==mode)
1000 {
1001
1002 el->cnodes[nodeid-1].srvs = count;
1003
1004 NDRX_LOG(log_debug, "SHM Service refresh: [%s] Bridge: [%d]"
1005 " Count: [%d]",
1006 svc, nodeid, count);
1007 }
1008 else
1009 {
1010 el->cnodes[nodeid-1].srvs+=count;
1011
1012
1013 if (el->cnodes[nodeid-1].srvs<0)
1014 {
1015 el->cnodes[nodeid-1].srvs=0;
1016 }
1017 NDRX_LOG(log_debug, "SHM Service update: [%s] Bridge: "
1018 "[%d] Diff: %d final count: [%d], cluster nodes: [%d]",
1019 svc, nodeid, count, el->cnodes[nodeid-1].srvs,
1020 el->csrvs);
1021 }
1022
1023
1024 if (el->cnodes[nodeid-1].srvs<=0 && was_installed)
1025 {
1026
1027 el->csrvs--;
1028 el->srvs--;
1029 }
1030
1031
1032 if (0==el->csrvs &&
1033 0==el->srvs)
1034 {
1035 NDRX_LOG(log_debug,
1036 "Bridge %d caused to remove svc [%s] from shm",
1037 nodeid, svc);
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047 memset(&el->cnodes, 0,
1048 sizeof(el->cnodes));
1049 el->totclustered = 0;
1050
1051 goto out;
1052 }
1053
1054
1055
1056
1057
1058 if (nodeid > el->cnodes_max_id)
1059 {
1060 el->cnodes_max_id = nodeid;
1061 }
1062
1063
1064 el->totclustered = 0;
1065 for (i=0; i<el->cnodes_max_id; i++)
1066 {
1067 el->totclustered+=
1068 el->cnodes[i].srvs;
1069 }
1070 NDRX_LOG(log_debug, "Total clustered services: %d",
1071 SHM_SVCINFO_INDEX(svcinfo, pos)->totclustered);
1072 }
1073 out:
1074
1075 #if defined(EX_USE_POLL) || defined(EX_USE_SYSVQ)
1076 if (EXSUCCEED!=ndrx_unlock_svc_nm(svc, __func__, NDRX_SEM_TYP_WRITE))
1077 {
1078 NDRX_LOG(log_error, "Failed to sem-unlock service: %s", svc);
1079 }
1080 #endif
1081
1082 lock_fail:
1083
1084 return ret;
1085 }
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095 expublic int ndrx_shm_install_svc(char *svc, int flags, int resid)
1096 {
1097 return ndrx_shm_install_svc_br(svc, flags, EXFALSE, 0, 0, 0, resid);
1098 }
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120 expublic void ndrxd_shm_uninstall_svc(char *svc, int *last, int resid)
1121 {
1122 int pos = EXFAIL;
1123 int i;
1124 shm_svcinfo_t *svcinfo = (shm_svcinfo_t *) G_svcinfo.mem;
1125 int lpos;
1126 shm_svcinfo_t* el;
1127
1128 #if defined(EX_USE_POLL) || defined(EX_USE_SYSVQ)
1129 if (EXSUCCEED!=ndrx_lock_svc_nm(svc, __func__, NDRX_SEM_TYP_WRITE))
1130 {
1131 NDRX_LOG(log_error, "Failed to sem-lock service: %s", svc);
1132 return;
1133 }
1134 #endif
1135
1136 *last=EXFALSE;
1137 if (_ndrx_shm_get_svc(svc, &pos, NDRX_SVCINSTALL_NOT, NULL))
1138 {
1139 el = SHM_SVCINFO_INDEX(svcinfo, pos);
1140 if (el->srvs>1)
1141 {
1142 NDRX_LOG(log_debug, "Decreasing count of servers for "
1143 "[%s] from %d to %d (resnr=%d)",
1144 svc, el->srvs,
1145 el->srvs-1, el->resnr);
1146
1147 #if defined(EX_USE_POLL) || defined(EX_USE_SYSVQ)
1148
1149
1150
1151
1152
1153 lpos = EXFAIL;
1154 for (i=0; i<el->resnr; i++)
1155 {
1156 if (el->resids[i].resid==resid)
1157 {
1158 lpos = i;
1159 break;
1160 }
1161 }
1162
1163 if (EXFAIL!=lpos)
1164 {
1165 NDRX_LOG(log_debug, "Local count: %hd", el->resids[lpos].cnt);
1166
1167 if (el->resids[lpos].cnt>1)
1168 {
1169 el->resids[lpos].cnt--;
1170 NDRX_LOG(log_debug, "Resource %d decrement to %hd",
1171 el->resids[lpos].resid, el->resids[lpos].cnt);
1172 }
1173 else if (lpos==el->resnr-1)
1174 {
1175 el->resnr--;
1176 NDRX_LOG(log_debug, "Server was at last position, "
1177 "just shrink the numbers...");
1178 }
1179 else
1180 {
1181 NDRX_LOG(log_debug, "Reducing the local server array...");
1182 memmove(&(el->resids[lpos]),
1183 &(el->resids[lpos+1]),
1184 (el->resnr - lpos -1)*sizeof(el->resids[0]));
1185 el->resnr--;
1186 }
1187 }
1188
1189 #endif
1190 el->srvs--;
1191
1192 if (el->csrvs==el->srvs)
1193 {
1194
1195 *last=EXTRUE;
1196 }
1197 }
1198 else
1199 {
1200 el = SHM_SVCINFO_INDEX(svcinfo, pos);
1201
1202 NDRX_LOG(log_debug, "Removing service from shared mem "
1203 "[%s]",
1204 svc);
1205
1206
1207
1208
1209
1210
1211
1212 memset(&el->cnodes, 0,
1213 sizeof(el->cnodes));
1214 el->totclustered = 0;
1215 el->csrvs = 0;
1216 el->srvs = 0;
1217 #if defined(EX_USE_POLL) || defined(EX_USE_SYSVQ)
1218 el->resnr = 0;
1219 el->resrr = 0;
1220 #endif
1221
1222 *last=EXTRUE;
1223 }
1224 }
1225 else
1226 {
1227 NDRX_LOG(log_debug, "Service [%s] not present in shm", svc);
1228 *last=EXTRUE;
1229 }
1230
1231 #if defined(EX_USE_POLL) || defined(EX_USE_SYSVQ)
1232 if (EXSUCCEED!=ndrx_unlock_svc_nm(svc, __func__, NDRX_SEM_TYP_WRITE))
1233 {
1234 NDRX_LOG(log_error, "Failed to sem-unlock service: %s", svc);
1235 return;
1236 }
1237 #endif
1238
1239 }
1240
1241
1242
1243
1244
1245 expublic void ndrxd_shm_resetsrv(int srvid)
1246 {
1247 shm_srvinfo_t *srv = ndrxd_shm_getsrv(srvid);
1248 if (NULL!=srv)
1249 memset(srv, 0, sizeof(shm_srvinfo_t));
1250 }
1251
1252
1253
1254
1255
1256
1257
1258
1259 expublic shm_srvinfo_t* ndrxd_shm_getsrv(int srvid)
1260 {
1261 shm_srvinfo_t *ret=NULL;
1262 int pos=EXFAIL;
1263 shm_srvinfo_t *srvinfo = (shm_srvinfo_t *) G_srvinfo.mem;
1264
1265 if (!ndrx_shm_is_attached(&G_srvinfo))
1266 {
1267 ret=NULL;
1268 goto out;
1269 }
1270
1271 if (srvid >-1 && srvid < G_max_servers)
1272 {
1273 ret=&srvinfo[srvid];
1274 }
1275 else
1276 {
1277 NDRX_LOG(log_error, "Invalid srvid requested to "
1278 "ndrxd_shm_getsrv => %d", srvid);
1279 ret=NULL;
1280 }
1281
1282 out:
1283 return ret;
1284 }
1285
1286
1287
1288
1289
1290 expublic int ndrx_shm_birdge_getnodesconnected(char *outputbuf)
1291 {
1292 int ret=EXSUCCEED;
1293 int *brinfo = (int *) G_brinfo.mem;
1294 int i;
1295 int pos=0;
1296
1297 if (!ndrx_shm_is_attached(&G_brinfo))
1298 {
1299 EXFAIL_OUT(ret);
1300 }
1301
1302 for (i=1; i<=CONF_NDRX_NODEID_COUNT; i++)
1303 {
1304 if (brinfo[i-1] & NDRX_SHM_BR_CONNECTED)
1305 {
1306 outputbuf[pos] = i;
1307 pos++;
1308 }
1309 }
1310
1311 out:
1312 return ret;
1313 }
1314
1315
1316
1317
1318
1319
1320 expublic int ndrx_shm_birdge_set_flags(int nodeid, int flags, int op_end)
1321 {
1322 int ret=EXSUCCEED;
1323 int *brinfo = (int *) G_brinfo.mem;
1324
1325 if (!ndrx_shm_is_attached(&G_brinfo))
1326 {
1327 ret=EXFAIL;
1328 goto out;
1329 }
1330
1331 if (nodeid >= CONF_NDRX_NODEID_MIN && nodeid <= CONF_NDRX_NODEID_MAX)
1332 {
1333 if (op_end)
1334 brinfo[nodeid-1]&=flags;
1335 else
1336 brinfo[nodeid-1]|=flags;
1337 }
1338 else
1339 {
1340 NDRX_LOG(log_error, "Invalid nodeid requested to "
1341 "shm_mark_br_connected => %d", nodeid);
1342 ret=EXFAIL;
1343 }
1344
1345 out:
1346 return ret;
1347 }
1348
1349
1350
1351
1352
1353
1354 expublic int ndrx_shm_bridge_disco(int nodeid)
1355 {
1356 return ndrx_shm_birdge_set_flags(nodeid, ~NDRX_SHM_BR_CONNECTED, EXTRUE);
1357 }
1358
1359
1360
1361
1362
1363
1364
1365 expublic int ndrx_shm_bridge_connected(int nodeid)
1366 {
1367 return ndrx_shm_birdge_set_flags(nodeid, NDRX_SHM_BR_CONNECTED, EXFALSE);
1368 }
1369
1370
1371
1372
1373
1374
1375 expublic int ndrx_shm_bridge_is_connected(int nodeid)
1376 {
1377 int *brinfo = (int *) G_brinfo.mem;
1378 int ret=EXFALSE;
1379
1380 if (!ndrx_shm_is_attached(&G_brinfo))
1381 {
1382 goto out;
1383 }
1384
1385 if (nodeid >= CONF_NDRX_NODEID_MIN && nodeid <= CONF_NDRX_NODEID_MAX)
1386 {
1387 if (brinfo[nodeid-1]&NDRX_SHM_BR_CONNECTED)
1388 {
1389 ret=EXTRUE;
1390 }
1391 }
1392 else
1393 {
1394 NDRX_LOG(log_error, "Invalid nodeid requested to "
1395 "shm_is_br_connected => %d", nodeid);
1396 }
1397
1398 out:
1399 return ret;
1400 }
1401
1402
1403
1404