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 #include <ndrstandard.h>
0038 #include <ndebug.h>
0039 #include <lcf.h>
0040 #include <lcfint.h>
0041 #include <nstd_int.h>
0042 #include <nstd_shm.h>
0043 #include <ndebugcmn.h>
0044 #include <sys_unix.h>
0045 #include <nerror.h>
0046 #include <exhash.h>
0047 #include <exregex.h>
0048 #include <lcfint.h>
0049 #include "exsha1.h"
0050 #include <exatomic.h>
0051 #include <singlegrp.h>
0052 #include <lcfint.h>
0053
0054
0055 #define MAX_LCFMAX_DFLT 20
0056 #define MAX_READERS_DFLT 50
0057 #define MAX_LCFREADERS_DFLT 1000
0058 #define MAX_LCFSTARTMAX_DFLT 60
0059 #define SGMREFRESHMAX_DFLT 30
0060 #define PGMAX_DFLT 64
0061 #define PGMAX_MAX 99999
0062 #define MAX_QUEUES_DLFT 20000
0063
0064
0065
0066 expublic ndrx_nstd_libconfig_t ndrx_G_libnstd_cfg;
0067 expublic ndrx_lcf_shmcfg_t *ndrx_G_shmcfg=NULL;
0068 expublic ndrx_lcf_shmcfg_ver_t M_ver_start = {.shmcfgver_lcf=0};
0069
0070
0071
0072
0073
0074 expublic volatile ndrx_lcf_shmcfg_ver_t *ndrx_G_shmcfg_ver=&M_ver_start;
0075
0076 expublic volatile unsigned ndrx_G_shmcfgver_chk = 0;
0077
0078 exprivate ndrx_shm_t M_lcf_shm = {.fd=0, .path="", .mem=NULL};
0079 exprivate ndrx_sem_t M_lcf_sem = {.semid=0};
0080
0081 exprivate ndrx_lcf_command_seen_t *M_locl_lcf=NULL;
0082
0083 exprivate ndrx_lcf_reg_funch_t *M_funcs=NULL;
0084 exprivate ndrx_lcf_reg_xadminh_t *M_xadmin_cmds=NULL;
0085
0086 exprivate int M_startup_run = EXTRUE;
0087 exprivate MUTEX_LOCKDECL(M_lcf_run);
0088
0089
0090
0091 exprivate int ndrx_lcf_logrotate(ndrx_lcf_command_t *cmd, long *p_flags);
0092 exprivate int ndrx_lcf_logchg(ndrx_lcf_command_t *cmd, long *p_flags);
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104 expublic ndrx_lcf_reg_xadminh_t* ndrx_lcf_xadmin_find_int(char *cmdstr)
0105 {
0106 ndrx_lcf_reg_xadminh_t *ret = NULL;
0107
0108 MUTEX_LOCK_V(M_lcf_run);
0109
0110 EXHASH_FIND_STR( M_xadmin_cmds, cmdstr, ret);
0111
0112 MUTEX_UNLOCK_V(M_lcf_run);
0113
0114 return ret;
0115 }
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125 expublic int ndrx_lcf_xadmin_add_int(ndrx_lcf_reg_xadmin_t *xcmd)
0126 {
0127 int ret = EXSUCCEED;
0128 ndrx_lcf_reg_xadminh_t *h;
0129
0130 h = ndrx_lcf_xadmin_find_int(xcmd->cmdstr);
0131
0132 if (NULL!=h)
0133 {
0134 NDRX_LOG_EARLY(log_debug, "xadmin [%s] lcf command %d", xcmd->cmdstr, xcmd->command);
0135 _Nset_error_fmt(NEEXISTS, "xadmin [%s] lcf command %d", xcmd->cmdstr, xcmd->command);
0136 EXFAIL_OUT(ret);
0137 }
0138 else
0139 {
0140 NDRX_LOG_EARLY(log_debug, "Adding [%s] xadmin lcf command %d",
0141 xcmd->cmdstr, xcmd->command);
0142 }
0143
0144
0145 h = NDRX_FPMALLOC(sizeof(ndrx_lcf_reg_xadminh_t), 0);
0146
0147 if (NULL==h)
0148 {
0149 NDRX_LOG_EARLY(log_error, "Failed to malloc %d bytes (xadmin lcf cmd hash): %s",
0150 sizeof(ndrx_lcf_reg_xadminh_t), strerror(errno));
0151 _Nset_error_fmt(NEMALLOC, "Failed to malloc %d bytes (xadmin lcf cmd hash): %s",
0152 sizeof(ndrx_lcf_reg_xadminh_t), strerror(errno));
0153 EXFAIL_OUT(ret);
0154 }
0155
0156 memcpy(&h->xcmd, xcmd, sizeof(ndrx_lcf_reg_xadmin_t));
0157 NDRX_STRCPY_SAFE(h->cmdstr, xcmd->cmdstr);
0158
0159 MUTEX_LOCK_V(M_lcf_run);
0160 EXHASH_ADD_STR(M_xadmin_cmds, cmdstr, h);
0161 MUTEX_UNLOCK_V(M_lcf_run);
0162
0163 out:
0164 return ret;
0165 }
0166
0167
0168
0169
0170
0171
0172 expublic ndrx_lcf_reg_funch_t* ndrx_lcf_func_find_int(int command, int do_lock)
0173 {
0174 ndrx_lcf_reg_funch_t *ret = NULL;
0175
0176 if (do_lock)
0177 {
0178 MUTEX_LOCK_V(M_lcf_run);
0179 }
0180
0181 EXHASH_FIND_INT( M_funcs, &command, ret);
0182
0183 if (do_lock)
0184 {
0185 MUTEX_UNLOCK_V(M_lcf_run);
0186 }
0187 return ret;
0188 }
0189
0190
0191
0192
0193
0194
0195 expublic int ndrx_lcf_func_add_int(ndrx_lcf_reg_func_t *cfunc)
0196 {
0197 int ret = EXSUCCEED;
0198 ndrx_lcf_reg_funch_t *h;
0199
0200 h = ndrx_lcf_func_find_int(cfunc->command, EXTRUE);
0201
0202 if (NULL!=h)
0203 {
0204
0205 _Nset_error_fmt(NEEXISTS, "Command [%d] already registered for [%s]",
0206 h->command, h->cfunc.cmdstr);
0207 EXFAIL_OUT(ret);
0208
0209 }
0210 else
0211 {
0212 NDRX_LOG_EARLY(log_debug, "Adding [%d] func lcf command [%s]",
0213 cfunc->command, cfunc->cmdstr);
0214 }
0215
0216
0217 h = NDRX_FPMALLOC(sizeof(ndrx_lcf_reg_funch_t), 0);
0218
0219 if (NULL==h)
0220 {
0221 NDRX_LOG_EARLY(log_error, "Failed to malloc %d bytes (func lcf cmd hash): %s",
0222 sizeof(ndrx_lcf_reg_funch_t), strerror(errno));
0223 _Nset_error_fmt(NEMALLOC, "Failed to malloc %d bytes (func lcf cmd hash): %s",
0224 sizeof(ndrx_lcf_reg_funch_t), strerror(errno));
0225 EXFAIL_OUT(ret);
0226 }
0227
0228 memcpy(&h->cfunc, cfunc, sizeof(ndrx_lcf_reg_func_t));
0229 h->command = cfunc->command;
0230
0231 MUTEX_LOCK_V(M_lcf_run);
0232 EXHASH_ADD_INT(M_funcs, command, h);
0233 MUTEX_UNLOCK_V(M_lcf_run);
0234
0235 out:
0236 return ret;
0237 }
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249 expublic int ndrx_lcf_init(void)
0250 {
0251 int ret = EXSUCCEED;
0252 char *tmp;
0253 size_t sz;
0254 ndrx_lcf_reg_func_t creg;
0255
0256 memset(&ndrx_G_libnstd_cfg, 0, sizeof(ndrx_G_libnstd_cfg));
0257
0258 tmp = getenv(CONF_NDRX_LCFNORUN);
0259
0260 if (NULL!=tmp && (tmp[0]=='y' || tmp[0]=='Y'))
0261 {
0262 ndrx_G_libnstd_cfg.lcf_norun=EXTRUE;
0263 }
0264 else
0265 {
0266 ndrx_G_libnstd_cfg.lcf_norun=EXFALSE;
0267 }
0268
0269
0270
0271 ndrx_G_libnstd_cfg.qprefix = getenv(CONF_NDRX_QPREFIX);
0272 if (NULL==ndrx_G_libnstd_cfg.qprefix)
0273 {
0274
0275 NDRX_LOG_EARLY(log_info, "Missing config key %s", CONF_NDRX_QPREFIX);
0276 EXFAIL_OUT(ret);
0277 }
0278
0279 NDRX_LOG_EARLY(log_info, "%s set to %s", CONF_NDRX_QPREFIX,
0280 ndrx_G_libnstd_cfg.qprefix);
0281
0282
0283 tmp = getenv(CONF_NDRX_PGMAX);
0284 if (NULL==tmp)
0285 {
0286 ndrx_G_libnstd_cfg.pgmax = PGMAX_DFLT;
0287 }
0288 else
0289 {
0290 ndrx_G_libnstd_cfg.pgmax = atol(tmp);
0291 }
0292
0293 if (ndrx_G_libnstd_cfg.pgmax > PGMAX_MAX)
0294 {
0295 NDRX_LOG_EARLY(log_error, "%s value %d exceeds hard limit %d, defaulting to %d",
0296 CONF_NDRX_PGMAX, ndrx_G_libnstd_cfg.pgmax, PGMAX_MAX, PGMAX_MAX);
0297 ndrx_G_libnstd_cfg.pgmax=PGMAX_MAX;
0298 }
0299
0300 NDRX_LOG_EARLY(log_info, "%s set to %d", CONF_NDRX_PGMAX,
0301 ndrx_G_libnstd_cfg.pgmax);
0302
0303
0304 tmp = getenv(CONF_NDRX_SGREFRESH);
0305 if (NULL==tmp)
0306 {
0307 ndrx_G_libnstd_cfg.sgrefreshmax = SGMREFRESHMAX_DFLT;
0308 }
0309 else
0310 {
0311 ndrx_G_libnstd_cfg.sgrefreshmax = atol(tmp);
0312 }
0313
0314 NDRX_LOG_EARLY(log_debug, "%s set to %d", CONF_NDRX_SGREFRESH,
0315 ndrx_G_libnstd_cfg.sgrefreshmax);
0316
0317
0318 tmp = getenv(CONF_NDRX_SVQREADERSMAX);
0319 if (NULL==tmp)
0320 {
0321 ndrx_G_libnstd_cfg.svqreadersmax = MAX_READERS_DFLT;
0322 }
0323 else
0324 {
0325 ndrx_G_libnstd_cfg.svqreadersmax = atol(tmp);
0326 }
0327 NDRX_LOG_EARLY(log_info, "%s set to %d", CONF_NDRX_SVQREADERSMAX,
0328 ndrx_G_libnstd_cfg.svqreadersmax);
0329
0330
0331 tmp = getenv(CONF_NDRX_LCFREADERSMAX);
0332 if (NULL==tmp)
0333 {
0334 ndrx_G_libnstd_cfg.lcfreadersmax = MAX_LCFREADERS_DFLT;
0335 }
0336 else
0337 {
0338 ndrx_G_libnstd_cfg.lcfreadersmax = atol(tmp);
0339 }
0340 NDRX_LOG_EARLY(log_info, "%s set to %d", CONF_NDRX_LCFREADERSMAX,
0341 ndrx_G_libnstd_cfg.lcfreadersmax);
0342
0343
0344 tmp = getenv(CONF_NDRX_LCFMAX);
0345 if (NULL==tmp)
0346 {
0347 ndrx_G_libnstd_cfg.lcfmax = MAX_LCFMAX_DFLT;
0348 }
0349 else
0350 {
0351 ndrx_G_libnstd_cfg.lcfmax = atol(tmp);
0352 }
0353 NDRX_LOG_EARLY(log_info, "%s set to %d", CONF_NDRX_LCFMAX,
0354 ndrx_G_libnstd_cfg.lcfmax);
0355
0356
0357 tmp = getenv(CONF_NDRX_MSGQUEUESMAX);
0358 if (NULL==tmp)
0359 {
0360 ndrx_G_libnstd_cfg.queuesmax = MAX_QUEUES_DLFT;
0361 NDRX_LOG_EARLY(log_info, "Missing config key %s - defaulting to %d",
0362 CONF_NDRX_MSGQUEUESMAX, ndrx_G_libnstd_cfg.queuesmax);
0363 }
0364 else
0365 {
0366 ndrx_G_libnstd_cfg.queuesmax = atol(tmp);
0367 }
0368 NDRX_LOG_EARLY(log_info, "%s set to %d", CONF_NDRX_MSGQUEUESMAX,
0369 ndrx_G_libnstd_cfg.queuesmax);
0370
0371
0372 tmp = getenv(CONF_NDRX_IPCKEY);
0373 if (NULL==tmp)
0374 {
0375
0376 NDRX_LOG_EARLY(log_info, "Missing config key %s - FAIL", CONF_NDRX_IPCKEY);
0377 EXFAIL_OUT(ret);
0378 }
0379 else
0380 {
0381 int tmpkey;
0382
0383 sscanf(tmp, "%x", &tmpkey);
0384 ndrx_G_libnstd_cfg.ipckey = tmpkey;
0385
0386 NDRX_LOG_EARLY(log_info, "(sysv queues): SystemV IPC Key set to: [%x]",
0387 ndrx_G_libnstd_cfg.ipckey);
0388 }
0389
0390
0391 tmp = getenv(CONF_NDRX_LCFCMDEXP);
0392 if (NULL==tmp)
0393 {
0394 ndrx_G_libnstd_cfg.startcmdexp = MAX_LCFSTARTMAX_DFLT;
0395 }
0396 else
0397 {
0398 ndrx_G_libnstd_cfg.startcmdexp = atol(tmp);
0399 }
0400 NDRX_LOG_EARLY(log_info, "%s set to %d", CONF_NDRX_LCFCMDEXP,
0401 ndrx_G_libnstd_cfg.startcmdexp);
0402
0403
0404
0405 NDRX_LOG_EARLY(log_info, "Opening LCF shared memory...");
0406
0407
0408
0409
0410 M_lcf_shm.fd = EXFAIL;
0411 M_lcf_shm.key = ndrx_G_libnstd_cfg.ipckey + NDRX_SHM_LCF_KEYOFSZ;
0412
0413
0414 M_lcf_shm.size = sizeof(ndrx_lcf_shmcfg_t)
0415
0416 + sizeof(ndrx_lcf_command_t) * ndrx_G_libnstd_cfg.lcfmax
0417
0418 + sizeof(ndrx_sg_shm_t) * ndrx_G_libnstd_cfg.pgmax;
0419
0420 snprintf(M_lcf_shm.path, sizeof(M_lcf_shm.path), NDRX_SHM_LCF, ndrx_G_libnstd_cfg.qprefix);
0421
0422 if (EXSUCCEED!=ndrx_shm_open(&M_lcf_shm, EXTRUE))
0423 {
0424
0425 NDRX_LOG_EARLY(log_error, "Failed to attach to LCF memory");
0426 userlog("Failed to open LCF shared memory - possibly changed "
0427 "NDRX_LCFMAX, thus use xadmin down -y to restart the app");
0428 EXFAIL_OUT(ret);
0429 }
0430
0431 M_lcf_sem.key = ndrx_G_libnstd_cfg.ipckey + NDRX_SEM_LCFLOCKS;
0432
0433
0434
0435
0436
0437
0438
0439
0440
0441 M_lcf_sem.nrsems = 1;
0442 M_lcf_sem.maxreaders = ndrx_G_libnstd_cfg.lcfreadersmax;
0443
0444 if (EXSUCCEED!=ndrx_sem_open(&M_lcf_sem, EXTRUE))
0445 {
0446 NDRX_LOG_EARLY(log_error, "Failed to open LCF semaphore");
0447 EXFAIL_OUT(ret);
0448 }
0449
0450 sz = sizeof(ndrx_lcf_command_seen_t)*ndrx_G_libnstd_cfg.lcfmax;
0451
0452 M_locl_lcf = NDRX_FPMALLOC(sz, 0);
0453
0454 if (NULL==M_locl_lcf)
0455 {
0456 NDRX_LOG_EARLY(log_error, "Failed to malloc local LCF storage (%d bytes): %s",
0457 sz, strerror(errno));
0458 EXFAIL_OUT(ret);
0459 }
0460
0461
0462 memset(M_locl_lcf, 0, sz);
0463
0464
0465
0466
0467 ndrx_G_shmcfg = (ndrx_lcf_shmcfg_t*)M_lcf_shm.mem;
0468
0469
0470
0471
0472 ndrx_G_shmcfg_ver = (ndrx_lcf_shmcfg_ver_t*)M_lcf_shm.mem;
0473
0474
0475
0476 memset(&creg, 0, sizeof(creg));
0477
0478 creg.version=NDRX_LCF_CCMD_VERSION;
0479 creg.pf_callback=ndrx_lcf_logrotate;
0480 creg.command=NDRX_LCF_CMD_LOGROTATE;
0481 NDRX_STRCPY_SAFE(creg.cmdstr, NDRX_LCF_CMDSTR_LOGROTATE);
0482
0483 ndrx_lcf_func_add_int(&creg);
0484
0485 memset(&creg, 0, sizeof(creg));
0486
0487
0488 creg.version=NDRX_LCF_CCMD_VERSION;
0489 creg.pf_callback=ndrx_lcf_logchg;
0490 creg.command=NDRX_LCF_CMD_LOGCHG;
0491 NDRX_STRCPY_SAFE(creg.cmdstr, NDRX_LCF_CMDSTR_LOGCHG);
0492
0493 ndrx_lcf_func_add_int(&creg);
0494
0495 if (EXSUCCEED!=ndrx_sg_init())
0496 {
0497 NDRX_LOG_EARLY(log_error, "Singleton group init failed");
0498 EXFAIL_OUT(ret);
0499 }
0500
0501 out:
0502
0503 if (EXSUCCEED!=ret)
0504 {
0505
0506 ndrx_G_libnstd_cfg.lcf_norun=EXTRUE;
0507 }
0508
0509 return ret;
0510 }
0511
0512
0513
0514
0515
0516
0517 expublic int ndrx_lcf_run(void)
0518 {
0519 int ret = EXSUCCEED;
0520 long flags;
0521 int i;
0522 long apply;
0523 ndrx_lcf_command_t *cur;
0524 char tmpbuf[32];
0525 long cmdage;
0526 ndrx_lcf_reg_funch_t* cbfunc;
0527 ndrx_lcf_command_t cmd_tmp;
0528
0529
0530
0531
0532
0533 MUTEX_LOCK_V(M_lcf_run);
0534
0535
0536 if (ndrx_G_libnstd_cfg.lcf_norun)
0537 {
0538
0539
0540
0541 ndrx_G_shmcfgver_chk=ndrx_G_shmcfg_ver->shmcfgver_lcf;
0542 goto out;
0543 }
0544
0545 if (ndrx_G_shmcfgver_chk==ndrx_G_shmcfg_ver->shmcfgver_lcf)
0546 {
0547 goto out;
0548 }
0549
0550 if (EXSUCCEED!=ndrx_sem_rwlock(&M_lcf_sem, 0, NDRX_SEM_TYP_READ))
0551 {
0552 EXFAIL_OUT(ret);
0553 }
0554
0555
0556 ndrx_G_shmcfgver_chk=ndrx_G_shmcfg_ver->shmcfgver_lcf;
0557
0558 for (i=0; i<ndrx_G_libnstd_cfg.lcfmax; i++)
0559 {
0560 if (ndrx_G_shmcfg->commands[i].cmdversion!=M_locl_lcf[i].cmdversion ||
0561 ndrx_G_shmcfg->commands[i].command !=M_locl_lcf[i].command ||
0562 0!=ndrx_stopwatch_diff(& ndrx_G_shmcfg->commands[i].publtim, &M_locl_lcf[i].publtim)
0563 )
0564 {
0565 cur = &ndrx_G_shmcfg->commands[i];
0566
0567 apply = 0;
0568
0569 if (cur->flags & NDRX_LCF_FLAG_ALL)
0570 {
0571 apply=EXTRUE;
0572 }
0573 else if (cur->flags & NDRX_LCF_FLAG_PID)
0574 {
0575
0576
0577 if (cur->flags & NDRX_LCF_FLAG_DOREX)
0578 {
0579 snprintf(tmpbuf, sizeof(tmpbuf), "%d", (int)getpid());
0580 if (EXSUCCEED==ndrx_regqexec(cur->procid, tmpbuf))
0581 {
0582 apply++;
0583 }
0584 }
0585 else
0586 {
0587 pid_t pp = (pid_t)atoi (cur->procid);
0588
0589 if (pp==getpid())
0590 {
0591 apply++;
0592 }
0593 }
0594 }
0595 else if (cur->flags & NDRX_LCF_FLAG_BIN)
0596 {
0597
0598
0599 if (cur->flags & NDRX_LCF_FLAG_DOREX)
0600 {
0601 if (EXSUCCEED==ndrx_regqexec(cur->procid, EX_PROGNAME))
0602 {
0603 apply++;
0604 }
0605 }
0606 else if (0==strcmp(cur->procid, EX_PROGNAME))
0607 {
0608 apply++;
0609 }
0610 }
0611
0612
0613 cmdage = ndrx_stopwatch_get_delta_sec(&cur->publtim);
0614
0615 if (M_startup_run)
0616 {
0617 if ( (cur->flags & NDRX_LCF_FLAG_DOSTARTUPEXP) &&
0618 cmdage <= ndrx_G_libnstd_cfg.startcmdexp)
0619 {
0620 apply++;
0621 }
0622 else if (cur->flags & NDRX_LCF_FLAG_DOSTARTUP)
0623 {
0624 apply++;
0625 }
0626 }
0627 else
0628 {
0629 apply++;
0630 }
0631
0632 if (2==apply && NULL!=(cbfunc =ndrx_lcf_func_find_int(cur->command, EXFALSE)))
0633 {
0634 apply++;
0635 }
0636
0637
0638
0639 if (apply==3)
0640 {
0641 NDRX_LOG(log_debug, "LCF: Slot %d changed command code %d (%s) version %u "
0642 "apply: %d flags: 0x%lx age: %ld apply: %d (%s)",
0643 i, cur->command, cur->cmdstr, cur->version, apply,
0644 cur->flags, cmdage, apply, apply==3?"apply":"ignore");
0645 }
0646
0647 if (apply==3)
0648 {
0649
0650
0651 memcpy(&cmd_tmp, cur, sizeof(cmd_tmp));
0652
0653 flags=0;
0654 if (EXSUCCEED!=cbfunc->cfunc.pf_callback(&cmd_tmp, &flags))
0655 {
0656 NDRX_ATOMIC_ADD(&cur->failed, 1);
0657 }
0658 else
0659 {
0660 NDRX_ATOMIC_ADD(&cur->applied, 1);
0661 }
0662
0663
0664 if (flags & NDRX_LCF_FLAG_FBACK_CODE)
0665 {
0666 cur->fbackcode = cmd_tmp.fbackcode;
0667 }
0668
0669 if (flags & NDRX_LCF_FLAG_FBACK_MSG)
0670 {
0671 cmd_tmp.fbackmsg[NDRX_LCF_FEEDBACK_BUF-1]=EXEOS;
0672 NDRX_STRCPY_SAFE(cur->fbackmsg, cmd_tmp.fbackmsg);
0673 }
0674 }
0675 else
0676 {
0677 NDRX_ATOMIC_ADD(&cur->seen, 1);
0678 }
0679
0680
0681 M_locl_lcf[i].cmdversion = cur->cmdversion;
0682 M_locl_lcf[i].command = cur->command;
0683 M_locl_lcf[i].publtim = cur->publtim;
0684 }
0685 }
0686
0687 if (EXSUCCEED!=ndrx_sem_rwunlock(&M_lcf_sem, 0, NDRX_SEM_TYP_READ))
0688 {
0689 EXFAIL_OUT(ret);
0690 }
0691
0692 out:
0693
0694
0695 M_startup_run=EXFALSE;
0696
0697 MUTEX_UNLOCK_V(M_lcf_run);
0698
0699 return ret;
0700 }
0701
0702
0703
0704
0705 expublic int ndrx_lcf_down(void)
0706 {
0707 int ret = EXSUCCEED;
0708
0709 ndrx_lcf_detach();
0710
0711
0712 if (EXSUCCEED!=ndrx_shm_remove(&M_lcf_shm))
0713 {
0714 ret = EXFAIL;
0715 }
0716
0717 if (EXSUCCEED!=ndrx_sem_remove(&M_lcf_sem, EXTRUE))
0718 {
0719 ret = EXFAIL;
0720 }
0721
0722 return ret;
0723
0724 }
0725
0726
0727
0728
0729 expublic void ndrx_lcf_detach(void)
0730 {
0731
0732
0733
0734
0735
0736
0737
0738
0739
0740
0741 ndrx_shm_close(&M_lcf_shm);
0742 ndrx_sem_close(&M_lcf_sem);
0743
0744
0745
0746
0747
0748
0749 }
0750
0751
0752
0753
0754
0755
0756
0757 exprivate int ndrx_lcf_logrotate(ndrx_lcf_command_t *cmd, long *p_flags)
0758 {
0759 return ndrx_debug_reopen_all();
0760 }
0761
0762
0763
0764
0765
0766
0767
0768 exprivate int ndrx_lcf_logchg(ndrx_lcf_command_t *cmd, long *p_flags)
0769 {
0770
0771
0772
0773 return tplogconfig_int(LOG_FACILITY_NDRX|LOG_FACILITY_UBF|LOG_FACILITY_TP,
0774 EXFAIL, (char *)cmd->arg_a, NULL, NULL, NDRX_TPLOGCONFIG_VERSION_INC);
0775 }
0776
0777
0778
0779
0780
0781
0782
0783
0784 expublic int ndrx_lcf_publish_int(int slot, ndrx_lcf_command_t *cmd)
0785 {
0786 int ret = EXSUCCEED;
0787 unsigned cmdversion;
0788
0789
0790
0791 if (ndrx_G_shmcfg_ver==&M_ver_start)
0792 {
0793 _Nset_error_fmt(NESUPPORT, "LCF framework disabled - cannot publish command %d [%s]",
0794 cmd->command, cmd->cmdstr);
0795
0796 NDRX_LOG(log_error, "LCF framework disabled - cannot publish command %d [%s]",
0797 cmd->command, cmd->cmdstr);
0798 EXFAIL_OUT(ret);
0799 }
0800
0801 if (slot >=ndrx_G_libnstd_cfg.lcfmax)
0802 {
0803 _Nset_error_fmt(NELIMIT, "Invalid command slot number, max slot: %d got: %d",
0804 ndrx_G_libnstd_cfg.lcfmax-1, slot);
0805 EXFAIL_OUT(ret);
0806 }
0807
0808 if (slot < 0 )
0809 {
0810 _Nset_error_fmt(NEINVAL, "Invalid command slot number, min slot: %d got: %d",
0811 0, slot);
0812 EXFAIL_OUT(ret);
0813 }
0814
0815 if (EXSUCCEED!=ndrx_sem_rwlock(&M_lcf_sem, 0, NDRX_SEM_TYP_WRITE))
0816 {
0817 _Nset_error_msg(NESYSTEM, "Failed to lock lcf sem");
0818 EXFAIL_OUT(ret);
0819 }
0820
0821
0822
0823 memset(&ndrx_G_shmcfg->commands[slot], 0, sizeof(ndrx_G_shmcfg->commands[slot]));
0824
0825 cmdversion = ndrx_G_shmcfg->commands[slot].cmdversion;
0826 memcpy(&ndrx_G_shmcfg->commands[slot], cmd, sizeof(*cmd));
0827
0828 cmdversion++;
0829 ndrx_G_shmcfg->commands[slot].cmdversion=cmdversion;
0830
0831
0832 ndrx_stopwatch_reset(&ndrx_G_shmcfg->commands[slot].publtim);
0833
0834
0835 ndrx_G_shmcfg->shmcfgver_lcf++;
0836
0837 if (EXSUCCEED!=ndrx_sem_rwunlock(&M_lcf_sem, 0, NDRX_SEM_TYP_WRITE))
0838 {
0839 EXFAIL_OUT(ret);
0840 }
0841
0842 out:
0843
0844 return ret;
0845 }
0846
0847
0848
0849
0850
0851 expublic void ndrx_lcf_xadmin_list(void (*pf_callback)(ndrx_lcf_reg_xadminh_t *xcmd))
0852 {
0853 ndrx_lcf_reg_xadminh_t *el, *elt;
0854
0855 MUTEX_LOCK_V(M_lcf_run);
0856
0857
0858 EXHASH_ITER(hh, M_xadmin_cmds, el, elt)
0859 {
0860 pf_callback(el);
0861 }
0862
0863 MUTEX_UNLOCK_V(M_lcf_run);
0864
0865 }
0866
0867
0868
0869
0870
0871 expublic int ndrx_lcf_read_lock(void)
0872 {
0873 return ndrx_sem_rwlock(&M_lcf_sem, 0, NDRX_SEM_TYP_READ);
0874 }
0875
0876
0877
0878
0879
0880 expublic int ndrx_lcf_read_unlock(void)
0881 {
0882 return ndrx_sem_rwunlock(&M_lcf_sem, 0, NDRX_SEM_TYP_READ);
0883 }
0884
0885
0886
0887
0888
0889 expublic int ndrx_lcf_supported_int(void)
0890 {
0891 int ret = EXTRUE;
0892
0893 if (ndrx_G_shmcfg_ver==&M_ver_start)
0894 {
0895 ret=EXFALSE;
0896 }
0897
0898 out:
0899 return ret;
0900 }
0901
0902
0903
0904
0905
0906
0907
0908
0909
0910
0911 expublic void ndrx_lcf_remove(key_t ipckeybase, char *q_prefix)
0912 {
0913 int do_reply = EXFALSE;
0914 NDRX_LOG(log_debug, "Removing LCF memory");
0915
0916 MUTEX_LOCK_V(M_lcf_run);
0917
0918 ndrx_dbg_intlock_set();
0919
0920
0921 ndrx_dbg_lock();
0922
0923
0924
0925
0926
0927 G_ndrx_debug_first=EXTRUE;
0928
0929
0930
0931 sched_yield();
0932
0933
0934 ndrx_G_shmcfg_ver=&M_ver_start;
0935 ndrx_G_shmcfgver_chk = ndrx_G_shmcfg_ver->shmcfgver_lcf;
0936
0937
0938 ndrx_lcf_detach();
0939
0940
0941 M_lcf_shm.key = ipckeybase + NDRX_SHM_LCF_KEYOFSZ;
0942 snprintf(M_lcf_shm.path, sizeof(M_lcf_shm.path), NDRX_SHM_LCF, q_prefix);
0943
0944 ndrx_shm_remove(&M_lcf_shm);
0945 ndrx_G_shmcfg=NULL;
0946
0947 ndrx_sem_remove(&M_lcf_sem, EXTRUE);
0948
0949 G_ndrx_debug_first=EXFALSE;
0950
0951 ndrx_dbg_unlock();
0952
0953
0954 ndrx_dbg_intlock_unset(&do_reply);
0955
0956
0957 if (do_reply)
0958 {
0959 ndrx_dbg_reply_memlog_all();
0960 }
0961
0962 out:
0963 MUTEX_UNLOCK_V(M_lcf_run);
0964
0965 }
0966
0967
0968
0969
0970 expublic void ndrx_lcf_reset(void)
0971 {
0972 MUTEX_LOCK_V(M_lcf_run);
0973
0974
0975
0976
0977 if (ndrx_G_shmcfg_ver==&M_ver_start)
0978 {
0979 goto out;
0980 }
0981
0982
0983 if (EXSUCCEED!=ndrx_sem_rwlock(&M_lcf_sem, 0, NDRX_SEM_TYP_WRITE))
0984 {
0985 goto out;
0986 }
0987
0988
0989 memset(ndrx_G_shmcfg->commands, 0, sizeof(ndrx_G_shmcfg->commands[0])*ndrx_G_libnstd_cfg.lcfmax);
0990
0991 ndrx_sem_rwunlock(&M_lcf_sem, 0, NDRX_SEM_TYP_WRITE);
0992
0993 ndrx_G_shmcfg->use_ddr = EXFALSE;
0994 ndrx_G_shmcfg->ddr_page=0;
0995 ndrx_G_shmcfg->ddr_ver1=0;
0996
0997 out:
0998 MUTEX_UNLOCK_V(M_lcf_run);
0999 }
1000
1001