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 #include <ndrx_config.h>
0036 #include <string.h>
0037 #include <stdio.h>
0038 #include <stdlib.h>
0039 #include <memory.h>
0040 #include <errno.h>
0041 #include <sys/sem.h>
0042 #include <signal.h>
0043
0044 #include <sys_unix.h>
0045 #include <atmi.h>
0046 #include <atmi_shm.h>
0047 #include <ndrstandard.h>
0048 #include <ndebug.h>
0049 #include <ndrxdcmn.h>
0050 #include <userlog.h>
0051
0052
0053 #include <sys/mman.h>
0054 #include <sys/types.h>
0055
0056 #include <unistd.h>
0057 #include <fcntl.h>
0058 #include <sys/stat.h>
0059 #include <sys/ipc.h>
0060
0061 #include <nstd_shm.h>
0062 #include <cpm.h>
0063
0064
0065
0066
0067
0068
0069
0070 exprivate ndrx_shm_t M_clt_shm = {.fd=EXFAIL, .path="", .mem=NULL};
0071 exprivate ndrx_sem_t M_clt_sem = {.semid=0};
0072 exprivate int M_attached = EXFALSE;
0073
0074
0075
0076
0077
0078
0079
0080
0081 expublic int ndrx_cltshm_init(int attach_only)
0082 {
0083 int ret = EXSUCCEED;
0084
0085 if (M_attached)
0086 {
0087 NDRX_LOG(log_warn, "Already attached to CPM/CLT SHM");
0088 goto out;
0089 }
0090
0091 M_clt_shm.fd = EXFAIL;
0092 M_clt_shm.key = G_atmi_env.ipckey + NDRX_SHM_CPM_KEYOFSZ;
0093
0094 snprintf(M_clt_shm.path, sizeof(M_clt_shm.path), NDRX_SHM_CPM, G_atmi_env.qprefix);
0095 M_clt_shm.size = sizeof(ndrx_clt_shm_t)*G_atmi_env.max_clts;
0096
0097 if (attach_only)
0098 {
0099 if (EXSUCCEED!=ndrx_shm_attach(&M_clt_shm))
0100 {
0101 NDRX_LOG(log_error, "Failed to attach ",
0102 M_clt_shm.path);
0103 EXFAIL_OUT(ret);
0104 }
0105 }
0106 else if (EXSUCCEED!=ndrx_shm_open(&M_clt_shm, EXTRUE))
0107 {
0108 NDRX_LOG(log_error, "Failed to open shm [%s] - System V Queues cannot work",
0109 M_clt_shm.path);
0110 EXFAIL_OUT(ret);
0111 }
0112
0113 memset(&M_clt_sem, 0, sizeof(M_clt_sem));
0114
0115
0116 M_clt_sem.key = G_atmi_env.ipckey + NDRX_SEM_CPMLOCKS;
0117 M_clt_sem.nrsems = 1;
0118 M_clt_sem.maxreaders = NDRX_CPMSHM_MAX_READERS;
0119
0120 NDRX_LOG(log_debug, "CPMSHM: Using service semaphore key: %d max readers: %d",
0121 M_clt_sem.key, M_clt_sem.maxreaders);
0122
0123
0124 if (attach_only)
0125 {
0126 if (EXSUCCEED!=ndrx_sem_attach(&M_clt_sem))
0127 {
0128 NDRX_LOG(log_error, "Failed to attach semaphore for CPM "
0129 "map shared mem");
0130 EXFAIL_OUT(ret);
0131 }
0132 }
0133 else if (EXSUCCEED!=ndrx_sem_open(&M_clt_sem, EXTRUE))
0134 {
0135 NDRX_LOG(log_error, "Failed to open semaphore for CPM "
0136 "map shared mem");
0137 userlog("Failed to open semaphore for CPM "
0138 "map shared mem");
0139 EXFAIL_OUT(ret);
0140 }
0141
0142 M_attached = EXTRUE;
0143 out:
0144 NDRX_LOG(log_debug, "returns %d", ret);
0145 return ret;
0146 }
0147
0148
0149
0150
0151
0152
0153
0154
0155 exprivate int cltkey_key_hash(ndrx_lh_config_t *conf, void *key_get, size_t key_len)
0156 {
0157 return ndrx_hash_fn(key_get) % conf->elmmax;
0158 }
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168 exprivate void cltkey_key_debug(ndrx_lh_config_t *conf, void *key_get,
0169 size_t key_len, char *dbg_out, size_t dbg_len)
0170 {
0171 NDRX_STRCPY_SAFE_DST(dbg_out, key_get, dbg_len);
0172 }
0173
0174
0175
0176
0177
0178
0179
0180
0181 exprivate void cltkey_val_debug(ndrx_lh_config_t *conf, int idx, char *dbg_out,
0182 size_t dbg_len)
0183 {
0184 NDRX_STRCPY_SAFE_DST(dbg_out, NDRX_CPM_INDEX((*conf->memptr), idx)->key, dbg_len);
0185 }
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195 exprivate int cltkey_compare(ndrx_lh_config_t *conf, void *key_get,
0196 size_t key_len, int idx)
0197 {
0198 return strcmp(NDRX_CPM_INDEX((*conf->memptr), idx)->key, key_get);
0199 }
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209 expublic int ndrx_cltshm_get_key(char *key, int oflag, int *pos, int *have_value)
0210 {
0211 static ndrx_lh_config_t conf;
0212 static int first = EXTRUE;
0213
0214 if (first)
0215 {
0216 conf.elmmax = G_atmi_env.max_clts;
0217 conf.elmsz = sizeof(ndrx_clt_shm_t);
0218 conf.flags_offset = EXOFFSET(ndrx_clt_shm_t, flags);
0219 conf.memptr = (void **)&(M_clt_shm.mem);
0220 conf.p_key_hash=&cltkey_key_hash;
0221 conf.p_key_debug=&cltkey_key_debug;
0222 conf.p_val_debug=&cltkey_val_debug;
0223 conf.p_compare=&cltkey_compare;
0224 first = EXFALSE;
0225 }
0226
0227 return ndrx_lh_position_get(&conf, key, 0, oflag, pos, have_value, "cltkey");
0228
0229 }
0230
0231
0232
0233
0234 expublic void ndrx_cltshm_detach(void)
0235 {
0236 NDRX_LOG(log_debug, "cltshm detach");
0237 ndrx_shm_close(&M_clt_shm);
0238 ndrx_sem_close(&M_clt_sem);
0239
0240 M_attached = EXFALSE;
0241 }
0242
0243
0244
0245
0246
0247 expublic int ndrx_cltshm_remove(int force)
0248 {
0249 int ret = EXSUCCEED;
0250
0251 NDRX_LOG(log_debug, "cltshm remove force: %d", force);
0252
0253 if (M_clt_shm.fd !=EXFAIL)
0254 {
0255 if (EXSUCCEED!=ndrx_shm_remove(&M_clt_shm))
0256 {
0257 ret = EXFAIL;
0258 }
0259 M_clt_shm.fd = EXFAIL;
0260 }
0261
0262 if (EXSUCCEED!=ndrx_sem_remove(&M_clt_sem, force))
0263 {
0264 ret = EXFAIL;
0265 }
0266
0267 out:
0268 return ret;
0269 }
0270
0271
0272
0273
0274
0275
0276 expublic ndrx_shm_t* ndrx_cltshm_mem_get(void)
0277 {
0278 return &M_clt_shm;
0279 }
0280
0281
0282
0283
0284
0285
0286 expublic ndrx_sem_t* ndrx_cltshm_sem_get(void)
0287 {
0288 return &M_clt_sem;
0289 }
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299 expublic pid_t ndrx_cltshm_getpid(char *key, char *procname,
0300 size_t procnamesz, time_t *p_stattime)
0301 {
0302 pid_t ret = EXFAIL;
0303 int pos;
0304 int have_value;
0305
0306
0307 if (EXSUCCEED!=ndrx_sem_rwlock(&M_clt_sem, 0, NDRX_SEM_TYP_READ))
0308 {
0309 goto out;
0310 }
0311
0312 if (ndrx_cltshm_get_key(key, 0, &pos, &have_value))
0313 {
0314 if (have_value)
0315 {
0316 ndrx_clt_shm_t *el = NDRX_CPM_INDEX(M_clt_shm.mem, pos);
0317
0318
0319 ret = el->pid;
0320
0321 if (NULL!=procname)
0322 {
0323 NDRX_STRCPY_SAFE_DST(procname, el->procname, procnamesz);
0324 }
0325
0326 if (NULL!=p_stattime)
0327 {
0328 memcpy(p_stattime, &el->stattime, sizeof(el->stattime));
0329 }
0330
0331 }
0332 }
0333
0334
0335 ndrx_sem_rwunlock(&M_clt_sem, 0, NDRX_SEM_TYP_READ);
0336 out:
0337 return ret;
0338 }
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350 expublic int ndrx_cltshm_setpos(char *key, pid_t pid, short flags, char *procname)
0351 {
0352 int ret = EXFAIL;
0353 int pos;
0354 int have_value;
0355 int oflag = 0;
0356 ndrx_clt_shm_t* el;
0357
0358 if (flags & NDRX_CPM_MAP_ISUSED)
0359 {
0360 oflag |=O_CREAT;
0361 }
0362
0363
0364 if (EXSUCCEED!=ndrx_sem_rwlock(&M_clt_sem, 0, NDRX_SEM_TYP_WRITE))
0365 {
0366 goto out;
0367 }
0368
0369 if (ndrx_cltshm_get_key(key, oflag, &pos, &have_value))
0370 {
0371
0372
0373 el = NDRX_CPM_INDEX(M_clt_shm.mem, pos);
0374 if (oflag)
0375 {
0376 NDRX_STRCPY_SAFE(el->key, key);
0377 el->pid = pid;
0378 NDRX_STRCPY_SAFE(el->procname, procname);
0379 el->flags = flags;
0380 time (&(el->stattime));
0381 }
0382 else
0383 {
0384 el->flags = flags;
0385 }
0386
0387 ret = EXSUCCEED;
0388 }
0389
0390
0391
0392
0393 ndrx_sem_rwunlock(&M_clt_sem, 0, NDRX_SEM_TYP_WRITE);
0394 out:
0395
0396 if (EXSUCCEED==ret)
0397 {
0398 if (oflag)
0399 {
0400 NDRX_LOG(log_info, "Process installed in CPM SHM: [%s]/%s/%d/%hd",
0401 key, procname, (int)pid, flags);
0402 }
0403 else
0404 {
0405 NDRX_LOG(log_info, "Process removed from CPM SHM: [%s]/%s/%d/%hd",
0406 key, NDRX_CPM_INDEX(M_clt_shm.mem, pos)->procname,
0407 (int)NDRX_CPM_INDEX(M_clt_shm.mem, pos)->pid, flags);
0408 }
0409 }
0410
0411 return ret;
0412 }
0413
0414
0415
0416
0417
0418
0419
0420
0421 expublic void ndrx_cltshm_down(int *signals, int *p_was_any)
0422 {
0423 int i, s;
0424 ndrx_clt_shm_t *el;
0425 string_list_t* cltchildren = NULL;
0426 int was_kill = EXFALSE;
0427 char *mem_cpy = NULL;
0428 size_t cpsz;
0429 int err;
0430
0431
0432
0433
0434
0435 if (EXSUCCEED==ndrx_cltshm_init(EXTRUE))
0436 {
0437 NDRX_LOG(log_warn, "CLTSHM processing down");
0438
0439 cpsz = G_atmi_env.max_clts * sizeof(ndrx_clt_shm_t);
0440 mem_cpy = NDRX_MALLOC(cpsz);
0441
0442 if (NULL==mem_cpy)
0443 {
0444 err = errno;
0445 NDRX_LOG(log_error, "Failed to malloc %d bytes: %s",
0446 cpsz, strerror(err));
0447 userlog("Failed to malloc %d bytes: %s",
0448 cpsz, strerror(err));
0449
0450
0451 goto out;
0452 }
0453
0454 if (EXSUCCEED!=ndrx_sem_rwlock(&M_clt_sem, 0, NDRX_SEM_TYP_WRITE))
0455 {
0456 goto out;
0457 }
0458
0459
0460 memcpy(mem_cpy, M_clt_shm.mem, cpsz);
0461
0462
0463 ndrx_sem_rwunlock(&M_clt_sem, 0, NDRX_SEM_TYP_WRITE);
0464
0465 for (s=0; EXFAIL!=signals[s]; s++)
0466 {
0467 for (i=0; i<G_atmi_env.max_clts; i++)
0468 {
0469 el = NDRX_CPM_INDEX(mem_cpy, i);
0470
0471 if (el->flags & NDRX_CPM_MAP_ISUSED &&
0472 ndrx_sys_is_process_running_by_pid(el->pid))
0473 {
0474
0475 if (0==s)
0476 {
0477 ndrx_proc_children_get_recursive(&cltchildren, el->pid);
0478 }
0479
0480
0481 kill(el->pid, signals[s]);
0482 was_kill = EXTRUE;
0483 }
0484 }
0485
0486
0487 if (was_kill && EXFAIL!=signals[s+1])
0488 {
0489 sleep(EX_KILL_SLEEP_SECS);
0490 }
0491 else
0492 {
0493 break;
0494 }
0495 }
0496
0497 ndrx_proc_kill_list(cltchildren);
0498 ndrx_string_list_free(cltchildren);
0499
0500 cltchildren = NULL;
0501
0502
0503 ndrx_cltshm_detach();
0504 ndrx_cltshm_remove(EXTRUE);
0505 }
0506
0507 out:
0508 *p_was_any = was_kill;
0509
0510 if (NULL!=mem_cpy)
0511 {
0512 NDRX_FREE(mem_cpy);
0513 }
0514 return;
0515 }
0516