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 #include <stdio.h>
0037 #include <stdlib.h>
0038 #include <string.h>
0039 #include <errno.h>
0040 #include <regex.h>
0041 #include <utlist.h>
0042 #include <unistd.h>
0043 #include <signal.h>
0044
0045 #include <ndebug.h>
0046 #include <atmi.h>
0047 #include <atmi_int.h>
0048 #include <typed_buf.h>
0049 #include <ndrstandard.h>
0050 #include <ubf.h>
0051 #include <Exfields.h>
0052 #include <Excompat.h>
0053 #include <ubfutil.h>
0054 #include <sys_unix.h>
0055 #include <utlist.h>
0056
0057 #include <tpadmsv.h>
0058 #include "expr.h"
0059 #include "cpm.h"
0060
0061
0062
0063
0064
0065
0066
0067
0068 typedef struct ndrx_adm_client ndrx_adm_client_t;
0069 struct ndrx_adm_client
0070 {
0071 char clientid[128+1];
0072 char name[MAXTIDENT+1];
0073 char lmid[MAXTIDENT+1];
0074
0075 char state[15+1];
0076 long pid;
0077 long curconv;
0078 long contextid;
0079 long curtime;
0080 int cursor_loaded;
0081
0082 EX_hash_handle hh;
0083 ndrx_adm_client_t *next;
0084
0085 };
0086
0087
0088
0089
0090 expublic ndrx_adm_elmap_t ndrx_G_client_map[] =
0091 {
0092
0093 {TA_LMID, TPADM_EL(ndrx_adm_client_t, lmid)}
0094 ,{TA_CLIENTID, TPADM_EL(ndrx_adm_client_t, clientid)}
0095 ,{TA_CLTNAME, TPADM_EL(ndrx_adm_client_t, name)}
0096 ,{TA_STATE, TPADM_EL(ndrx_adm_client_t, state)}
0097 ,{TA_PID, TPADM_EL(ndrx_adm_client_t, pid)}
0098 ,{TA_CURCONV, TPADM_EL(ndrx_adm_client_t, curconv)}
0099 ,{TA_CONTEXTID, TPADM_EL(ndrx_adm_client_t, contextid)}
0100 ,{TA_CURTIME, TPADM_EL(ndrx_adm_client_t, curtime)}
0101 ,{BBADFLDID}
0102 };
0103
0104
0105
0106
0107
0108
0109
0110 exprivate ndrx_adm_client_t *M_prehash_act = NULL;
0111 exprivate ndrx_adm_client_t *M_ll_dea = NULL;
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121 expublic int ndrx_adm_client_get(char *clazz, ndrx_adm_cursors_t *cursnew, long flags)
0122 {
0123 int ret = EXSUCCEED;
0124 int typ;
0125 string_list_t* qlist = NULL;
0126 string_list_t* elt = NULL;
0127 ndrx_qdet_t qdet;
0128 TPMYID myid;
0129 ndrx_adm_client_t clt;
0130 ndrx_adm_client_t *p_clt, *p_clt2, *cel, *clet;
0131 int cltshm_attached = EXFALSE;
0132 ndrx_sem_t *sem = NULL;
0133 ndrx_shm_t *shm = NULL;
0134 ndrx_clt_shm_t *el;
0135 long l1, l2;
0136 int idx=0;
0137 int i;
0138 cursnew->map = ndrx_G_client_map;
0139
0140 ndrx_growlist_init(&cursnew->list, 100, sizeof(ndrx_adm_client_t));
0141
0142 qlist = ndrx_sys_mqueue_list_make(G_atmi_env.qpath, &ret);
0143
0144 if (EXSUCCEED!=ret)
0145 {
0146 NDRX_LOG(log_error, "posix queue listing failed!");
0147 EXFAIL_OUT(ret);
0148 }
0149
0150
0151 LL_FOREACH(qlist,elt)
0152 {
0153
0154
0155
0156
0157 if (0!=strncmp(elt->qname,
0158 G_atmi_env.qprefix_match, G_atmi_env.qprefix_match_len))
0159 {
0160 continue;
0161 }
0162
0163
0164
0165 typ = ndrx_q_type_get(elt->qname);
0166
0167
0168 if (NDRX_QTYPE_CLTRPLY==typ)
0169 {
0170 if (EXSUCCEED==ndrx_qdet_parse_cltqstr(&qdet, elt->qname))
0171 {
0172 memset(&clt, 0, sizeof(clt));
0173 clt.pid = qdet.pid;
0174 NDRX_STRCPY_SAFE(clt.clientid, elt->qname);
0175 clt.contextid = qdet.contextid;
0176 NDRX_STRCPY_SAFE(clt.name, qdet.binary_name);
0177 snprintf(clt.lmid, sizeof(clt.lmid), "%ld", tpgetnodeid());
0178
0179 if (EXSUCCEED==kill(qdet.pid, 0))
0180 {
0181 NDRX_STRCPY_SAFE(clt.state, "ACT");
0182 }
0183 else
0184 {
0185 NDRX_STRCPY_SAFE(clt.state, "DEA");
0186 }
0187
0188 if (EXSUCCEED!=ndrx_growlist_add(&cursnew->list, (void *)&clt, idx))
0189 {
0190 NDRX_LOG(log_error, "Growlist failed - out of memory?");
0191 EXFAIL_OUT(ret);
0192 }
0193
0194 NDRX_LOG(log_debug, "client [%s] state %s added (Q)",
0195 clt.clientid, clt.state);
0196 idx++;
0197 }
0198 }
0199 }
0200
0201
0202 LL_FOREACH(qlist,elt)
0203 {
0204
0205
0206
0207 if (0!=strncmp(elt->qname,
0208 G_atmi_env.qprefix_match, G_atmi_env.qprefix_match_len))
0209 {
0210 continue;
0211 }
0212
0213
0214
0215 typ = ndrx_q_type_get(elt->qname);
0216
0217 if (NDRX_QTYPE_CONVINIT==typ)
0218 {
0219
0220 if (EXSUCCEED==ndrx_cvnq_parse_client(elt->qname, &myid))
0221 {
0222
0223 for (i=0; i<=cursnew->list.maxindexused; i++)
0224 {
0225 p_clt = (ndrx_adm_client_t *) (cursnew->list.mem + i*sizeof(ndrx_adm_client_t));
0226
0227
0228 myid.binary_name[MAXTIDENT] = EXEOS;
0229 if (p_clt->pid == myid.pid
0230 && p_clt->contextid == myid.contextid
0231 && 0==strcmp(p_clt->name, myid.binary_name)
0232 && myid.nodeid == atoi(p_clt->lmid)
0233 )
0234 {
0235 p_clt->curconv++;
0236 NDRX_LOG(log_debug, "client [%s] currconv incremented to %ld",
0237 p_clt->name, p_clt->curconv);
0238 break;
0239 }
0240 }
0241
0242 }
0243 }
0244
0245 }
0246
0247
0248
0249
0250
0251
0252
0253
0254 if (EXSUCCEED==ndrx_cltshm_init(EXTRUE))
0255 {
0256 char *p;
0257 cltshm_attached = EXTRUE;
0258
0259 sem = ndrx_cltshm_sem_get();
0260 shm = ndrx_cltshm_mem_get();
0261
0262
0263 if (EXSUCCEED!=ndrx_sem_rwlock(sem, 0, NDRX_SEM_TYP_READ))
0264 {
0265 EXFAIL_OUT(ret);
0266 }
0267
0268 NDRX_LOG(log_debug, "Build up the hash of SHM");
0269 for (i=0; i<G_atmi_env.max_clts; i++)
0270 {
0271 el = NDRX_CPM_INDEX(shm->mem, i);
0272
0273 if (el->flags & NDRX_CPM_MAP_WASUSED)
0274 {
0275 int err;
0276 p_clt = NDRX_CALLOC(1, sizeof(ndrx_adm_client_t));
0277
0278 err = errno;
0279
0280 if (NULL==p_clt)
0281 {
0282 NDRX_LOG(log_error, "Failed to calloc of %d bytes failed: %s",
0283 sizeof(ndrx_adm_client_t), strerror(err));
0284 userlog("Failed to calloc of %d bytes failed: %s",
0285 sizeof(ndrx_adm_client_t), strerror(err));
0286
0287
0288 ndrx_sem_rwunlock(sem, 0, NDRX_SEM_TYP_READ);
0289
0290 EXFAIL_OUT(ret);
0291 }
0292
0293 p_clt->pid = el->pid;
0294
0295 snprintf(p_clt->clientid, sizeof(p_clt->clientid),
0296 "%ld/%s", tpgetnodeid(), el->key);
0297
0298 p = strchr(p_clt->clientid, NDRX_CPM_SEP);
0299 if (NULL!=p)
0300 {
0301 *p = '/';
0302 }
0303
0304
0305 p_clt->curtime = (long)el->stattime;
0306 p_clt->curconv = EXFAIL;
0307 p_clt->contextid = EXFAIL;
0308 snprintf(p_clt->lmid, sizeof(clt.lmid), "%ld", tpgetnodeid());
0309
0310
0311 NDRX_STRCPY_SAFE(p_clt->name, el->procname);
0312
0313 if (el->flags & NDRX_CPM_MAP_ISUSED && ndrx_sys_is_process_running_by_pid(el->pid))
0314 {
0315 NDRX_STRCPY_SAFE(p_clt->state, "ACT");
0316 EXHASH_ADD_LONG(M_prehash_act, pid, p_clt);
0317 NDRX_LOG(log_debug, "Hashed pid=%d - %s", p_clt->pid, p_clt->clientid);
0318 }
0319 else
0320 {
0321
0322 NDRX_STRCPY_SAFE(p_clt->state, "DEA");
0323 LL_APPEND(M_ll_dea, p_clt);
0324 }
0325
0326 }
0327 }
0328
0329
0330 ndrx_sem_rwunlock(sem, 0, NDRX_SEM_TYP_READ);
0331 }
0332
0333
0334 NDRX_LOG(log_debug, "Merge clients Q + SHM");
0335
0336 for (i=0; i<=cursnew->list.maxindexused; i++)
0337 {
0338
0339 p_clt = (ndrx_adm_client_t *) (cursnew->list.mem + i*sizeof(ndrx_adm_client_t));
0340
0341 EXHASH_FIND_LONG(M_prehash_act, &(p_clt->pid), p_clt2);
0342
0343 if (NULL!=p_clt2)
0344 {
0345 NDRX_LOG(log_debug, "PID %d matched with SHM", (int)p_clt->pid);
0346
0347 snprintf(p_clt->clientid, sizeof(p_clt->clientid), "%s/%ld",
0348 p_clt2->clientid, p_clt->contextid);
0349
0350
0351 p_clt->curtime = p_clt2->curtime;
0352 p_clt2->cursor_loaded = EXTRUE;
0353 }
0354 }
0355
0356
0357 NDRX_LOG(log_debug, "Add HASH/SHM data");
0358 EXHASH_ITER(hh, M_prehash_act, cel, clet)
0359 {
0360 if (!cel->cursor_loaded)
0361 {
0362
0363 memcpy(&clt, cel, sizeof(clt));
0364 if (EXSUCCEED!=ndrx_growlist_add(&cursnew->list, (void *)&clt, idx))
0365 {
0366 NDRX_LOG(log_error, "Growlist failed - out of memory?");
0367 EXFAIL_OUT(ret);
0368 }
0369
0370 NDRX_LOG(log_debug, "client [%s] state %s added (SHM)", clt.clientid, clt.state);
0371 idx++;
0372 }
0373 }
0374
0375 LL_FOREACH(M_ll_dea, cel)
0376 {
0377 memcpy(&clt, cel, sizeof(clt));
0378 if (EXSUCCEED!=ndrx_growlist_add(&cursnew->list, (void *)&clt, idx))
0379 {
0380 NDRX_LOG(log_error, "Growlist failed - out of memory?");
0381 EXFAIL_OUT(ret);
0382 }
0383
0384 NDRX_LOG(log_debug, "client [%s] state %s added (SHM)", clt.clientid, clt.state);
0385 idx++;
0386 }
0387
0388 out:
0389
0390 if (cltshm_attached)
0391 {
0392 ndrx_cltshm_detach();
0393 }
0394
0395 if (NULL!=qlist)
0396 {
0397 ndrx_string_list_free(qlist);
0398 }
0399
0400 if (EXSUCCEED!=ret)
0401 {
0402 ndrx_growlist_free(&cursnew->list);
0403 }
0404
0405
0406 EXHASH_ITER(hh, M_prehash_act, cel, clet)
0407 {
0408 EXHASH_DEL(M_prehash_act, cel);
0409 NDRX_FREE(cel);
0410 }
0411
0412
0413 LL_FOREACH_SAFE(M_ll_dea, cel, clet)
0414 {
0415 LL_DELETE(M_ll_dea, cel);
0416 NDRX_FREE(cel);
0417 }
0418
0419 return ret;
0420 }
0421
0422